如何等待 SwingWorker 的 doInBackground() 方法?
假设我有以下代码:
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
通常,在
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 thedone()
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 callget()
.NB. Calling
get()
within thedone()
method will return with your result immediately, so you don't have to worry about that blocking any UI work.调用
get()
将导致SwingWorker
来阻止。来自 Javadocs:
您的代码将如下所示:
Calling
get()
will cause theSwingWorker
to block.From the Javadocs:
Your code will then look like:
您可以重写 did() 方法,该方法在 doInBackground() 完成时调用。 did() 方法在 EDT 上调用。所以类似这样的事情:
在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:
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.
一般来说,您必须保留
SwingWorker
直至其完成,您可以通过调用isDone()
对其进行测试。否则,只需调用 get() 即可使其等待。In general, you must hold onto the
SwingWorker
until it finishes, which you can test by callingisDone()
on it. Otherwise just callget()
which makes it wait.