Swing: Passing a value back to the UI from a scheduled thread - java

I have a system tray UI in Java that requires a schedule database poll. What is the best method for spawning a new thread and notifying the UI?
I'm new to Swing and it's threading model.

SwingWorker is the exact thing designed to do this.
It allows you to run a task that won't block the GUI and then return a value and update the GUI when it is done.
Java has a great tutorial on how to use SwingWorker.
Basically do the database pull in the doInBackground() method. And, in the done() method, update your GUI.

As jinguy mentioned SwingWorker should be the first place you look at.
Wikipedia, of all places, has some interesting examples that may be good to look at before you tackle the JavaDocs.

As jjnguy mentioned, SwingWorker helps abstract away the complexity here, but basically you do the work in a new thread, and when the method comes back, you need to update the GUI in the swing thread. If you aren't using SwingWorker, the underlying method is SwingUtilities (or EventQueue) .invokeLater(Runnable).
Do not update anything Swing related (including models) outside of the swing queue, unpredictable things will happen. And don't attempt to hold a reference to the queue and use that, as queues are suspended and replaced (if for example you open a model dialog box).

Related

EventQueue.invokeLater in Java Swing

I am trying to understand the real purpose of this thread.
I have read books , articles ,but didn't undrstand clearly what EventQueue thread is responsible for. I have seen a lot of examples, sometimes this is used, sometimes not. As I understood this thread is responsible for ALL GUI OPERATIONS, such creating windows, components, calling native functions from OS API and other stuff. So every time I change some part of GUI I should pass this action to queue.
So using queue application has two threads by default main and event dispatching thread. So I all bussines logic should be performed in main thread (or create new thread from main) and all gui operations in EventQueue(for example adding new item to the table, changing text in label updating list). Futhermore I should create instance of main windows (class extends jframe) in EventQueue ?
Am I right ? If not please explain. Thanks everyone in advance.
EventQueue manages a single GUI thread because it must rely on the host platform's GUI resources, which are also single-threaded. You can run non-GUI code on the initial thread, but you must synchronize access to any shared data yourself. SwingWorker, examined here, is a convenient alternative.
It sounds like you've got the gist of it, yes. If your application is essentially "pure GUI" you can just do everything on the EDT (Event Dispatch Thread, which is the thread that runs whatever you pass to EventQueue.invokeLater), but you must create windows on the EDT which means your main() method must use EventQueue.invokeLater at least once.
Because all listeners on GUI objects will be notified on the EDT, you do not need use EventQueue.invokeLater from your handlers, generally.

Is SwingWorker the only way?

I have found that in order to keep Java GUIs (using Swing) responsive the only way is to use the SwingWorker class, as opposed to java.lang.Thread. Is SwingWorker truly the only way when it comes multithreaded GUI based desktop apps? Are there any good alternatives? Rarely can I configure the Thread class to do what I want to do, but SwingWorker usually works, if sometimes in a cumbersome way.
SwingWorker is nothing but a thin convenience API around Thread. Therefore it is definitely possible to use Thread without SwingWorker. The main point is that Swing is not thread-safe and any actions you perform on Swing objects must happen on the Event Dispatch Thread. This is the fundamental obstacle, and SwingWorker tries to help you overcome it a bit more conveniently.
The alternative is a continuation using EventQueue.invokeLater(), but SwingWorker has important advantages:
It synchronizes granular access to data shared between itself and the EDT.
It provides property change support for progress indication.
It implements the Future interface.
See also Worker Threads and SwingWorker for details.
Multithreading in GUI application is difficult to implement since there can be so many actions that trigger actions. A good explanation of why is this a "failed dream" can be found here
Multithreaded toolkits: A failed dream.. For solutions to your problem, read this article on concurrency in swing: Concurrency in Swing
Depending on your duration of the action you can go with SwingUtilities.invokeLater() or make a SwingWorker for tasks that take a long time to complete and run in background.
You must use this classes or else you may be in situations where a thread will block your entire application and may seem unresponsive to the user.
Another option, most suitable for repetitive tasks, is javax.swing.Timer (it can be used for one-shot tasks as well).

Why should I use a separate thread to show a GUI in JAVA

This simple issue confuses me. You can display a JAVA GUI application by setting the frames' setVisible property true. But in almost all the examples I found on internet they use a separate thread to do the same thing.
They do something like this,
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Frame().setvisible(true); //just take the idea of this line
}
});
I found no difference between the two methods. But there must be some special reason, that's why everyone is doing this.
Can someone explain it..thanks!
The main reason for launching your application in this way is that Swing components are not thread-safe so you need to guarantee which thread your GUI will start from: the one called the Event Dispatching Thread (EDT). Without doing this, you can't be sure what thread it will start in, but as noted by several kind commentators, the main thread is guaranteed not to be the EDT.
You should only create, access, or modify UI components from within the EDT. Doing otherwise will result in unexpected behavior (if you're lucky) and/or dirty repaints.
Some resources I suggest you become familiar with:
The Event Dispatch Thread
Painting in AWT and Swing
You could also have a read of Why does my boilerplate Java desktop app JFrame use EventQueue.invokeLater in the main method?
UPDATE
This is the blog I've been trying to find :P
This basically explains why it's important to sync your main with the EDT before getting started, it also describes some of the details about why.
It also describes why many developers make this fundamental mistake when starting their applications (basically, we were told we could, but we never were really allowed to...bad us)
Because every modification you do on the GUI should be done on the event dispatching thread. This is how AWT and SWING are meant to work.
This because the redraw is executed on a single thread, by using invokeLater you let that thread manage it without having potential issued by the lack of thread safety of Swing. Using that syntax you delegate that instructions to be executed on the appopriate thread, which is the one that manages the GUI elements.
Swing is not thread-safe and all components needs to be initialized in the EDT. This will prevent issues such as deadlocking.
The Swing classes are not thread-safe; they get their thread correctness solely from the fact that all actions on them are executed on the same thread (the Event Dispatch Thread, or EDT). So any time you interact with a Swing object, it must be on the EDT -- and SwingUtilities.invokeLater is a good way to do that.
Without that call, if you just called setVisible(true) from any ol' thread, you wouldn't have any thread safety and the Frame might not even see the actions of that method. Worse yet, the Frame could see only some of the actions, breaking internal assumptions and invariants and causing odd behavior, crashes or deadlocks.
Pretty much any operation that invokes Swing methods must be run on the Swing Event Dispatch thread. invokeLater() is the way to ensure that this invariant holds.
Read more about this here.
Also note that the same is true about most other GUI toolkits, such as forms in .NET, MFC and others.
Java gui framework is designed as a single thread to enforce thread safety: this technique is called thread confinement. Any gui operation e.g. components creation, model creation, event sent, etc must therefore execute in the Event Dispatch Thread (EDT).
The way you describe is one way to queue the operation in the EDT.

Java Event-Dispatching Thread explanation

I've recently started learning and exploring the basics of GUI programming in Java.
Having been programming for a while I have only done backend work or work and as a result the closest I've gotten to user interfaces is the command console (embarrassing I know).
I'm using Swing and as far as I can gather that means by extension I am also using AWT.
My question is based on this piece of code:
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new frame.setVisible(true);
}
} );
I have been researching this for a while as I wanted to fully understand this strange piece of code and have come across the term 'Event-Dispatching Thread' multiple times. Correct me if I'm wrong but as I understand it; it has to do with using multiple threads and how Java Swing interprets those threads. I gather as well that the above code is used to make sure all the threads are 'safe' before it creates the window, hence the invokeLater?
I have read that:
"You can only call methods that operate on the frame from the Event-Dispatching Thread"
and that only under certain circumstances can you call methods that operate on the frame from the main method.
Can somebody please clarify to me what exactly the Event-Dispatching Thread is?
How it relates to multiple threads of execution and how those threads are not safe to be called from the main method? Also why do we need this invokeLater?
Can we not just create the window as any other object?
I've hit a bit of a road block in my research as I'm not grasping these relations and ideas.
A side note is that I like to base my knowledge on in-depth understanding as I believe this leads to the best overall outcome and as a result the best programs. If I understand in-depth how something works then you can use the tips and tweaks effectively rather than just parroting them back in to code, so please don't be afraid to give me some extra in-depth explanations and broaden my knowledge.
Thank you.
The event dispatch thread is a special thread that is managed by AWT. Basically, it is a thread that runs in an infinite loop, processing events.
The java.awt.EventQueue.invokeLater and javax.swing.SwingUtilities.invokeLater methods are a way to provide code that will run on the event queue. Writing a UI framework that is safe in a multithreading environment is very difficult so the AWT authors decided that they would only allow operations on GUI objects to occur on a single special thread. All event handlers will execute on this thread and all code that modifies the GUI should also operate on this thread.
Now AWT does not usually check that you are not issuing GUI commands from another thread (The WPF framework for C# does do this), meaning it's possible to write a lot of code and be pretty much agnostic to this and not run into any problems. But this can lead to undefined behavior, so the best thing to do, is to always ensure that GUI code runs on the event dispatch thread. invokeLater provides a mechanism to do this.
A classic example is that you need to run a long running operation like downloading a file. So you launch a thread to perform this action then, when it is completed, you use invokeLater to update the UI. If you didn't use invokeLater and instead you just updated the UI directly, you might have a race condition and undefined behavior could occur.
Wikipedia has more information
Also, if you are curious why the AWT authors don't just make the toolkit multithreaded, here is a good article.
EventDispatchThread (EDT) is special thread reserved only for Swing GUI and *Swing's related events e.g. create/change/update Swing JComponents, more for asked questions here and here
all output to the GUI from BackGround Tasks, Runnable#Thread must be wrapped into invokeLater(), from synchronized Objects into invokeAndWait();

Java: Swing Libraries & Thread Safety

I've often heard criticism of the lack of thread safety in the Swing libraries. Yet, I am not sure as to what I would be doing in my own code with could cause issues:
In what situations does the fact Swing is not thread safe come into play ?
What should I actively avoid doing ?
Never do long running tasks in response to a button, event, etc as these are on the event thread. If you block the event thread, the ENTIRE GUI will be completely unresponsive resulting in REALLY pissed off users. This is why Swing seems slow and crusty.
Use Threads, Executors, and SwingWorker to run tasks NOT ON THE EDT ( event dispatch thread).
Do not update or create widgets outside of the EDT. Just about the only call you can do outside of the EDT is Component.repaint(). Use SwingUtilitis.invokeLater to ensure certain code executes on the EDT.
Use EDT Debug Techniques and a smart look and feel (like Substance, which checks for EDT violation)
If you follow these rules, Swing can make some very attractive and RESPONSIVE GUIs
An example of some REALLY awesome Swing UI work: Palantir Technologies. Note: I DO NOT work for them, just an example of awesome swing. Shame no public demo... Their blog is good too, sparse, but good
This is one of those questions that makes me glad I purchased Robinson & Vorobiev's book on Swing.
Anything that accesses the state of a java.awt.Component should be run inside the EDT, with three exceptions: anything specifically documented as thread-safe, such as repaint(), revalidate(), and invalidate(); any Component in a UI that has not yet been realized; and any Component in an Applet before that Applet's start() has been called.
Methods specially made thread-safe are so uncommon that it's often sufficient to simply remember the ones that are; you can also usually get away with assuming there are no such methods (it's perfectly safe to wrap a repaint call in a SwingWorker, for example).
Realized means that the Component is either a top-level container (like JFrame) on which any of setVisible(true), show(), or pack() has been called, or it has been added to a realized Component. This means it's perfectly fine to build your UI in the main() method, as many tutorial examples do, since they don't call setVisible(true) on the top-level container until every Component has been added to it, fonts and borders configured, etc.
For similar reasons, it's perfectly safe to build your applet UI in its init() method, and then call start() after it's all built.
Wrapping subsequent Component changes in Runnables to send to invokeLater() becomes easy to get right after doing it only a few times. The one thing I find annoying is reading the state of a Component (say, someTextField.getText()) from another thread. Technically, this has to be wrapped in invokeLater(), too; in practice, it can make the code ugly fast, and I often don't bother, or I'm careful to grab that information at initial event handling time (typically the right time to do it in most cases anyway).
It's not just that Swing is not thread-safe (not much is), but it's thread-hostile. If you start doing Swing stuff on a single thread (other than the EDT), then when in cases where Swing switches to the EDT (not documented) there may well be thread-safety issues. Even Swing text which aims to be thread-safe, isn't usefully thread-safe (for instance, to append to a document you first need to find the length, which might change before the insert).
So, do all Swing manipulations on the EDT. Note the EDT is not the thread the main is called on, so start your (simple) Swing applications like this boilerplate:
class MyApp {
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() { public void run() {
runEDT();
}});
}
private static void runEDT() {
assert java.awt.EventQueue.isDispatchThread();
...
An alternative to using intelligent skins like substance is to create the following utility method:
public final static void checkOnEventDispatchThread() {
if (!SwingUtilities.isEventDispatchThread()) {
throw new RuntimeException("This method can only be run on the EDT");
}
}
Call it in every method you write that is required to be on the event dispatch thread. An advantage of this would be to disable and enable system wide checks very quickly, eg possibly removing this in production.
Note intelligent skins can of course provide additional coverage as well as just this.
Actively avoid doing any Swing work at all except on the event dispatching thread. Swing was written to be easy to extend and Sun decided a single-threaded model was better for this.
I have had no issues whilst following my advice above. There are some circumstances where you can 'swing' from other threads but I've never found the need.
If you're using Java 6 then SwingWorker is definately the easiest way to deal with this.
Basically you want to make sure that anything that changes a UI is performed on the EventDispatchThread.
This can be found by using the SwingUtilities.isEventDispatchThread() method to tell you if you are in it (generally not a good idea - you should know what thread is active).
If you aren't on the EDT then you use SwingUtilities.invokeLater() and SwingUtilities.invokeAndWait() to invoke a Runnable on the EDT.
If you update UI's not on the EDT you get some incredibly strange behaviour. Personally I don't consider this a flaw of Swing, you get some nice efficiency by not having to synchronize all of the threads to provide a UI update - you just need to remember that caveat.
The phrase 'thread-unsafe' sounds like there is something inherently bad (you know... 'safe' - good; 'unsafe' - bad). The reality is that thread safety comes at a cost - threadsafe objects are often way more complex to implement (and Swing is complex enough even as it is.)
Also, thread-safety is achieved either using locking (slow) or compare-and-swap (complex) strategies. Given that the GUI interfaces with humans, which tend to be unpredictable and difficult to synchronize, many toolkits have decided to channel all events through a single event pump. This is true for Windows, Swing, SWT, GTK and probably others. Actually I don't know a single GUI toolkit which is truly thread-safe (meaning that you can manipulate its objects' internal state from any thread).
What is usually done instead is that the GUIs provide a way to cope with the thread-unsafety. As others noted, Swing has always provided the somewhat simplistic SwingUtilities.invokeLater(). Java 6 includes the excellent SwingWorker (available for previous versions from Swinglabs.org). There are also third party libraries like Foxtrot for managing threads in Swing context.
The notoriety of Swing is because the designers have taken light handed approach of assuming that the developer will do the right thing and not stall the EDT or modify components from outside the EDT. They have stated their threading policy loud and clear and it's up to the developers to follow it.
It's trivial to make each swing API to post a job to the EDT for each property-set, invalidate, etc., which would make it threadsafe, but at the cost of massive slowdowns. You can even do it yourself using AOP. For comparison, SWT throws exceptions when a component is accessed from a wrong thread.
Here's a pattern for makng swing thread-freindly.
Sublass Action (MyAction) and make it's doAction threaded.
Make the constructor take a String NAME.
Give it an abstract actionImpl() method.
Let it look like.. (pseudocode warning!)
doAction(){
new Thread(){
public void run(){
//kick off thread to do actionImpl().
actionImpl();
MyAction.this.interrupt();
}.start(); // use a worker pool if you care about garbage.
try {
sleep(300);
Go to a busy cursor
sleep(600);
Show a busy dialog(Name) // name comes in handy here
} catch( interrupted exception){
show normal cursor
}
You can record the time taken for the task, and next time, your dialog can show a decent estimate.
If you want to be really nice, do the sleeping in another worker thread too.
Note that not even the model interfaces are thread safe. The size and the content are queried with separate get methods and so there is no way of synchronizing those.
Updating the state of the model from another thread allows for it to at least paint a situation where size is still bigger (table row is still in place), but the content is no longer there.
Updating state of the model always in EDT avoids these.
invokeLater() and invokeAndWait() really MUST be used when you are doing any interaction with GUI components from any thread that is NOT the EDT.
It may work during development, but like most concurrent bugs, you'll start to see weird exceptions come up that seem completely unrelated, and occur non-deterministly - usually spotted AFTER you've shipped by real users. Not good.
Also, you've got no confidence that your app will continue to work on future CPUs with more and more cores - which are more prone to encountering weird threading issues due to them being truely concurrent rather than just simulated by the OS.
Yes, it gets ugly wrapping every method call back into the EDT in a Runnable instance, but that's Java for you. Until we get closures, you just have to live with it.
For more details about threading, Taming Java Threads by Allen Holub is an older book but a great read.
Holub, really promotes responsive UI and details examples and how to alleviate problems.
http://www.amazon.com/Taming-Java-Threads-Allen-Holub/dp/1893115100
http://www.holub.com/software/taming.java.threads.html
Love the "If i was king" section in the end there.

Categories

Resources