2

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?

Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
  • 1
    `invokeLater()`, when needed, makes things run reliably. These are threading bugs which will not happen every time, but will happen, usually at the worst time. – user949300 Oct 02 '14 at 21:42
  • See http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html. The reason your code appears to work is that thread races are notoriously hard to reproduce. But the more complex your program gets, the more likely you will hit a thread bug *somewhere*, if you don't observe the swing threading rules. – kiheru Oct 02 '14 at 21:42
  • As you noted (and others stated), it will work without `invokeLater` *in most cases*. But I remember that I once used a special LookAndFeel which *reproducably* crashed when not invoked from the EDT. (Crashing in this case is legitimate, because it's simply a wrong usage of the API...) – Marco13 Oct 02 '14 at 22:37
  • Take a look at [Initial Threads](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html) for more details, but basically, yes, it is required (or at the very least, very, very, very highly recommneded) – MadProgrammer Oct 02 '14 at 23:39

1 Answers1

4

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.

mdewitt
  • 2,526
  • 19
  • 23