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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4261666/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 15:08:10  来源:igfitidea点击:

How do I wait for a SwingWorker's doInBackground() method?

javaswingsynchronizationswingworker

提问by Max

Say I have the following code:

假设我有以下代码:

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");
    }
}

I need to wait until t.doTask()is done before printing out 'done', but I'm not sure exactly how. I know I should probably use join()here, but I need a thread to call it on, and I don't know how to get doInBackground()'s thread from where I need to call join(). Thanks for any help.

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



EDIT: Thanks for the responses. Unfortunately, get()and the like don't quite solve the problem. In my actual code, the SwingWorker also has an overridden process()function that updates a GUI window while the background thread is running. get()does stop 'done' from being printed till after doInBackground, but then the GUI doesn't update. I updated my sample code to reflect this, although now of course it won't compile.

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

Is there a way to get 'done' to print only once doInBackgroundis finished? Are the GUI update code and the 'done' statement on the same thread? Do I need to make a new thread?

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

采纳答案by ColinD

Typically anything that needs to be done after a SwingWorkercompletes its background work is done by overriding the done()method in it. This method is called on the Swing event thread after completion, allowing you to update the GUI or print something out or whatever. If you really do need to block until it completes, you can call get().

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

NB. Calling get()within the done()method will return with your result immediately, so you don't have to worry about that blocking any UI work.

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

回答by jjnguy

Calling get()will cause the SwingWorkerto block.

调用get()将导致SwingWorker阻塞。

From the Javadocs:

来自 Javadocs:

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

Your code will then look like:

您的代码将如下所示:

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

回答by Actorclavilis

In general, you must hold onto the SwingWorkeruntil it finishes, which you can test by calling isDone()on it. Otherwise just call get()which makes it wait.

通常,您必须保持SwingWorker直到它完成,您可以通过调用isDone()它来测试。否则只需调用get()使其等待。

回答by Jim

You can override the done() method, which is called when the doInBackground() is complete. The done() method is called on EDT. So something like:

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

@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
  }
}

Calling the get() method inside the done helps get back any exceptions that were thrown during the doInBackground, so I highly recommend it. SwingWorker uses Callable and Futureinternally to manage the background thread, which you might want to read up on instead of trying the join/yield approach.

在 done 中调用 get() 方法有助于恢复在 doInBackground 期间抛出的任何异常,因此我强烈推荐它。SwingWorker 在内部使用 Callable 和Future来管理后台线程,您可能希望阅读这些内容而不是尝试 join/yield 方法。