简体   繁体   English

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

[英]Java - SwingWorker - Can we call one SwingWorker from other SwingWorker instead of EDT

I have a SwingWorker as follows: 我有一个SwingWorker如下:

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

I invoked the above Swing Worker from EDT: 我从EDT调用了上面的Swing Worker

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

Now, the mainWorker creates 10 instances of a MyTask class so that each instance will run on its own thread so as to complete the work faster. 现在, mainWorker创建了MyTask类的10个实例,以便每个实例都可以在自己的线程上运行,从而更快地完成工作。

But the problem is I want to update the gui from time to time while the tasks are running. 但问题是我想在任务运行时不时更新gui。 I know that if the task was executed by the mainWorker itself, I could have used publish() and process() methods to update the gui. 我知道如果任务是由mainWorker本身执行的,我可以使用publish()process()方法来更新gui。

But as the tasks are executed by threads different from the Swingworker thread, how can I update the gui from intermediate results generated by threads executing tasks. 但是由于任务是由不同于Swingworker线程的线程执行的,我如何从执行任务的线程生成的中间结果更新gui。

The SwingWorker's API documentation offers this hint: SwingWorker的API文档提供了以下提示:

The doInBackground() method is called on this thread. 在此线程上调用doInBackground()方法。 This is where all background activities should happen. 这是所有背景活动应该发生的地方。 To notify PropertyChangeListeners about bound properties changes use the firePropertyChange and getPropertyChangeSupport() methods. 要通知PropertyChangeListeners有关绑定属性的更改,请使用firePropertyChange和getPropertyChangeSupport()方法。 By default there are two bound properties available: state and progress. 默认情况下,有两个绑定属性:状态和进度。

MainWorker can implement PropertyChangeListener . MainWorker可以实现PropertyChangeListener It can then register itself with its PropertyChangeSupport : 然后它可以使用PropertyChangeSupport注册自己:

getPropertyChangeSupport().addPropertyChangeListener( this );

MainWorker can supply its PropertyChangeSupport object to every MyTask object it creates. MainWorker可以将其PropertyChangeSupport对象提供给它创建的每个MyTask对象。

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

A MyTask object can then notify its MainWorker of progress or property updates by using PropertyChangeSupport.firePropertyChange methods. 然后, MyTask对象可以使用PropertyChangeSupport.firePropertyChange方法通知其MainWorker进度或属性更新。

MainWorker , so notified, can then use SwingUtilities.invokeLater or SwingUtilities.invokeAndWait to update the Swing components via the EDT. MainWorker ,通知的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;
}

Even if you do not use SwingWorker, you can always post things to do in the EDT using SwingUtilities.invokeLater(...) or SwingUtilities.invokeAndWait(...) 即使您不使用SwingWorker,也可以使用SwingUtilities.invokeLater(...)或SwingUtilities.invokeAndWait(...)在EDT中发布要做的事情。

EDIT: suppose that you have a thread executing some code, you can always interact with EDT like in the example below. 编辑:假设您有一个执行某些代码的线程,您可以随时与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
        }
    });
}

Here is an example that uses a SwingWorker to launch multiple threads. 以下是使用SwingWorker启动多个线程的示例 A CountDownLatch ensures that doInBackground() returns only when all threads have completed. CountDownLatch确保doInBackground()仅在所有线程完成时返回。 Each thread uses the thread-safe append() method of JTextArea to update the GUI, but EventQueue.invokeLater() would be a convenient alternative. 每个线程使用JTextArea的线程安全的append()方法来更新GUI,但EventQueue.invokeLater()将是一个方便的替代方案。

Read these artcles to get a clear picture of your problem 阅读这些技巧,以清楚地了解您的问题

Threads and Swing 线程和Swing

Using a Swing Worker Thread 使用Swing Worker线程

The last word in Swing Threads Swing Threads中的最后一个单词

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM