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?
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.
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.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.Calling
get()
will cause theSwingWorker
to block.From the Javadocs:
Your code will then look like: