JScrollPaneにJTextAreaを埋め込み、そのJTextAreaを出力に使用しています。
出力がJTextAreaのサイズを超えるたびに、JTextAreaが自動的にスクロールするため、ユーザーが最近の出力を表示するために手動でスクロールする必要はありません。
どうやってやるの?
JTextAreaとJScrollPaneの両方のautoscrollプロパティをtrueに設定済みです。
JDK1.4.2(またはそれ以前)を使用する場合、フォーラムで最も一般的な提案は、次のようなコードを使用することです。
textArea.append(...);
textArea.setCaretPosition(textArea.getDocument().getLength());
ただし、JDK5では、この問題はAPIの変更により実際に解決されていることに気づきました。テキスト領域のDefaultCaretにプロパティを設定することにより、この動作を制御できるようになりました。このアプローチを使用すると、コードは次のようになります。
JTextArea textArea = new JTextArea();
DefaultCaret caret = (DefaultCaret)textArea.getCaret();
caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
キャレット更新ポリシーを設定する上記の提案は機能しません。
代わりに、 Smart Scrolling をチェックアウトすることをお勧めします。これにより、ユーザーは、スクロールを自動的に行うかどうかを判断できます。
テキスト領域での自動スクロールの詳細な説明は、ここにあります: テキスト領域のスクロール
JTextAreaの任意の場所をクリックすると、自動スクロールを停止できるようになりました。キャレットの位置が一度変わると、視点も変わります。このとき、テキストを追加または追加するときにキャレット位置を設定する必要があります。途中で、キャレットの位置を設定するメソッドを作成し、追加または追加するときに使用します。
JScrollBar vbar = scrollPane.getVerticalScrollBar();
for (int i = 0; i < 20; i++) {
myJTxt.append("This is text " + i + "\n");
vbar.setValue(vbar.getMaximum());
vbar.Paint(vbar.getGraphics());
myJTxt.scrollRectToVisible(myJTxt.getVisibleRect());
myJTxt.Paint(myJTxt.getGraphics());
try {
Thread.sleep(250);
} catch (InterruptedException ex) {
Logger.getLogger(ScrollTextView.class.getName()).log(Level.SEVERE, null, ex);
}
}
JTextArea jTextArea = new JTextArea();
DefaultCaret caret = (DefaultCaret)jTextArea.getCaret();
caret.setUpdatePolicy(DefaultCaret.OUT_BOTTOM);
ほとんどの提案を試しましたが、JTextAreaのコンテンツが大きくなると(数MB)問題に遭遇しました。最後に、以下が最高のパフォーマンスを示しました。
myTextArea.append( someText );
myTextArea.getCaret().setDot( Integer.MAX_VALUE );
もちろん、ユーザーが行った選択は失われます。したがって、テキスト領域の「表示のみ」の使用にのみ使用できます。
それでも、私のインストールでは、JTextAreaのコンテンツが9MBを超えると、使用できなくなります(ほとんどフリーズしたGUIに対して非常に遅くなります)。
同様の現象は、テキストにUTF-16エンコードで2つの文字(2つの16ビット単位)で表される文字が含まれている場合(いわゆるサロゲートペア、????)に発生します。フィルタリングのソリューションはありますが、別のトピックかもしれません。