javaswingevent-dispatch-threadinvokelaterswingutilities

Is javax.swing.SwingUtilities.invokeLater nesessary?


So I have seen countless different GUI tutorials, and all of them have said to use this code:

   public static void main(String[] args) {
     javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            createAndShowGUI();
        }
    });

}

And although I may not quite understand what this exactly does, since I'm somewhat new to GUI, I do understand the basics of what it does... or so I thought. But then I, as an experiment, cut it all out, and just left:

   public static void main(String[] args) {
     createAndShowGUI(); 
   }

And it appeared to work. So now I have a question: what is the purpose of keeping the first piece of code I had, rather than just using the second, when it seemed like the second worked just as fine? If it is necessary, what will happen if I don't use it?


Solution

  • In short, yes, it is necessary whenever you make changes to any Swing object (unless the API says they are thread safe).

    Any changes you make to the GUI must be made on the Event Dispatch Thread (EDT) because the Swing objects are not thread safe. From the Event Dispatch Thread Tutorial

    Swing event handling code runs on a special thread known as the event dispatch thread. Most code that invokes Swing methods also runs on this thread. This is necessary because most Swing object methods are not "thread safe": invoking them from multiple threads risks thread interference or memory consistency errors. Some Swing component methods are labelled "thread safe" in the API specification; these can be safely invoked from any thread. All other Swing component methods must be invoked from the event dispatch thread. Programs that ignore this rule may function correctly most of the time, but are subject to unpredictable errors that are difficult to reproduce.

    Calling SwingUtilities.invokeLater ensures that the code int he runnable is invoked on the EDT and you don't get weird errors. That is why when you removed that code it looks like everything is working, because in the situations you tested it probably did. But it might not always and you don't want to have code that works sometimes or has timing issues.