Java - SwingWorker - 我们可以从其他SwingWorker而不是EDT调用一个SwingWorker

Yat*_*oel 3 java user-interface swingworker

我有SwingWorker如下:

public class MainWorker extends SwingWorker(Void, MyObject) {
    :
    :
}
Run Code Online (Sandbox Code Playgroud)

Swing Worker从EDT 调用了上述内容:

MainWorker mainWorker = new MainWorker();
mainWorker.execute();
Run Code Online (Sandbox Code Playgroud)

现在,mainWorker创建一个MyTask类的10个实例,以便每个实例都在自己的线程上运行,以便更快地完成工作.

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

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

Noe*_*Ang 8

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

在此线程上调用doInBackground()方法.这是所有背景活动应该发生的地方.要通知PropertyChangeListeners有关绑定属性的更改,请使用firePropertyChange和getPropertyChangeSupport()方法.默认情况下,有两个绑定属性:状态和进度.

MainWorker可以实施PropertyChangeListener.然后它可以注册自己PropertyChangeSupport:

getPropertyChangeSupport().addPropertyChangeListener( this );
Run Code Online (Sandbox Code Playgroud)

MainWorker可以将其PropertyChangeSupport对象提供给MyTask它创建的每个对象.

new MyTask( ..., this.getPropertyChangeSupport() );
Run Code Online (Sandbox Code Playgroud)

然后,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;
}
Run Code Online (Sandbox Code Playgroud)