Steven C. Britton Steven C. Britton - 8 months ago 12
Java Question

Operation priority in Java. (An object instantiates and runs before the GUI is updated?)

I want the GUI to change the title of a button from "Go" to "Working..." before an object is instantiated and actually does the work. When finished, I want the title of the button to switch back to "Go."

Here's the code:

private class convert implements ActionListener {
public void actionPerformed(ActionEvent e) {
JButton button = (JButton)e.getSource();


anObject name = new AnObject();
boolean result = name.methodName(chooser.getSelectedFile(),encoding);

// A bunch of stuff was here but irrelevant to the question,
// so it was removed to save room.


What actually happens in practise is name is instantiated, methodName gets called, and THEN the button gets updated on the screen, despite the fact that I have told the VM to change the button title first.

My working theory is, given I have not made this program threaded, this has something to do with operational priority, or internal threading of the JVM, or something...

Any suggestions?


I know that you've already accepted a solution, but since you are running into the "frozen gui" syndrome, you most definitely have a threading issue, and invokeLater won't solve your problem. As noted above by extraneon, you need a SwingWorker or some background thread to solve this. Also, I think that this is a good case for use of an AbstractAction rather than an ActionListener. For example:

import java.awt.Dimension;
import java.awt.event.*;
import javax.swing.*;

public class Convert extends AbstractAction {
   private static final long SLEEP_TIME = 3000; // 3 seconds
   private String enabledText;
   private String disabledText;

   public Convert(String enabledText, String disabledText) {
      this.enabledText = enabledText;
      this.disabledText = disabledText;

   public void actionPerformed(ActionEvent e) {
      Object source = e.getSource();
      if (!(source instanceof JButton)) {
      final JButton button = (JButton) source;
      setButtonEnabled(button, false);
      new SwingWorker<Void, Void>() {
         protected Void doInBackground() throws Exception {
            // TODO: long-running code goes here. 
            // Emulated by Thread.sleep(...) 
            return null;

         protected void done() {
            setButtonEnabled(button, true);

   public void setButtonEnabled(JButton button, boolean enabled) {
      if (enabled) {
      } else {

   private static void createAndShowUI() {
      JFrame frame = new JFrame("Convert");
      frame.getContentPane().add(new ConvertGui());

   public static void main(String[] args) {
      java.awt.EventQueue.invokeLater(new Runnable() {
         public void run() {

class ConvertGui extends JPanel {
   public ConvertGui() {
      add(new JButton(new Convert("GO", "Working...")));

   public Dimension getPreferredSize() {
      return new Dimension(300, 200);