Same as scenario 1 except that the work in step B is much more complex and calls a custom class which does a bunch of db queries/writes that take, on average, about 3-6 seconds to complete. The custom class is not runnable or threaded and is simply called with;
customClass cc = new customClass(); cc.makeMyDataPlease(); for whatever reason, in scenario 2, the .setVisible(true) step 'A' does not happen until after the complex work step 'B' is completed.
The problem is, Swing is a single threaded environment. All interactions with the UI are expected to be executed within the context of the Event Dispatching Thread. Any process which blocks this thread, will prevent it from processing new events, including paint requests.
What's happening is that scenario 2 is most likely blocking the EDT, preventing it from displaying the window, but instead, by the time all you processing has completed, the EDT is responding to the close event immediately after the open event.
Because of the way the framework is structured, you must ensure that;
- All interactions and modifications to the UI are done within the EDT
- Any long running or block process is done outside of the EDT.
Start by taking a look at Concurrency in Swing for more details.
Without further evidence, my gut feeling is to use a SwingWorker
For example...
import java.awt.EventQueue;
import java.util.concurrent.ExecutionException;
import javax.swing.JLabel;
import javax.swing.JWindow;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class QuickWorker {
public static void main(String[] args) {
new QuickWorker();
}
public QuickWorker() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JWindow window = new JWindow();
window.add(new JLabel("Look no hands!"));
window.pack();
window.setLocationRelativeTo(null);
}
});
}
public class Worker extends SwingWorker<Object, Object> {
private JWindow window;
public Worker(JWindow window) {
this.window = window;
}
@Override
protected Object doInBackground() throws Exception {
// Long running process...
Thread.sleep(5000);
return "All done";
}
@Override
protected void done() {
try {
// Get the results of the process if you want them...
get();
} catch (InterruptedException | ExecutionException ex) {
ex.printStackTrace();
}
window.dispose();
// This is only here because the example will keep running without it :P
System.exit(0);
}
}
}