如何在漫长的过程中使JScrollPane更新

时间:2012-11-07 20:54:59

标签: java swing

我有一个包含JTextArea对象的JScrollPane。在这个特定的应用程序中,JTextArea充当“进程控制台”,以便有人可以看到长时间运行的进程发生了什么。我的代码如下所示:

JTextArea console;

...

// Initializes the console panel, including creation of the JTextArea and JScrollPane
private void initializePanel() {
    JPanel consolePanel = new JPanel();
    ...
    console = new JTextArea();
    console.setEnabled(false);
    textAreaScrollPane = new JScrollPane(console);
    ...
}

// Appends an incoming message to the console
@Override
public void update(Observable observable, Object consoleMessage) {
    console.append(consoleMessage + "\n");
    console.update(console.getGraphics());
}

我遇到的问题是我的JScrollPane没有以滚动条开头。当文本被附加到底层的JTextArea时,它会脱离JScrollPane的底部。不幸的是,滚动条在长时间运行的过程完成之前不会出现。此时,滚动条突然出现,视图跳转到JTextArea的最后。

因此,应用程序看起来像被冻结,因为更多消息在JScrollPane的当前视口之外。

我尝试过不同的代码组合,试图在每次写入消息时重新绘制JSrollPane,但没有这样的运气。 JTextArea获取消息并在收到后立即打印 - 这真的是JScrollPane没有立即添加滚动条,这是有问题的。

感谢。

1 个答案:

答案 0 :(得分:1)

Mrpyo的评论很明显。我产生了第二个线程(使用SwingWorker)来执行长时间运行的进程,并释放用户线程来进行UI更新。

我必须添加的一件事是强制JScrollPane始终滚动到底部。我通过简单地调用

来做到这一点
console.selectAll(); // console is my JTextArea object

因为我的JTextArea对象未启用,所以调用selectAll()实际上并不会导致选择任何内容,但它确实具有将JScrollPane滚动到末尾的副作用。这不是一个优雅的解决方案所以,如果有人有更好的东西,我会全神贯注 - 但它确实有效。

谢谢,mrpyo!

trashgod提供的链接让我在这里:

http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html

...它成为了如何正确执行此并发的重要资源。