13

假设我有以下代码:

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()在这里使用,但我需要一个线程来调用它,而且我不知道如何doInBackground()从我需要调用的地方获取 's 线程join()。谢谢你的帮助。


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

有没有办法让“完成”打印一次doInBackground完成?GUI 更新代码和“完成”语句是否在同一个线程上?我需要创建一个新线程吗?

4

4 回答 4

11

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

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

于 2010-11-23T22:37:08.557 回答
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");
}
于 2010-11-23T22:34:30.607 回答
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来管理后台线程,您可能想要阅读这些线程,而不是尝试 join/yield 方法。

于 2010-11-30T18:41:30.760 回答
0

一般来说,你必须坚持到SwingWorker它完成,你可以通过调用它来测试isDone()它。否则只需调用get()使其等待。

于 2010-11-23T22:35:50.153 回答