In my application, I would like to do something like
- show a wait dialog, where some preparatory task is happening in the background
- after that preparatory task is done, close the dialog
- when dialog is closed (or
SwingWorker.done()
, execute the rest of my code)
I started noticing problems: the code after my new WaitScreen().execute();
was being executed before it and I had to manually close the dialog to trigger the done()
.
To try to make sense of it, I took some simpler code, made it my own, and used it to emulate my problem. Here it is:
import java.awt.EventQueue; import java.awt.BorderLayout;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
public class SwingWorkerDialogTest
{
public static void main(String[] args)
{
new SwingWorkerDialogTest();
}
private JDialog dialog;
public SwingWorkerDialogTest()
{
EventQueue.invokeLater(new Runnable()
{
@Override
public void run()
{
try
{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch (ClassNotFoundException | InstantiationException | IllegalAccessException ex)
{
}
catch (javax.swing.UnsupportedLookAndFeelException ex)
{
}
MyWorker worker = new MyWorker(true);
worker.execute();
new MyWorker(false).execute();
}
});
}
public class MyWorker extends SwingWorker<Object, Object>
{
private boolean runGUI;
public MyWorker(boolean b) { this.runGUI = b; }
@Override
protected Object doInBackground() throws Exception
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
if (runGUI)
{
getDialog().setVisible(true);
}
else
{
for (int j = 0; j < 30; j++)
{
System.out.println("j == " + j);
}
}
}
});
Thread.sleep(20000);
return null;
}
@Override
protected void done()
{
System.out.println("now in done...");
JDialog dialog = getDialog();
// Don't care, dismiss the dialog
//dialog.setVisible(false);
dialog.dispose();
}
}
protected JDialog getDialog()
{
if (dialog == null)
{
dialog = new JDialog();
dialog.setModal(true);
dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
dialog.setLayout(new BorderLayout());
dialog.add(new JLabel("Please wait..."));
dialog.setSize(200, 200);
dialog.setLocationRelativeTo(null);
}
return dialog;
}
}
It was working fine when there was only worker
running. But, the instant I execute()
d another MyWorker
, my problem reoccurred. How do I remedy this?