I am new to java and there was an interview question for a Graduate role which i didn't understand, so can you tell me which thread and its purpose please.
Swing UI toolkit is single threaded (in the sense that it is unsafe to call any of the swing libraries from any other thread). All the UI events, both rendering and dispatching them is done by the EDT thread.
So on clicking at a button on desktop. The OS gives the notification to EDT which receives the event and then triggers the callback function which was registered for the button click. Moreover from the code, when you do some action (for ex: repaint screen or draw Image). The EDT delivers the change to the OS and it is rendered on the screen. Hence a 2-way interaction.
Because as mentioned Swing UI toolkit is single-threaded. Hence it is advisable to call any of the Swing libraries from EDT only usign System.invokeLater. More info here.
You're looking for the Event Dispatch Thread.
Knowing about it is pretty.. important. It is vital to understand what thread your code will end up running on - long-running tasks should not be run on the EDT. Instead, dispatch those tasks on their own thread, then run a callback at the end of the operation to update the GUI using SwingUtilities.
Related
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?
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, ...).
Swing is single threaded and all changes to the GUI must be done on EDT
Basic usage for invokeLater()
Main methods should be always wrapped in invokeLater()
Delayed (but asynchronously) action/event to the end of EventQueue,
If EDT doesn't exists then you have to create a new EDT by using invokeLater(). You can test it with if (SwingUtilities.isEventDispatchThread()) {...
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)
Basic stuff: Concurrency in Swing
All output from background tasks must be wrapped in invokeLater()
Every Swing application has at least 2 threads:
The main thread that executes the application
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.
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.
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.
I was comparing the differences between Swing's SwingWorker and Android's AsyncTask classes. While Android has a Main Thread/UI Thread and then spawns a background thread (using AsyncTask), SwingWorker has three threads that are involved -
Current thread
Worker thread
Event Dispatch Thread.
And then I also came across the statement (in docs) -
Often, the Current thread is the Event Dispatch Thread.
Now, what does this mean?
Does it mean that Swing also has only 1 thread - the Main Thread and
even the events are received on the same thread OR
Is it different for different JVM implementations?
This is only valid for Swing, which shares some similarities with Android UI programming but is indeed not the same.
A little bit of context
The EDT (Event Dispatch Thread) is Swing's thread dedicated to handling UI events (mouse and keyboard input, events on controls, rendering of the UI, etc...).
This is an Event Loop model, similar to what is done in Android.
The fact that event listeners in Swing are executed on the EDT is the root cause for freezing UIs in Swing applications: developers misunderstanding the threading model often put long-running code in the listeners, which blocks the EDT and thus the GUI.
SwingWorker was introduced to better guide developers in separating UI updates from long-running background code. It spawns a dedicated background thread for the I/O processing (or long-running task) in doInBackground and executes UI updates in done and process methods. While these 3 methods guarantee in which thread they'll be executed, all other methods are executed in the current thread.
What is meant by the sentence you quoted
The whole reason for SwingWorker to exist is to properly initiate a long-running process from the GUI, without blocking the GUI.
Often, it will be in reaction to a user's input (e.g. clicking a Button). Since reactions to the user's input (implemented as Listeners) are always executed in the EDT by the Swing framework, unless you happen to call execute or get from another thread explicitly, it will get executed on the EDT.
By the way, execute is "fire-and-forget" and is the typical use-case (call it from a listener). get on the other hand blocks, and is not suited to be called from a listener (it would defeat SwingWorker's purpose, call it on your own threads if needed)!
I'm coding a Java 7 Swing application which calls a non-GUI class to do something in a loop. Unfortunately, I can't interact with the GUI while the loop is running. Is it possible to force the processing of GUI events while in that loop?
I'm searching for something that tells the JVM to process other GUI events like button clicks before continuing with the loop.
Is there something in Java 7 Swing that does what I want or do I really have to mess with multi-threading by myself (I'm not that far yet...)?
No, unlike Qt framework (which is C++ based), Java does not support manually processing and/or dispatching UI events (at least, at time of writting, 2022).
In other words, don't block the EDT (Event Dispatch Thread) - the GUI will 'freeze' when that happens (and there is not way out yet).
Instead of calling Thread.sleep(n) implement:
a Swing Timer for repeating tasks
or a SwingWorker for long running tasks.
See Concurrency in Swing for more details.
Use a SwingWorker. Basically, all UI event handling is always done on a single specific thread, called the Event Dispatch Thread, and doing anything else in that thread prevents UI events (mouse clicks, keyboard input etc) from being processed and thus makes the UI "hang".
The SwingWorker class was added to the JRE specifically for doing time-consuming tasks "in the background" (not in the UI thread) and allows you to easily do your heavy lifting someplace else, optionally update the UI at intervals (think progress bar), and, again optionally, update the UI once you're done. You do this simply by overriding specific methods (doInBackground() and done()) and you never need to directly deal with threading.
The SwingWorker Javadoc page has everything you need to start using it, including example code.
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?
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, ...).
Swing is single threaded and all changes to the GUI must be done on EDT
Basic usage for invokeLater()
Main methods should be always wrapped in invokeLater()
Delayed (but asynchronously) action/event to the end of EventQueue,
If EDT doesn't exists then you have to create a new EDT by using invokeLater(). You can test it with if (SwingUtilities.isEventDispatchThread()) {...
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)
Basic stuff: Concurrency in Swing
All output from background tasks must be wrapped in invokeLater()
Every Swing application has at least 2 threads:
The main thread that executes the application
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.
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.
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.
Why is it necessary to put GUI update code in SwingUtilities.invokeLater()?
Why cant it be internally taken care of by Swing itself? Why does the caller have to care about how swing handles UI updates?
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]
Because GUI updates must be done in the event dispatch thread. If you're operating in a different thread, doing the update in invokeLater yanks it out of your thread and into the event thread.
More explanation here: http://www.oracle.com/technetwork/java/painting-140037.html
The smart thing to do with big updates (like repopulating a JTable from the database) on Swing is to get the underlying model, do the updates on the model in your thread, then fire off a notification using invokeLater. That keeps your gui responding to events and redrawing. If the update is going to be very extensive, you can even fire off these notifications with invokeLater at regular intervals while you're updating, like every second or two.
Swing is single-threaded. Every update to the UI must happen from the so-called EDT – the event-dispather thread which is the main GUI thread Swing (and I think AWT) uses. If you don't do this, then weird things can or will happen (though I like Windows Forms better here which just throws an exception if you do it wrong).
That being said, you don't need to wrap every single UI operation into SwingUtilities.invokeLater() – if the code you're writing is already executed by the EDT this isn't needed. So the ActionListener for a button click doesn't need this. But a listener on an external object, running in some other thread, that updates a JLabel somewhere – there you need it.
Swing was not written to be a thread safe GUI toolkit so all GUI updates should happen from a single thread to avoid any deadlocks. In Swing this is the Event Dispatcher Thread (EDT).
See Concurrent in Swing from the Java tutorial for more details. It also references this blog entry on why it is hard to write a multithreaded GUI toolkit.
All the painting of the components should be performed in a single thread, so, they are rendered properly. That way the component will know, what part has already been painted and which part hasn't.
If you invoke a "painting" related method ( paint, update, paintComponent, show, setVisible, pack etc. ) outside the EDT, you'll be trying to paint in two different threads, and that may bring problems.
When you need to use another thread to update the UI, you should invoke it with the invokeLater facility, which in turn will put it in the EDT for you, so you still paint in the same thread.
You don't need to use it, if you're coding in a method that runs in the EDT already ( for instance, actionPerformed or paint or one of those ) Or if you are executing code not UI related ( for instance, processing files in the background etc. )
To better understand all these concepts read:The single thread rule
SwingUtilities.invokeLater()
Causes doRun.run() to be executed asynchronously on the AWT event dispatching thread. This will happen after all pending AWT events have been processed. This method should be used when an application thread needs to update the GUI.
...
Repeating others: Swing is not thread safe so one thread must do all the updates to avoid concurrency problems. invokeLater is an utility method to execute something inside the event processing thread.
Why doesn't Swing does it internally: this is my impression... I think because it would be overkill -to check every place where an update is taking place. It would bloat the Swing code, dificult the review and maintainability of the code.
By the other hand it's not that dificult for an application to know if it's not executing inside the GUI thread and call invokeLater. It will be when the own application launched some thread before.