我已经在JScrollPane上嵌入了JTextArea,并且正在使用该JTextArea进行输出。
我希望每当输出超出JTextArea的大小时,JTextArea都会自动滚动,以便用户不必手动向下滚动即可查看最新输出。
我怎样才能做到这一点?
我已经将JTextArea和JScrollPane的autoscroll属性都设置为true。
Answers:
当使用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的内容变大(几个MB)时遇到了问题。最后,以下显示最佳性能:
myTextArea.append( someText );
myTextArea.getCaret().setDot( Integer.MAX_VALUE );
当然,用户所做的任何选择都会丢失。因此,它仅可用于文本区域的“仅显示”用法。
尽管如此,在我的安装中,如果JTextArea的内容超过9MB,它就变得无法使用(非常缓慢甚至几乎冻结的GUI)。
当文本包含以UTF-16编码的两个字符(两个16位单元)表示的字符(所谓的代理对,例如:🌹)时,会发生类似的现象。我有一个过滤解决方案,但也许是另外一个话题。