Java GUIでJTextAreaの自動スクロールを設定するにはどうすればよいですか?
-
06-07-2019 - |
質問
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ビット単位)で表される文字が含まれている場合に発生します(いわゆるサロゲートペア:&#127801;)。フィルタリングのソリューションはありますが、別のトピックかもしれません。
代わりにこれを使用
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);