我有一个SwingWorker,如下所示:

public class MainWorker extends SwingWorker(Void, MyObject) {
    :
    :
}

我从EDT调用了上面的Swing Worker:
MainWorker mainWorker = new MainWorker();
mainWorker.execute();

现在,mainWorker创建MyTask类的10个实例,以便每个实例将在其自己的线程上运行,从而更快地完成工作。

但是问题是我想在任务运行时不时更新gui。我知道,如果任务是由mainWorker本身执行的,则可以使用publish()process()方法来更新gui。

但是由于任务是由与Swingworker线程不同的线程执行的,因此如何从执行任务的线程生成的中间结果中更新gui。

最佳答案

SwingWorker的API文档提供了以下提示:

调用doInBackground()方法
在这个线程上。这是所有
应该进行后台 Activity 。
通知PropertyChangeListeners
关于绑定属性的更改,请使用
firePropertyChange和
getPropertyChangeSupport()方法。通过
默认有两个绑定属性
可用:状态和进度。
MainWorker可以实现PropertyChangeListener。然后可以使用PropertyChangeSupport注册自己:

getPropertyChangeSupport().addPropertyChangeListener( this );
MainWorker可以为其创建的每个PropertyChangeSupport对象提供其MyTask对象。
new MyTask( ..., this.getPropertyChangeSupport() );

然后,MyTask对象可以使用MainWorker方法将其进度或属性更新通知给PropertyChangeSupport.firePropertyChange

如此通知的MainWorker然后可以使用SwingUtilities.invokeLaterSwingUtilities.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;
}

10-04 13:31