I need to make a thread that start at swing button push and wait for input from rs232, process it and return String to my variable. The question is how to do that?
it should be something like that:
String myOutputString = waitForInputThread();
Or if its possible in swing panel make something like listener that do something if this waitForInputThread send interrupt (for example, if get rs232 input do update a list of items in JTable).
Could you give me some clues, tutorials, examples etc ?
To avoid blocking the Event Dispatch Thread (which is the thread that updates the GUI), start a new thread to interact with the RS232. The SwingWorker class is one option, but you can just as easily use a normal thread.1 Blocking the EDT causes your GUI to freeze, so it must never be used for lengthy tasks.
Once your result is computed, update the GUI using SwingUtilities.invokeLater(). This ensures the GUI change occurs on the EDT.
1 I tend to find normal threads executed via an ExecutorService are better for unit testing (as you can write an ExecutorService that immediately executes the Runnable, avoiding any nasty thread issues with JUnit).
Related
With Java Swing, is it possible to pause the current thread Runnable and give room to the Event Dispatching Thread to update the gui?
I know it is possible with multi-threading (SwingWorker class) but I was wondering if there's an easier way to achieve this for single threaded programs (aka: all my code is in the gui's Run()).
E.g. Matlab has the very convenient drawnow; method
If not: how can I split the updating task to a second thread without having to rewrite anything? Would that be the Updating the gui from a running thread from this link?
The short answer is no. If you pause the current thread (which according to you is the EDT) then you pause the EDT...
You can make requests that the UI be updated using methods like repaint, but this also assumes you are not blocking the EDT with things like loops and pauses, as the EDT will need time to process these requests.
And no, I wouldn't follow the link's advice, as it violates the single thread of Swing by updating the components outside of the of EDT
Depending on your needs you would either need to use a javax.swing.Timer or SwingWorker. Yes, you can use a Thread, you become responsible for ensuring that all updates to the UI are synced back to the EDT, which the other two suggest provide mechanisms for.
Take a look at Concurrency in Swing for more details
this is a beginner question:
I am working on a small chat program that use TCP to deliver messages, and I have a simple GUI to display it, I have finished the program, but the EDT has confused me a lot...
does EDT behave like it "extends Thread"? I imagine it is a single thread since I will need worker thread to process the heavy logic, but apparently I can not do Thread.sleep/yield (I have a while loop that constantly reading message from the outputstream and append to the jTextArea, running in main Thread, I tried to terminate the while loop by set a false flag and then yield to main Thread, did not work.)
I am not so sure about how listener works, if I have to write it...I will probably start a thread for each listener, as soon as I hear something I will process it...but this is definitely wrong because it will make EDT a multithread ( a lot of ears ) but singlethread during the process ( only 1 brain )
This must be me lacking knowledge!! because in my head I just can not figure out how to fire an event... you pressed a button and java suddenly knows? I must missed something.
My first time post a question, hope it is clear
The Event Dispatching Thread is a Thread like any other Thread in Java.
It is responsible for dispatching all events and repaint requests (and few other things, like running synchronized Runnable). Any action you take that blocks the EDT will stop it from processing these events, making it look like your application has hung ... because basically it has.
All interactions with any UI component MUST be executed within the context of the EDT. That means you should never try and create or update any UI component from any Thread other then the EDT.
If you need to do any actions that are blocking or time consuming, you should use another thread. SwingWorker is an excellent place to start.
Adding listeners to component will not create more threads. The EDT will post event notifications back to the listeners (this is an incredibly shortened explanation, but the concept is sound), this is one of the reasons why you should never block the EDT.
How events are raised depends on the component. Mouse and keyboard events for example, will be posted to the Event Queue by a native portion of code dependent on the OS/implementation (as I understand it, coming from the ToolKit, but I could be wrong).
actionPerformed events raised by JButtons may be executed directly against the listener (not dispatched via the Event Queue), but within the EDT. This are raised by any number of events, but typically caused by mouse clicks and special key events. The JButton is notified of these because it registers itself with the Event Queue.
While getting an understanding of the workings is a good goal, you need to ask yourself, does it matter (in the short term)? Do you know how electricity gets from the light switch to the light? Or do you only care that it does?
Understand the rules required to use it (don't stick sharp objects into the power points) and let the understanding come as you become more confident.
It seems I miss a certain point in Java and Swing. The issue is as follows:
I have a swing GUI with a Start / Stop button (And some more)
It starts the function (What is set up as a thread in this case), Thread starts, it works, Swing GUI is fully operational and does all the other things it is made for, e.g. modifying parameters for the worker thread.
Of course, sending an interrupt to ask the thread to stop on users request is in and functions. So far so good.
But I did not found a way that Swing GUI notices the thread stopped on its own:
If I ignore it, it confuses the user.
I of course put a loop in, where Swing GUI regularly asks if Thread.isAlive (And sleeps some time to ask again), but this loop completely blocks Swing GUI.
Ideally, I would like to get a notification or an event that the thread has stopped.
Just like all the other events, Swing processes:-) .
What is the proper way to set it up?
Have a look at the SwingWorker. It is designed to perform tasks on the background as the result of a Swing event such a button press. It has hooks to listen for when the task finishes.
use a boolean flag 'done' private field. initialize done=false; when your thread run() method is complete set done=true inside thread run() method.
monitoring the value of the flag 'done' will tell you when your thread has finished.
I know what "thread" means and if I understand the event dispatching thread (EDT) as
"just a thread", it explains a lot but, apparently, it does not explain everything.
I do not understand what is special about this thread. For example I do not understand why we should start a GUI in a the EDT? Why the "main" thread is bed for GUI? Well, if we just do not want to occupy the main thread why we cannot start GUI just in "another thread" why it should be some "special" thread called EDT?
Then I do not understand why we cannot start the EDT like any other thread? Why we should use some special tool (called invokeLater). And why GUI, unlike any other thread, does not start immediately. We should wait until it is ready to accept our job. Is it because EDT can, potentially execute several task simultaneously?
If you decide to answer this question, could you pleas use a really simple terminology because otherwise, I am afraid, I will not be able to understand the answer.
ADDED:
I always thought that we have one "task" per thread. So, in every thread we execute a predefined sequence of commands. But it seems to me that in the event dispatching thread we can have sever task. Well, they are not executed simultaneously (thread switches between different task but there are still several task in one thread). Is it right? For example there is one thread in the EDT which display the main window, and then additionally to that we sent to the EDT another task which should update one of the window components and EDT will execute this new task whenever it is ready. Is EDT differ from other threads in this way?
The event dispatching thread is the thread that handles all GUI events and manages your Swing GUI. It is started somewhere in the Swing code if you have any GUI in your program. The reason it is done behind the scenes is because of simplicity - you do not have to bother with starting and managing an extra thread by yourself.
Regarding the fact that you have to update your GUI with invokeLater() it is because of concurrency issues. The GUI can be modified only from one thread because Swing is not thread safe(it is worth to note that most of toolkits are not thread safe, there is a nice article that gives some ideas why). This is why you have to submit all GUI updates to run on EDT.
You can read more on concurrency in Swing and event dispatching thread in Sun tutorial on concurrency in Swing. Also, if you would like to see how this could be done in a different way you might like to check out SWT toolkit. In SWT you have to manage EDT by yourself.
I always thought that we have one
"task" per thread. So, in every thread
we execute a predefined sequence of
commands. But it seems to me that in
the event dispatching thread we can
have sever task. Well, they are not
executed simultaneously (thread
switches between different task but
there are still several task in one
thread). Is it right? For example
there is one thread in the EDT which
display the main window, and then
additionally to that we sent to the
EDT another task which should update
one of the window components and EDT
will execute this new task whenever it
is ready. Is EDT differ from other
threads in this way?
No, the EDT is not fundamentally different from other threads. And "task" is not a good word to use, because it could be confused with OS-level processes (which are also often called task). Better use Runnable, the interface used to give code to the EDT to execute via invokeLater().
The EDT is basically connected to a queue of things it has to do. When the user clicks a button on the GUI, a Runnable that notifies all listeners attached to the button goes into the queue. When a window is resized, a Runnable doing revalidate&repaint goes into the queue. And when you use invokeLater(), your Runnable goes into the queue.
The EDT simply runs an endless loop that says "take a Runnable from the queue (and if it's empty sleep until you're notified that it's not) and execute it.
Thus, it executes all those little Runnable pieces of code one after another, so that each of them basically has the GUI all to itself while it runs, and doesn't have to worry about synchronizing anything. When you manipulate the GUI from another thread, this assumption is broken, and you can end up with the GUI in a corrupted state.
What is the EDT?
It's a hacky workaround around the great many concurrency issues that the Swing API has ;)
Seriously, a lot of Swing components are not "thread safe" (some famous programmers went as far as calling Swing "thread hostile"). By having a unique thread where all updates are made to this thread-hostile components you're dodging a lot of potential concurrency issues. In addition to that, you're also guaranteed that it shall run the Runnable that you pass through it using invokeLater in a sequential order.
Note that it's not just that you're dodging the concurrency issue: you must respect Sun's guidelines regarding what must and what must not be done on the EDT or you'll have serious problems in your application.
Another benefit is that some Swing components tend to throw unwanted exceptions and when this happen they're automagically dealt with and won't crash the EDT (AFAIK if you really manage to kill the EDT it is automagically restarted).
In other words: you don't have to deal with all the broken Swing components and the exceptions they throw yourself: the EDT is taking care of that (just take a look at the countless Swing bugs throwing exceptions in Sun's bug parade, it's fascinating... And yet most apps keep working normally).
Also, by doing only what's mandatory in the EDT allows the GUI of your app to stay "responsive" even tough there may be tasks running in the background.
The important thing to remember is that Swing classes are not thread-safe. This means that you always should call Swing methods from the same thread, or you risk getting weird or undefined behavior.
So the solution: only call Swing methods from a single thread. This is the EDT thread - it's not special in any way other than that it is the thread designated to call swing methods from.
Now you may ask why are Swing methods not thread safe? After several unsuccessful attempts, GUI toolkit designers discovered that it's inherently impossible to design a thread-safe GUI toolkit. Too often events are passed in opposite directions (input events from bottom to top, application events from top to bottom) which always leads to deadlocks. So that's just the way it is.
I am writing an application in java (1.6) using swing. I currently have a JXBusyLabel on a JXLayer over the content area of my program acting as a busy indicator. I want to provide a way to allow others working with me to create a task that pops up the busy label while it's executing. The catch is, the task must be cancel-able. What is the best way to expose the functionality I desire?
Some ideas I've come up with:
Raw access to setBusy()
This is obviously the easiest for me but requires users know and understand swing threading issues.
public <T> Future<T> execute(Callable<T>)
Wraps the callable in a FutureValue that is run() on a separate thread and returns that FutureValue. The question then becomes, how to keep track of all FutureValue's generated and how to ensure that they can be cancelled. (e.g. cancel(true) always cancels)
I have never used the concurrency package in Java before and it didn't exist back when I 'learned' Java. So I am open to completely new and different ways of implementing this functionality.
Edit:
Clarification of my question. I know about SwingWorker. I've just never used it. What I want to know is this:
Given a Callable (Java version of a closure?) How can I:
Return the value of call() to the user w/o blocking (I think I need to use a Future for this)
Tell the JXLayer to lock (starts painter), execute the supplied callable, and then unlock the JXLayer (stops painter)
Ensure that, no matter what thread calls my busyExec() function, the GUI remains responsive and the background task completes. (NOTE: If I return some sort of Future object and they call get() on the event thread, it can/will block and that is ok)
I guess my main stumbling point is how to implement #2. Should I have busyExec() spin off a new thread that blocks until no background tasks are running? Should I try for some sort of queue. Is there an object that will do this all for me already?
The SwingWorker (of Java 6) implements Future so it seems like it has the ability to cancel tasks via the cancel method.
More information on SwingWorker from The Java Tutorials:
Lesson: Concurrency in Swing
Worker Threads and SwingWorker
Canceling Background Tasks
Okay. For anyone interested here is what I am currently using to implement my request.
I have a method that will take a Callable<T>. It then creates a FutureTask<T> this will be returned to the caller as a this as a Future<T>. The JXBusyLabel and JXLayer are told to start painting and to lock the ui. The FutureValue and Thread (see below) is enqueued in a special list. A Runnable is created that: calls run() on the FutureTask, removes the FutureValue (and thread) from the list, and if the list is empty, unlocks the JXLayer and stops the JXBusyLabel. This Runnable is launched in a new Thread with normal priority.
When the user hits the cancel button. The list is iterated over and the FutureTasks are all canceled and removed from the list if they could be cancelled. First try cancel(false), then cancel(true). If both those means fail, the user is prompted with a warning asking them if they want to Thread.stop() the task and explains that this could make the app unstable. If yes, stop() the thread running the task. This might bring the app down. In all cases, the UI is unlocked.
The documentation for other team members states that they must be aware that the task can be killed. They are not to call get() until isDone() is true. They are explicitly told that this will basically force them to block until the task is done or cancelled. So they can't call it from the event dispatch thread.
Other solutions are still welcome