3

我有一个SwingWorker如下:

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

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

MainWorker mainWorker = new MainWorker();
mainWorker.execute();

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

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

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

4

4 回答 4

8

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

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

MainWorker可以实施PropertyChangeListener。然后它可以用它自己注册PropertyChangeSupport

getPropertyChangeSupport().addPropertyChangeListener( this );

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

new MyTask( ..., this.getPropertyChangeSupport() );

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

MainWorker,收到通知后,就可以通过 EDT 使用SwingUtilities.invokeLaterSwingUtilities.invokeAndWait更新 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;
}
于 2010-05-13T19:45:23.617 回答
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
        }
    });
}
于 2010-05-09T11:58:21.957 回答
2

这是一个使用 a启动多个线程的示例。SwingWorkerACountDownLatch确保doInBackground()仅在所有线程完成后才返回。每个线程都使用线程安全append()的方法JTextArea来更新 GUI,但这EventQueue.invokeLater()将是一个方便的替代方案。

于 2010-05-13T22:10:07.067 回答
0

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

线程和摆动

使用 Swing 工作线程

Swing Threads 中的最后一句话

于 2010-05-13T03:47:24.343 回答