Java swing的一般方法是使用文本行(例如从线程)更新textarea,然后在添加文本时将文本插入符号流到textarea的底部。还要更新滚动条,使其位于底部。
我想我会有一个字符串缓冲区并将文本附加到该文本然后在textarea中设置字符串并将滚动条放在底部。
答案 0 :(得分:13)
使用append()
添加文字,然后setCaretPosition()
以确保您使用它滚动。
myTextPane.append(textFromSomewhere);
myTextPane.setCaretPosition(myTextPane.getDocument().getLength());
答案 1 :(得分:7)
append()方法不能做你想要的吗?
虽然您没有问:当您在后台线程中生成某些内容时,请务必使用SwingUtilities.invokeLater()来更新您的组件。
答案 2 :(得分:3)
从另一个主题,您应该使用java.awt.EventQueue.invokeLater
来加入EDT,然后一切正常。
所以:
java.awt.EventQueue.invokeLater(new Runnable() { public void run() {
Document doc = text.getDocument();
int origLen = doc.getLength()
try {
doc.insertString(origLen, msg, null);
} catch (BadLocationException exc) {
// Odd APIs forces us to deal with this nonsense.
IndexOutOfBoundsException wrapExc = new IndexOutOfBoundsException();
wrapExc.initCause(exc);
throw wrapExc;
}
// IIRC, Position is a bit odd and
if (origLen == 0) {
text.setCaretPosition(doc.getLength());
}
}});
如果有人阅读JTextArea.append
的API文档,它声称是线程安全的。 JDK7删除了这种不太可能的声明(提醒:线程很难)。作为一项规则,在Swing中,我倾向于直接使用模型/ Document
。
我相信如果插入符号在最后它应该在追加后移动。唯一的例外是如果没有文本,因为奇怪的API。如果它被移动了,那么我们可能不希望在追加后更新它。
注意:如果多个线程正在执行此操作,则您不一定知道哪个线程会首先到达那里。
答案 3 :(得分:1)
如果要从线程更新,请不要忘记使用SwingWorker
或其他一些AWT线程安全方法。
答案 4 :(得分:1)
您可以使用以下内容更新滚动条而不读取doc.length:
scrollbar.setValue(scrollbar.getMaximum());
更新(包含在Invoke之后,来自Tom Hawtin的代码)
java.awt.EventQueue.invokeLater(new Runnable() { public void run() {
try {
textArea.append(msg);
} catch (BadLocationException exc) {
// Odd APIs forces us to deal with this nonsense.
IndexOutOfBoundsException wrapExc = new IndexOutOfBoundsException();
wrapExc.initCause(exc);
throw wrapExc;
}
JScrollBar bar = scrollPane.getVerticalScrollBar();
bar.setValue(bar.getMaximum());
}});