SwingWorker在Java中完成后启动另一个线程

时间:2014-11-06 20:49:47

标签: java multithreading swing swingworker

我知道有很多关于SO的问题,但是他们没有足够好的答案,在问这里之前我搜索了很多东西,但是没有什么可以说清楚。我只是想在我的SwingWorker完成其工作时启动我的其他线程。

我想在SwingWorker完成它的工作时启动一个计时器但是无法弄清楚如何。

class createGUI extends SwingWorker<Void, Void>
{
    @Override
    protected Integer doInBackground() throws Exception
    {
         //Some long processing
    }

    @Override
    protected void done()
    {
         //Doing GUI work here
         prgBar.setInderminent(false);
    }
}

//Starts a progressBar and calls createGUI();
prgBar.setInderminent(true);
new createGUI().execute();

现在还有另一个startTimer线程,我想在SwingWork完成时启动它。

public class startTimer implements Runnable
{
     @Override
     public void run()
     {
         while(true)
         {
             Thread.sleep(1000);
             //Update Database
         }
     }
}

但我不明白我该怎么办?

2 个答案:

答案 0 :(得分:3)

除非我遗漏了某些内容,否则您可以将构造函数中的引用传递给createGUI,并在done()时启动。

class createGUI extends SwingWorker<Void, Void>
{
  private Thread startTimer;
  public createGUI(Thread startTimer) {
    this.startTimer = startTimer;
  }
  @Override
  protected Integer doInBackground() throws Exception {
     //Some long processing
  }

  @Override
  protected void done()
  {
     //Doing GUI work here
     prgBar.setInderminent(false);
     startTimer.start();
  }
}

您还需要更改

new createGUI().execute();

类似

new createGUI(new Thread(new startTimer())).execute();

此外,班级名称应以大写字母开头。 CreateGUIStartTimer

答案 1 :(得分:1)

注意:Elliot的答案没有任何问题,期望它将工作流程耦合到工作者并将对象引用传递给工作者,否则不需要(对他的回答+1)

作为传递对可能不需要知道或关心此类事物的类的引用的替代方法,您可以使用SwingWorker s PropertyChangeListener支持。

这使工人脱钩并使其更可重复使用......

CreateGUI worker = new CreateGUI();
worker.addPropertyChangeListener(new PropertyChangeListener() {
    @Override
    public void propertyChange(PropertyChangeEvent evt) {
        if ("state".equals(evt.getPropertyName())) {
            SwingWorker.StateValue state = (SwingWorker.StateValue) evt.getNewValue();
            switch (state) {
                case DONE:
                    prgBar.setInderminent(false);
                    startTimer.start();
                    break;
            }
        }
    }
});
worker.execute();

哪个只会运行...

public class CreateGUI extends SwingWorker<Integer, Integer> {

    @Override
    protected Integer doInBackground() throws Exception {
        // Working hard or hardly working...
        return ???;
    }
}

就像旁注(因为工作者名称吓坏了我),Swing不是线程安全的,你不应该在事件调度线程之外创建或修改UI元素......

<强>更新...

如果您要做的就是链接线程的执行,那么您可以使用单线程ExecutorService,例如......

ExecutorService es = Executors.newSingleThreadExecutor();
es.submit(new CreateGUI());
es.submit(new StartTimer());

es.shutdown();

这可确保StartTimerCreateGUI完成或失败之前无法运行...