我如何等待SwingWorker的doInBackground()方法?

时间:2010-11-23 22:32:14

标签: java swing synchronization swingworker

说我有以下代码:

import java.lang.InterruptedException;
import javax.swing.SwingWorker;

public class Test
{
    private JDialog window;

    public Test
    {
        // instantiate window
    }

    private class Task extends SwingWorker<Void, Void>
    {
        public Void doInBackground()
        {
            try { Thread.currentThread().sleep(5000); }
            catch(InterruptedException e) {}
            return null;
        }
    }

    public void doTask()
    {
        Task task = new Task();
        task.execute();
    }

    protected void process()
    {
        // update various GUI components here
    }

    public static void main(String args[])
    {
        Test t = new Test();
        t.doTask();
        System.out.println("done");
    }
}

我需要等到t.doTask()完成才能打印出'完成',但我不确定具体如何。我知道我应该在这里使用join(),但我需要一个线程来调用它,我不知道如何从我需要调用{{1}的地方获取doInBackground()的线程}。谢谢你的帮助。


编辑:感谢您的回复。不幸的是,join()等并没有完全解决问题。在我的实际代码中,SwingWorker还有一个重写的get()函数,它在后台线程运行时更新GUI窗口。 process()确实在get()之后打印'完成',但GUI不会更新。我更新了我的示例代码以反映这一点,虽然现在它当然不会编译。

只有在doInBackground完成后才能打印'完成'的方法吗? GUI更新代码和'done'语句是否在同一个线程上?我需要制作新帖吗?

4 个答案:

答案 0 :(得分:11)

通常,在SwingWorker完成其后台工作后需要完成的任何操作都是通过覆盖其中的done()方法完成的。完成后在Swing事件线程上调用此方法,允许您更新GUI或打印出一些内容或其他内容。如果确实需要阻止直到完成,您可以致电get()

NB。在get()方法中调用done()将立即返回您的结果,因此您不必担心阻止任何UI工作。

答案 1 :(得分:9)

调用get()会导致SwingWorker阻止。

来自Javadocs:

T get() 
      Waits if necessary for the computation to complete, 
      and then retrieves its result.

您的代码将如下所示:

public static void main(String args[])
{
    Test t = new Test();
    t.doTask();
    t.get();  // Will block
    System.out.println("done");
}

答案 2 :(得分:5)

您可以覆盖done()方法,该方法在doInBackground()完成时调用。在EDT上调用done()方法。如下所示:

@Override
protected void done() {
  try {
    super.get();

    System.out.println("done");
    //can call other gui update code here
  } catch (Throwable t) {
    //do something with the exception
  }
}

在done内部调用get()方法有助于恢复在doInBackground期间抛出的任何异常,所以我强烈推荐它。 SwingWorker在内部使用Callable和Future来管理后台线程,您可能想要阅读它而不是尝试连接/收益方法。

答案 3 :(得分:0)

一般情况下,您必须抓住SwingWorker直到完成为止,您可以通过调用isDone()来测试它。否则只需拨打get()即可让它等待。