[英]Wait for Swing to finish updating JProgressBar before continuing
我有一个设置了CardLayout
的JFrame
作为其布局管理器。 它具有两个JPanel
子类。 一个是WordsLoadingPanel
面板,它显示文本“ Loading words ...”并具有JProgressBar
。 另一个必须实际加载单词。 这需要一段时间(100个单词大约需要10-14秒;这是一个非常有选择性的算法),因此我想向用户保证程序仍在运行。 我使面板中的加载算法使用firePropertyChange(String, int, int)
触发属性更改,而WordsLoadingPanel
可以很好地捕获更改-我知道这是因为我为此事件添加了一个侦听器以执行println
,并且作品。 但是,当我将println
更改为实际更改JProgressBar
的值时,它没有执行任何操作。 我知道我正在正确更改该值,因为如果在算法开始之前设置该值,它将起作用, 并且可以在循环的最后一次迭代中起作用。 我猜这是因为我的算法正在JProgressBar
计算能力,并且不会让JProgressBar
更新。
所以,我的问题是:如何使我的算法等待Swing(将是AWT Dispatching Thread?)在继续之前完成更新进度条? 我试过了:
Thread.yield
的每次迭代中的Thread.yield
Thread.sleep(1000L)
SwingUtilities.invokeLater(Runnable)
中的循环中 SwingUtilities.invokeLater(Runnable)
编辑:为了进一步支持我的CPU为食算法的假设(听起来像一个孩子的故事...),当我设置JProgressBar
不确定的,它只启动算法完成后移动。
有没有人有什么建议?
谢谢!
要在后台执行昂贵的操作,请考虑使用SwingWorker
类。 该文档提供了有关如何使用它来执行与用户界面在单独线程中进行交互的任务的示例,包括JProgressBar
的进度显示。
如果您在理解类的工作方式时遇到问题,请考虑:
SwingWorker
是具有两个参数的通用类: T
和V
doInBackground
方法返回T
并在单独的线程中执行。 doInBackground
线程中操纵Swing,因此您不能在doInBackground
操纵Swing。 process
方法将List<V>
作为参数,并在事件调度线程上被异步调用。 publish
方法采用V...
参数,并将其发送以在process
方法中进行处理。 结论:
T
是计算结果的类型(如果有)。 V
是操作用户界面所需的数据类型。 doInBackground
运行。 process
方法中进行操作。 publish
将数据发送到process
方法。 好的,我已经解决了。 对于可能遇到类似问题的任何人,我的解决方案是将启动算法的方法从同步执行改为异步执行(使用new Thread(Runnable).start
)。 所以,我的代码现在
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new Thread(new Runnable () {
public void run () {
window.keyboardTrainingPanel.initialize();
}
}).start();
}
});
我希望这可以帮助别人! 但是,如果有更好的方法可以执行此操作,请随时通知我。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.