I couldn't find a better way to express the problem in the title of the question, but hopefully you'll understand...
I have the following code...
[...]
final JDialog waitingDialog = optionPane.createDialog(optionPane, "Processing in backgroung");
waitingDialog.setLocationRelativeTo(homeFrame);
waitingDialog.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
SwingWorker<Void, Void> backgroundThread = new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() throws Exception {
// Background processing is done here
System.out.println("[DEBUG] -- Background processing has started");
MyCustomClass.initParameters();
System.out.println("DEBUG] -- initParameters() has finished. Starting main processing now...");
waitingDialog.setVisible(true);
MyCustomClass.run();
return null;
}
// This is called when background thread above has completed
@Override
protected void done() {
waitingDialog.dispose();
};
};
backgroundThread.execute();
[and does other things after this...]
... which executes just fine until it hits MyCustomClass.run()
. When it is supposed to start such method, it simply doesn't do it. The application doesn't pause, stop or crash... it just keeps on waiting to continue after the background processing is done, which is not happening for some unknown reason.
MyCustomClass.run()
is a static
method over at MyCustomClass
. I suspected the problem could be with its name - run - so I changed it to some random thing like "doIt()", but the issue persisted.
The very first line on the method is a simple System.out.println("I got here")
, but not even that gets printed.
I added breakpoints just before and right after the method invocation and tried debugging, but that didn't help either. Everything seemed fine and I couldn't find out the problem.
Edit
I ask: how do I make the dialog show only when I wanted it to show? In other words, the script is:
Immediately off the bat I see that you're making Swing calls from within the SwingWorker's doInBackground, something which completely defeats the purpose of using a SwingWorker or background thread. Also, the call you're making, one that displays a modal dialog:
waitingDialog.setVisible(true); // **** here ****
MyCustomClass.run(); // **** not sure what this does or if this makes Swing calls or not.
will pause all code flow below it until the dialog is no longer visible, as that is how modal dialogs function. This is what is blocking your SwingWorker. You must try to separate your code so that Swing calls are only made on the Swing event thread, and use the worker for only the background work.
Instead
setVisible(true)
on your modal dialogIn pseudocode:
create modal dialog
create SwingWorker
Attach any PropertyChangeListeners to the SwingWorker (if needed)
Execute the SwingWorker
Display the modal dialog
So, the first quick change I would make in your code above would be to remove waitingDialog.setVisible(true);
from your SwingWorker doInBackground()
method, and then call the waitingDialog.setVisible(true);
method AFTER executing the SwingWorker, i.e., after backgroundThread.execute(); in particular. I know it seems counter-intuitive to call dispose on it seemingly before making it visible, but trust me, it will work better this way, since the dispose call will be blocked by the time it takes to run the background thread.