Search code examples
javaswinguser-interfaceswingworkeractionevent

GUI not updating visually before running ActionEvent


To expound a little more, I have a GUI that looks like:

enter image description here

Then I have an action listener on the OK button that starts like:

//OK Button Action Listener
private void okButtonActionPerformed(ActionEvent e) {   
    //Enable/Disable Buttons
    okButton.setEnabled(false);
    cancelButton.setEnabled(true);
    updateCheckbox.setEnabled(false);
    //Move on to a series of other methods here...

Which should, in theory, make this happen:

enter image description here

However, instead, I get the following until ALL methods and other things connected to the OK button are completed:

enter image description here

This obviously can't happen, because the idea is to make the cancel button available and the OK button and several other tick-boxes unavailable for the duration of the program (Image 2), where, instead, it freezes in a half-state (Image 3). Is there any way to combat this?


Solution

  • Every time you execute logic from the GUI you should be using the SwingWorker in the following way:

    SwingWorker myWorker= new SwingWorker<String, Void>() {
        @Override
        protected String doInBackground() throws Exception {
            //Execute your logic
            return null;
        }
    };
    myWorker.execute();
    

    If you want to update the GUI from inside this logic use InvokeLater:

    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            //To update your GUI
        }
    });
    

    With this you can be sure that both your logic and your GUI stay responsive.

    Edit:

    You could also use invokeAndWait if this suits your needs more. Link to related answer