In my code, I initialize a JDialog:
dialog = new JDialog( frame, "Login", true );
dialog.setContentPane( panel );
dialog.setDefaultCloseOperation( JDialog.HIDE_ON_CLOSE );
dialog.setBounds( new Rectangle( 50, 50, 500, 500 ) );
When a button in my main application is clicked, I show the dialog and then run an expensive method with the data I get from it:
dialogWrapper.show(); // Runs dialog.setVisible( true ) directly
LoginCredentials credentials = dialogWrapper.getCredentials(); // Gets data from dialog
try {
SwingUtilities.invokeLater( new Runnable() {
@Override
public void run() {
progressBar.setIndeterminate( true );
mainWindow.getFrame().repaint();
accountModel.login( credentials );
System.out.println( "Successful login." );
mainWindow.getFrame().revalidate();
mainWindow.getFrame().repaint();
progressBar.setIndeterminate( false );
}
} );
} catch ( Exception ex ) {
// ...
}
My problem is that as soon as I click the button that runs dialog.setVisible( false )
:
- The dialog disappears
- The frame completely freezes up (the progress bar state doesn't ever change)
- After the message "Successful login." appears on the console, the frame is still frozen up
- After around 10 seconds have passed, the frame finally repaints and all the status messages I call as part of
accountModel.login()
appear on it
How can I make my main window components responsive as the login code is running?
As you can see, I have the entire thing wrapped in a SwingUtilities.invokeLater()
call, but that doesn't seem to be helping at all.