Java – SwingWorker – 我们可以从其他SwingWorker而不是EDT调用一个SwingWorker
我有一个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()方法。 这是所有背景活动应该发生的地方。 要通知PropertyChangeListeners有关绑定属性的更改,请使用firePropertyChange和getPropertyChangeSupport()方法。 默认情况下,有两个绑定属性:状态和进度。
MainWorker
可以实现PropertyChangeListener
。 然后它可以使用PropertyChangeSupport
注册自己:
getPropertyChangeSupport().addPropertyChangeListener( this );
MainWorker
可以将其PropertyChangeSupport
对象提供给它创建的每个MyTask
对象。
new MyTask( ..., this.getPropertyChangeSupport() );
然后, MyTask
对象可以使用PropertyChangeSupport.firePropertyChange
方法通知其MainWorker
进度或属性更新。
MainWorker
,通知的MainWorker
可以使用SwingUtilities.invokeLater
或SwingUtilities.invokeAndWait
通过EDT更新Swing组件。
protected Void doInBackground() { final int TASK_COUNT = 10; getPropertyChangeSupport().addPropertyChangeListener(this); CountDownLatch latch = new CountDownLatch( TASK_COUNT ); // java.util.concurrent Collection threads = new HashSet (); 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; }
即使您不使用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 } }); }
以下是使用SwingWorker
启动多个线程的示例 。 CountDownLatch
确保doInBackground()
仅在所有线程完成时返回。 每个线程使用JTextArea
的线程安全的append()
方法来更新GUI,但EventQueue.invokeLater()
将是一个方便的替代方案。
阅读这些技巧,以清楚地了解您的问题
线程和Swing
使用Swing Worker线程
Swing Threads中的最后一个单词