Java Swing:在文本区域中动态附加文本的方法,具有滚动条更新

时间:2009-06-11 20:33:45

标签: java swing

Java swing的一般方法是使用文本行(例如从线程)更新textarea,然后在添加文本时将文本插入符号流到textarea的底部。还要更新滚动条,使其位于底部。

我想我会有一个字符串缓冲区并将文本附加到该文本然后在textarea中设置字符串并将滚动条放在底部。

5 个答案:

答案 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());
}});