JScrollPaneにJTextAreaを埋め込み、そのJTextAreaを出力に使用しています。
出力がJTextAreaのサイズを超えると、JTextAreaが自動的にスクロールするため、ユーザーは手動で下にスクロールして最近の出力を確認する必要がありません。
どうやってやるの?
JTextAreaとJScrollPaneの両方のautoscrollプロパティをすでにtrueに設定しています。
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);
カレット更新ポリシーを設定するための上記の提案は機能しません。
代わりに、スクロールを自動にするかどうかをユーザーが判断できるスマートスクロールを確認することをお勧めします。
テキスト領域での自動スクロールの詳細については、テキスト領域のスクロールを参照してください。
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 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ビット単位)で表される文字がテキストに含まれている場合に発生します(このようないわゆるサロゲートペア:)。フィルタリングの解決策はありますが、別のトピックかもしれません。
最良かつ最も簡単な方法、これを試してください:
import javax.swing.text.DefaultCaret;
DefaultCaret caret = (DefaultCaret) textArea.getCaret();
caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
代わりにこれを使用してください
JTextArea textArea = new JTextArea();
DefaultCaret caret = (DefaultCaret)textArea.getCaret();
caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
scrollPane = new JScrollPane();
scrollPane.add(textArea);
scrollPane.setViewportView(textArea);
これを試して:
JTextArea jTextArea = new JTextArea();
JScrollPane jScrollPane = new JScrollPane();
jScrollPane.setViewport(jTextArea);