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

Posted

技术标签:

【中文标题】如何在漫长的过程中让 JScrollPane 更新【英文标题】:How to get JScrollPane to Update during long process 【发布时间】:2012-11-07 20:54:59 【问题描述】:

我有一个 JScrollPane,其中包含一个 JTextArea 对象。在这个特定的应用程序中,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 没有立即添加滚动条造成问题。

谢谢。

【问题讨论】:

你试过在另一个线程中运行这个“进程”吗? 我没有,但这不是一个坏主意。 记得在从另一个线程更新 GUI 时使用 SwingUtilities.invokeLaterSwingUtilities.invokeAndWait... 你想要一个在JTextArea 上调用append()SwingWorker,见here。 【参考方案1】:

Mrpyo 的评论很到位。我生成了第二个线程(使用 SwingWorker)来执行长时间运行的进程,从而释放用户线程来执行 UI 更新。

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

console.selectAll(); // console is my JTextArea object

因为我的 JTextArea 对象未启用,所以调用 selectAll() 实际上不会导致任何内容被选中,但它确实具有将 JScrollPane 滚动到最后的副作用。这不是一个优雅的解决方案,因此,如果有人有更好的解决方案,我会全力以赴 - 但它确实有效。

谢谢,先生!

trashgod 提供的链接把我带到了这里:

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

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

【讨论】:

我会使用setCaretPosition 方法 @Robin:谢谢。我更改了我的实现以使用 setCaretPosition 并且对此感到更满意,因为我觉得我没有使用副作用来获得我想要的行为。

以上是关于如何在漫长的过程中让 JScrollPane 更新的主要内容,如果未能解决你的问题,请参考以下文章

如何做到这一点,以便当我将可动态调整大小的 JPanel 放入 JScrollPane 时它​​可以工作?

可缩放的 JScrollPane - setViewPosition 无法更新

如何在漫长的循环中使用服务器端变量更新客户端?

如何在漫长的循环中使用服务器端变量更新客户端?

JScrollPane 中的列表在视口外绘制

在 JScrollPane 中查找可见组件的快速方法