How do I wait for a SwingWorker's doInBackground() method?
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 Tas开发者_开发百科k 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?
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.
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");
}
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.
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.
精彩评论