Why to use SwingUtilities.invokeLater in main method?
Asked Answered
P

4

24

After years of Java programming I always used to create my main() methods like this :

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

But recently I studied some codes from the Web and saw this sometimes instead of the usual main() use above :

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

I simply want to know :

  • Why to use this instead of the usual main() way ? I can't see any difference when I give it a try.
  • What is the difference between these two ways ?

Thanks for reading me and your answers.

Psilocybin answered 8/3, 2013 at 19:47 Comment(0)
D
23

The docs explain why. From Initial Threads

Why does not the initial thread simply create the GUI itself? Because almost all code that creates or interacts with Swing components must run on the event dispatch thread.

and from The Event Dispatch Thread

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.

Dimphia answered 8/3, 2013 at 20:0 Comment(2)
I see, very interesting. Thanks for the links and having highlighted the essential.Psilocybin
Is there a small clear example of what can go wrong if main calls runProgram() directly? None of the linked references nor excerpts shown here seem to answer that, as far as I can see.Vernacularize
C
15

Because the thread "main" started by VM is not the event dispatch thread.

Chicoine answered 8/3, 2013 at 20:8 Comment(0)
K
3

A few Swing components from the API are not thread safe,which means that they may cause some problems like deadlock,So its better to create and update such swing components by using Event dispatcher thread provided by Swing but not from the main thread or any other thread created from main.

Kyanize answered 11/9, 2013 at 12:4 Comment(0)
R
1

While the answers above are all correct, I believe they lack a correct explanation.

Yes, everything that interacts with Swing (creating the UI, updating it, adding new components or layouts, etc.) should be always done on the AWT event-dispatch thread (see this post for more information on the topic).

SwingUtilities.invokeLater() places your code in the FIFO Queue of the event-dispatch thread (EDT), so it will be executed from the EDT whenever it has finished the other tasks it was doing.


Having that said, the EDT should be used exclusively to run Swing-related tasks that are quick to perform (if you block the EDT, you block the whole UI).

There is no point using SwingUtilities.invokeLater() on the main method if you aren't using Swing/AWT (e.g. a JavaFX app or a terminal app).

If you want to perform some tasks that have nothing to do with Swing at all but they're required to start Swing (e.g. starting the Model and Controller in a MVC-like app), you could do it either from the EDT or the Main thread (see this post for a discussion on this topic).

Reposition answered 17/3, 2021 at 12:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.