SwingUtilities.invokeLater
Asked Answered
P

5

56

My question is related to SwingUtilities.invokeLater. When should I use it? Do I have to use each time I need to update the GUI components? What does it exactly do? Is there an alternative to it since it doesn't sound intuitive and adds seemingly unnecessary code?

Phallus answered 25/8, 2011 at 20:38 Comment(4)
It's the equivalent of Control.BeginInvoke.Sustentacular
@Sustentacular Does that mean if I have one thread I don't have to use it?Phallus
@FadelMS, Since the Swing frameworks spawns a thread of its own (the EDT), you'll always have that thread. (You don't have a "message-checking"-loop that processes user-clicks etc, right? So how does the various actionPerformed methods get called? By the EDT!) So when you say you have one thread, I would have to intepret that as you only have the EDT (i.e., you threw up a GUI and fell off the edge of the main method). In that case, NO, you won't need to use invokeLater. However you won't be able to do any "background" processing. If you do, you'll lock up the GUI completely...Domiciliary
possible duplicate of What does SwingUtilities.invokeLater do?Heiney
D
54

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, ...).

Domiciliary answered 25/8, 2011 at 20:41 Comment(2)
@ Jens: Which means I can do without it if I'm on the same thread (Swing) or doing things at run time.Phallus
Well, "or doing things at run time" isn't very precise. If you do things in runtime, in, say, a timer-thread, then no, you can't do without these type of methods.Domiciliary
I
15
Swing is single threaded and all changes to the GUI must be done on EDT 

Basic usage for invokeLater()

  1. Main methods should be always wrapped in invokeLater()

  2. Delayed (but asynchronously) action/event to the end of EventQueue,

  3. If EDT doesn't exists then you have to create a new EDT by using invokeLater(). You can test it with if (SwingUtilities.isEventDispatchThread()) {...

  4. There exists invokeAndWait(), but till today I (just my view) can't find a reason for using invokeAndWait() instead of invokeLater(), except hard changes into GUI (JTree & JTable), but just with Substance L&F (excellent for testing consistency of events on the EDT)

  5. Basic stuff: Concurrency in Swing

  6. All output from background tasks must be wrapped in invokeLater()

Indiscretion answered 25/8, 2011 at 21:0 Comment(0)
K
7

Every Swing application has at least 2 threads:

  1. The main thread that executes the application
  2. The EDT (Event Dispatching Thread) is a thread that updates the UI (so the UI will not freeze).

If you want to update the UI you should execute code within the EDT. Methods like SwingUtilities.invokeLater, SwingUtilities.invokeAndWait, EventQueue.invokeLater, EventQueue.invokeAndWait allow you to execute code by the EDT.

Klutz answered 25/8, 2011 at 20:57 Comment(0)
L
7

My question this time is related to SwingUtilities.invokeLater: When should I use it?

What is key to understand is that Java has a separate thread (EDT) handling Swing related events.

You should use invokeLater() to display the main JFrame of a desktop application (for example), instead of trying to do it in the current thread. It will also create the context for graceful closing of the application later.

That's about it for most applications.

Do I have to use each time I need to update the GUI components? What does it exactly do?

No. If you modify a GUI component, it will trigger an event which is registered for later dispatching by Swing. If there is a listener for this event, the EDT thread will call it somewhere down the road. You don't need to use invokeLater(), just set your listeners on components properly.

Keep in mind that this thread is the same thread drawing frames etc... on your screen. Hence, listeners should not perform complex/long/CPU intensive tasks, otherwise your screen will freeze.

Is there an alternative to it since it doesn't sound intuitive and adds seemingly unnecessary code?

You don't need to write more code than displaying your application with invokeLater() + listeners you are interested in on component. The rest is handled by Swing.

Lickspittle answered 25/8, 2011 at 20:57 Comment(0)
B
3

Most user-initiated events (clicks, keyboard) will already be on the EDT so you won't have to use SwingUtilities for that. That covers a lot of cases, except for your main() thread and worker threads that update the EDT.

Begot answered 25/8, 2011 at 20:57 Comment(2)
Well, a user could update a file that is being monitored by a thread that updates the GUI.Begot
hmm ... that doesn't count as a (direct, that's where the rule holds) user-initiated event: the user updates the file (inside swing, on EDT) and save it (via clicking a button, on EDT), which triggers an OS file-update event (outside swing, off EDT) notification, that notification reaches the monitor (off EDT) which is responsible for updating the GUI on EDTTransmogrify

© 2022 - 2024 — McMap. All rights reserved.