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

时间:2010-05-09 11:29:40

标签: java user-interface swingworker

我有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。

4 个答案:

答案 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.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;
}

答案 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启动多个主题的SwingWorkerCountDownLatch确保doInBackground()仅在所有线程完成后返回。每个线程使用append()的线程安全JTextArea方法来更新GUI,但EventQueue.invokeLater()将是一个方便的替代方案。

答案 3 :(得分:0)

阅读这些文章以清楚了解您的问题

Threads and Swing

Using a Swing Worker Thread

The last word in Swing Threads