我有SwingWorker
如下:
public class MainWorker extends SwingWorker(Void, MyObject) {
:
:
}
我从EDT调用了上述Swing Worker
:
MainWorker mainWorker = new MainWorker();
mainWorker.execute();
现在,mainWorker
创建了10个MyTask
类的实例,以便每个实例都在自己的线程上运行,以便更快地完成工作。
但问题是我想在任务运行时不时更新gui。我知道如果任务是由mainWorker
本身执行的,我可以使用publish()
和process()
方法来更新gui。
但由于任务是由不同于Swingworker
线程的线程执行的,我如何从执行任务的线程生成的中间结果更新gui。
答案 0 :(得分:8)
SwingWorker的API文档提供了以下提示:
调用doInBackground()方法 在这个线程上。这就是全部 背景活动应该发生。 通知PropertyChangeListeners 关于绑定属性更改使用 firePropertyChange和 getPropertyChangeSupport()方法。通过 默认有两个绑定属性 可用:状态和进展。
MainWorker
可以实施PropertyChangeListener
。然后它可以使用PropertyChangeSupport
:
getPropertyChangeSupport().addPropertyChangeListener( this );
MainWorker
可以将PropertyChangeSupport
对象提供给它创建的每个MyTask
对象。
new MyTask( ..., this.getPropertyChangeSupport() );
MyTask
对象可以使用MainWorker
方法通知其PropertyChangeSupport.firePropertyChange
进度或属性更新。
MainWorker
,然后通知,可以使用SwingUtilities.invokeLater
或SwingUtilities.invokeAndWait
通过EDT更新Swing组件。
protected Void doInBackground() {
final int TASK_COUNT = 10;
getPropertyChangeSupport().addPropertyChangeListener(this);
CountDownLatch latch = new CountDownLatch( TASK_COUNT ); // java.util.concurrent
Collection<Thread> threads = new HashSet<Thread>();
for (int i = 0; i < TASK_COUNT; i++) {
MyTask task = new MyTask( ..., latch, this.getPropertyChangeSupport() ) );
threads.add( new Thread( task ) );
}
for (Thread thread: threads) {
thread.start();
}
latch.await();
return null;
}
答案 1 :(得分:3)
即使您不使用SwingWorker,也可以使用SwingUtilities.invokeLater(...)或SwingUtilities.invokeAndWait(...)
始终在EDT中发布要做的事情。编辑: 假设您有一个执行某些代码的线程,您可以随时与EDT交互,如下例所示。
public void aMethodExecutedInAThread() {
// Do some computation, calculation in a separated Thread
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
// Post information in the EDT
// This code is executed inside EDT
}
});
}
答案 2 :(得分:2)
以下是使用example启动多个主题的SwingWorker
。 CountDownLatch
确保doInBackground()
仅在所有线程完成后返回。每个线程使用append()
的线程安全JTextArea
方法来更新GUI,但EventQueue.invokeLater()
将是一个方便的替代方案。
答案 3 :(得分:0)