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

发布于 2024-10-04 05:54:16 字数 1298 浏览 4 评论 0原文

假设我有以下代码:

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() 完成后再打印“done”,但我不确定具体如何。我知道我可能应该在这里使用 join() ,但我需要一个线程来调用它,而且我不知道如何获取 doInBackground() 的线程从我需要调用join()的地方。感谢您的任何帮助。


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

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

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.


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.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

瀞厅☆埖开 2024-10-11 05:54:16

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

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

Typically anything that needs to be done after a SwingWorker completes 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().

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.

窝囊感情。 2024-10-11 05:54:16

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

Calling get() will cause the SwingWorker to block.

From the 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");
}
乜一 2024-10-11 05:54:16

您可以重写 did() 方法,该方法在 doInBackground() 完成时调用。 did() 方法在 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
  }
}

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

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

@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 Future internally to manage the background thread, which you might want to read up on instead of trying the join/yield approach.

灯下孤影 2024-10-11 05:54:16

一般来说,您必须保留 SwingWorker 直至其完成,您可以通过调用 isDone() 对其进行测试。否则,只需调用 get() 即可使其等待。

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文