2012-05-21 15 views
13

ここでは簡単なJava質問があります。 JTextAreaを使用して作成されたテキスト領域の最後の行の先頭に自動テキストスクロールする必要があります。テキスト領域の1行あたりのテキストの量は、テキスト領域の幅よりもかなり長い。キャレット位置が最後の行の先頭に設定されたテキスト領域(JTextArea)の自動テキストスクロール

ここでは、これを設定するために使用したコードスニペットを示します。

JTextArea textArea = new JTextArea(); 
DefaultCaret caret = (DefaultCaret)textArea.getCaret(); 
caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE); 

問題であり、上記のコードで、デフォルトの動作では、キャレットが自動結果として、全体のテキスト領域の先頭部分がスコープ外になり、ドキュメントの末尾に配置されていることです。私は、ドキュメント内の最後の行の先頭にオートスクロールが起こるようにしたいと思います。ここでは、それを明確にする

は、2回のスクリーンショットで、私が欲しいもの

は最初のものであるが、何が起こっていることは二番目です。

What I want is this What I get is this

答えて

13

単にテキストエリアのテキストを更新した後getLineCountgetLineStartOffsetを使用して正しい場所にキャレットを移動します。

import java.util.List; 

import javax.swing.JFrame; 
import javax.swing.JScrollPane; 
import javax.swing.JTextArea; 
import javax.swing.SwingUtilities; 
import javax.swing.SwingWorker; 
import javax.swing.text.BadLocationException; 
import javax.swing.text.DefaultCaret; 

public class Test { 

    private JFrame frame; 
    private JTextArea ta; 

    protected void initUI() { 
     frame = new JFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     ta = new JTextArea(); 
     DefaultCaret caret = (DefaultCaret) ta.getCaret(); 
     caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE); 
     frame.add(new JScrollPane(ta)); 
     frame.setSize(400, 200); 
     frame.setVisible(true); 
     new UpdateText().execute(); 
    } 

    class UpdateText extends SwingWorker<String, String> { 

     @Override 
     public String doInBackground() { 
      for (int i = 0; i < 1000; i++) { 
       publish("Hello-" + i); 
       try { 
        Thread.sleep(500); 
       } catch (InterruptedException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 
      return null; 
     } 

     @Override 
     public void process(List<String> chunks) { 
      for (String s : chunks) { 
       if (ta.getDocument().getLength() > 0) { 
        ta.append("\n"); 
       } 
       ta.append(s); 
      } 
      try { 
       ta.setCaretPosition(ta.getLineStartOffset(ta.getLineCount() - 1)); 
      } catch (BadLocationException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 

     @Override 
     public void done() { 

     } 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       new Test().initUI(); 
      } 
     }); 
    } 

} 
+0

クールソリューション:ここ

は、あなたの希望の動作を説明する実施例であります!しかし、私はここに質問があります。 ta.setCaretPosition(ta.getLineStartOffset(ta.getLineCount() - 1));)を設定する方法はありますか。それは毎回更新するのではなく、一度だけ行うことができるので、アプリケーション全体に有効です。 –

+0

また、DefaultCaretを使用していますが、キャレット=(DefaultCaret)ta.getCaret();キャレット.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);あなたのコードはこれらの記述もなくても動作しますか?この点であなたの意見は何ですか? –

+0

@JtheRockerは私が知っているわけではありません。テキストが更新されると、キャレット位置が移動し続けます。したがって、毎回その場所を再計算する必要があります。 JTextAreaを拡張し、setTextをオーバーライドするには、まずsuper.setTextを呼び出してからキャレットを配置します。あなたの2番目の質問については、これは望ましい行動と人間工学の問題です。あなたの質問では、あなたが求めているものです。今、あなたが実際にスクロールペインの左下隅にスクロールするのを見ているなら、あなたは他の何かを探しています。その場合は、別の質問を投稿することを検討してください。 –

関連する問題