I'm new to Java and after reading many articles about threads and swing I understood that all the invocations of Swing methods should be done on the EDT because Swing is not thread safe. however, I already wrote a couple of quite long Swing applications before reading about the EDT. and all of my applications ran quite fine. So my question is were my Swing applications running on the EDT by default or were they running on a different thread and i was just lucky not to have any issues with them?
Like for example if I add a JButton to a JPanel or JFrame, or if I simply call a JTextField's Field.setText(), will these operations be running on the EDT by default or no?
and if the answer is no, then do I have to explicitly send all my Swing component's methods implementations to run on the EDT by invoking SwingUtilities.invokeLater()
Thanks
Remember objects don't live on threads, only execution of methods happens on a thread.
All action emerging (through listeners) from swing components automatically run on the EDT.
For instance a button you click, the onClicked() function will already run on the EDT so you don't need to do anything.
If you don't create any threads explicitly, your basic application will have a main thread and an EDT (and many other threads that you don't accidentally get your code executed on, until you start using extra frameworks).
The thing you have to do manually is construct the GUI on the EDT. As you can see here this can be done in your main thread as follows:
SwingUtilities.invokeLater(new Runnable() {
public void run() {
MyWindow window = new MyWindow ();
window.setVisible(true);
}
});
If you fail to use the EDT correctly. Everything will seem to work fine, but every now and then you can get very strange behavior (because two threads will be doing things instead of one).
So in summary you have to use invokeLater(), or in some exceptions invokeNow() in the following cases:
Constructing Swing components from the main thread.
Calling swing components from your personally created threads.
Calling swing components from events on threads created by frameworks.
This question contains some tools that can help you automatically detect errors (not all though).
where my Swing applications running on the EDT by default or were they running on a diffrent thread and i was just lucky not to have any issues with them?
They were mostly being ran on the EDT. All the painting and updating that Swing does by itself is on the EDT. Anything you do specifically in your code base that you know wasn't on the EDT, is the code that was not on the EDT. So these would be actions like querying the text of a JLabel, or setting the text of a JLabel, or initializing the JLabel itself.
The various listener methods that are executed by Swing which you have implemented in your code base are however executed on the EDT (as long as Swing called it, not yourself). So in these methods you can query/modify Swing components, but remember to properly transfer in and out any data you give to a Swing component or queried from a Swing component in a thread-safe manner.
Like for example if I create a JButton and add it to a JPanel or JFrame, are these operations running on the EDT by default or no?
The initialization of the objects happens on whatever thread you created them on, and so are the rest of the modifications of the Swing objects (like adding one component to another). I do not know of any Swing components whose public method implementations are wrapped in their own invokeNow() or invokeLater() call, so it's best to assume all portions of the actions happened on whatever thread you called the original methods on.
do I have to explicitly send all my Swing components and methods to run on the EDT by invokingSwingUtilities.invokeLater()
Yes, or invokeNow()
Components will be accessed from within the thread context they are called, wch leads to a problem...
All Swing components (or enough not to matter) MIST be accessed within the context of the Event Dispatching Thread once they have been added to a displayable container (attached to a native peer).
This makes Swing components NOT thread safe and you are responsible for ensuring that they are modified/accessed from the EDT correctly, the framework will NOT do it for you
Take a look at Concurrency in Swing for more details
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 read somewhere that for any thread that affects the visuals of the gui it should be ran in the EDT using SwingUtilities.invokeAndWait/invokeLater
For a basic gui, is it necessary to put something like new SwingGUI().setVisible(true); in the line of the EDT using invokeAndWait? Just to display?
Does this count?
The short answer to your question is: yes, even calling setVisible should happen on the EDT. To find out whether the current thread is the EDT, you can use the EventQueue#isDispatchThread method
Some reference links:
Multithreaded Swing Applications
Threads and Swing
Concurrency in Swing
Edit:
after reading the links I provided, it seems some of the articles on the Oracle site are outdated as in they still document you can create Swing components on another thread. There is a stackoverflow question on this which contains some nice answers and links to blogposts and articles about the 'new' policy (new as in a few years old)
Yes, if you touch a Swing object you have to do it on the EDT. In most cases you are already there, but if not, use the SwingUtilities classes. The reason for this is that the Swing classes are not multi-threaded, so you are likely to cause nasty problems if you access it on other threads. And it could be that setVisible() is doing a lot of things under the covers to make something display (like re-laying things out). Better to be safe.
Anything that is called from your
public static void main(String[] agrs) {
directly (without spawning another thread or using invokeLater) is running on the main thread.
Accessing GUI objects with the main thread while they may be being accessed (simultaneously) by the EDT (which is triggered by user input) can cause threading issues. Calling invokeLater causes tasks (runnables) to run on the EDT, preventing simultaneous access by other EDT tasks ie. button presses etc.
If you can be sure the EDT is not busy (before the first window is setVisible(true)) you can access the GUI from the main thread. If you can be sure the EDT has no reference to the component you're working on (it is out of EDT's scope) ie. before it's added to any container, you can access it from main thread without the EDT accessing it simultaneously, as the EDT has no way to reach it.
Everything that access Swing objects should do so via the Event Dispatch Thread (EDT). There is one small exception to this (which I'll mention later). The purpose of the EDT is to process any events that may occur due to IO (mouse and keyboard events). Quite a lot of the time this can mean altering the layout of your GUI. Swing was not developed to be thread-safe, meaning that that if two thread try to modify the same component at the same time then you can end up with a corrupted GUI. Since there is already one known thread to be accessing Swing components (the EDT), no other thread should attempt to modify them or even read their state.
Now, to the exceptional case when you can manipulate Swing objects outside of the EDT. Before any components have become visible it is not possible for IO to be triggering events. Therefore, the main thread can setup a Swing GUI and then set a single JFrame to be visible. Since there is now a visible frame IO events can occur and the main thread should not try to modify any more Swing components. The should only use this option to get a GUI started, and really only with toy problems.
What I'm saying is that the following is fine and won't cause problems if you're just playing around with stuff.
public static void main(String[] args) {
// create components
JFrame f = new JFrame();
...
// do layout and other bits of setup
// show gui to user
f.setVisible(true);
}
I learned about how swing isn't thread-safe. Delving deeper, I discovered that every modification to a swing component must be done on the Event Dispatch Thread in order to prevent various issues associated with multithreading. However, the information seemed to completely stop there. There doesn't seem to be a good tutorial that explains how to do this anywhere accessible on the internet.
Patching together information from code posted in relation to other issues, it seemed that I would have to put an untidy block of code around every single swing modification in my program (like this example from my own code):
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
setTitle("Frame title");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
setSize(800, 480);
setLocationRelativeTo(null);
setIconImage(Toolkit.getDefaultToolkit().createImage(ClassLoader.getSystemResource("Frame icon.png")));
}
});
} catch (Exception e) {
e.printStackTrace();
}
Basically, is this right? Do I have to put that code (or the equivalent with invokeLater) around every modification to a Swing component in my code?
Also, why doesn't Swing do this automatically?
The trick is that when swing calls you it will ALWAYS be in the EDT, so you don't have to worry about it.
However if you are in a timer or an action triggered by some other external event, your main thread or any other thread you've created then yes, you have to use invokeLater or invokeAndWait.
In other words, yes swing does do "it" automatically. Needing to use invokeXx is so rare that if swing were to do it internally it would waste too much time.
Many java programmers never figure this out and it can cause some pretty nasty hard-to-find problems with drawing your GUI. I do wish swing threw an exception when you called it not using the EDT--Java would have a better reputation when it came to professional GUIs if it did because there would be less crap out there.
note that any code executed from event handlers is already run in the EDT (the Event in the acronym)
this means that for general use (while you don't mess with swingworkers and threadpools and such) you are always inside the EDT
and you can always query if you are in the EDT with SwingUtilities.isEventDispatchThread()
also note that in your code the call to invokeAndWait will fail and throw an error when you are in the EDT already
Basically, you dont draw or update the GUI from outside of the EDT.
You use SwingUtilitis.invokeLater() from another thread to ensure the GUI drawing or updating code is run on the EDT.
Not all your UI code must be part of a runnable in an invokeLater call. That is simply because a large part of your program will be run on the EDT anyway. You need to dispatch messages to the EDT only when you are on a different thread.
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.