Swingutilities.Invokelater() Why Is It Needed

What does SwingUtilities.invokeLater do?

As other answers have said, it executes your Runnable on the AWT event-dispatching thread. But why would you want to do that? Because the Swing data structures aren't thread-safe, so to provide programmers with an easily-achievable way of preventing concurrent access to them, the Swing designers laid down the rule that all code that accesses them must run on the same thread. That happens automatically for event-handling and display maintenance code, but if you've initiated a long-running action - on a new thread, of course - how can you signal its progress or completion? You have to modify a Swing control, and you have to do it from the event-dispatching thread. Hence invokeLater.

SwingUtilities.invokeLater() why is it needed?

Swing objects are not thread safe. SwingUtilities.invokeLater() allows a task to be executed at some later point in time, as the name suggests; but more importantly, the task will be executed on the AWT event dispatch thread. When using invokeLater, the task is executed asynchronously; there's also invokeAndWait, which won't return until the task has finished executing.

Some information about the decision not to make Swing thread-safe can be found here: Multithreaded toolkits: A failed dream? [Archived]

Why to use SwingUtilities.invokeLater in main method?

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.

SwingUtilities.invokeLater

Do I have to use each time I need to update the GUI components?

No, not if you're already on the event dispatch thread (EDT) which is always the case when responding to user initiated events such as clicks and selections. (The actionPerformed methods etc, are always called by the EDT.)

If you're not on the EDT however and want to do GUI updates (if you want to update the GUI from some timer thread, or from some network thread etc), you'll have to schedule the update to be performed by the EDT. That's what this method is for.

Swing is basically thread unsafe. I.e., all interaction with that API needs to be performed on a single thread (the EDT). If you need to do GUI updates from another thread (timer thread, networking thread, ...) you need to use methods such as the one you mentioned (SwingUtilities.invokeLater, SwingUtilities.invokeAndWait, ...).

What is SwingUtilities.invokeLater

Nothing bad will happen if you're updating it from the EDT while following guidelines.

That is...

If invokeLater is called from the event dispatching thread -- for
example, from a JButton's ActionListener -- the doRun.run() will still
be deferred until all pending events have been processed.

Source

If that isn't the case, invokeLater() is required.

It schedules a Runnable which will be executed on the EDT (event dispatching thread).

What exactly does the call to the SwingUtilities.invokeLater() method into the main class that perform a Swing application?

This is really two questions rolled into one.

  1. SwingUtilities.invokeLater() makes sure that whatever you want to do happens on the Event Dispatcher Thread. Since Swing is strictly single threaded, this is required for everything that interacts with Swing and doesn't already run in the EDT (e.g. is called as a result of an event handler) The main() method of your application is one such example, as it's invoked by the VM on startup in its own separate thread (called, unsurprisingly, the Main Thread).
  2. This is an anonymous inner class. It's a shortcut for creating a class that implements Runnable and creating an instance of that class straight away. (Note that it isn't completely equivalent with doing that, there are small but important details in which it is different.) SwingUtilities.invokeLater() will then put this Runnable object in the Swing event queue, which will be processed by the EDT (usually a couple of moments) later, calling the run() method you provided.


Related Topics



Leave a reply



Submit