I'm trying to flash a Java graphic object by changing the color and calling the repaint() method. The color is only updating with the final change color call. Here is my code:
public void start() {
try {
Color origColor = node.getColor();
for (int i=0; i<noOfFlashes; i++) {
Manager.gui.getDrawGraph().changeNodeColor(node, Color.WHITE);
Thread.sleep(500);
Manager.gui.getDrawGraph().changeNodeColor(node, origColor);
Thread.sleep(500);
}
Manager.gui.getDrawGraph().changeNodeColor(node, Graph.VISITED_NODE);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
and the change node color method is:
public void changeNodeColor(Node node, Color c) {
node.setColor(c);
repaint();
}
The change node color is in the same class as the paint component.
Any help would be much appreciated.
You need to use separate thread to manage your GUI event.
You can do this, using a SwingWorker, as suggested by Amine, or implement the Runnable interface, or extend the Thread class, developing the run() method, that is the task of your thread.
You can read this old question of SO : How do I use SwingWorker in Java?
A tutorial for SwingWorker : http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html
A tutorial to make a Thread : http://docs.oracle.com/javase/tutorial/essential/concurrency/
The color is only updating with the final change color call.
If you don't use a separate thread, your gui will freezing until the method is completely executed, and you won't see the color change separated by Thread.sleep(500);.
UPDATE
In this link, in the paragraph Why does a Swing GUI freeze or lock up?, you can understand why a Java Swing GUI freezes, with the use of a single thread.
Check also this official link, in the paragraph Creating Threads, and this page, that returns:
Swing's single-thread rule says that Swing components can only be
accessed by a single thread. This rule applies to both gets and sets,
and the single thread is known as the event-dispatch thread.
The single-thread rule is a good match for UI components because they
tend to be used in a single-threaded way anyway, with most actions
being initiated by the user. Furthermore, building thread safe
components is difficult and tedious: it's a good thing not to be doing
if it can be avoided. But for all its benefits, the single-thread rule
has far-reaching implications.
Swing components will generally not comply with the single-thread rule
unless all their events are sent and received on the event-dispatch
thread. For example, property-change events should be sent on the
event-dispatch thread, and model-change events should be received on
the event-dispatch thread.
For model-based components such as JTable and JTree, the single-thread
rule implies that the model itself can only be accessed by the
event-dispatch thread. For this reason, the model's methods must
execute quickly and should never block, or the entire user interface
will be unresponsive.
I think that the sentences above are very useful to understand better the Swing package.
I report the suggestion of trashgod.
You can use the Timer class, from the javax.swing.Timer package. That is also a good alternative.
In this question, trashgod reports some examples of Timer.
Check here for a tutorial about Timer.
Based on what i understand from your code, I will probably recommend the use of SwingWorker.
I know you do not have any cost expensive code but you using SwingWorker, you will be able to update your GUI more easily.
I am not sure which framework you're using here... but you may need a repaint() just before the Thread.sleep(). Is there a Manager.gui.repaint() perhaps? (Sorry, complete guesswork here...)
Related
I know about the Swing components and that they should be called from the event dispatch thread but as of now i developed test applications which are event thread centric, that means the UI does the program flow definition by calling listeners on event invocation. But i have read that other threads should not communicate with the UI because it is not synchronized.
Most books just teach how to use individual components and not how to
to use them in a real world application context.
How does one update status of a completed or in process thread status to a swing component.
UPDATE: If we configure the listener to invoke the job in an ExecutorService how does the working thread update the UI component in a safe manner.
the safest way is to use
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
});
inside run method you can manipulate Swing components
The basic answer is calling repaint.
The idea behind AWT/Swing is that at any moment, a component could be shown, resized, moved etc (either by the code or thru user interaction) prompting the need for repainting. So when you do your updating, you should update the model that the rendering is going to be based on... sometimes necessitating doing this on the EDT for consistency's sake, and then use repaint to show the changes to the model
You could...
Use SwingUtilities.invokeLater to schedule an a callback to be executed on the EDT at some time in the future.
The problem with this is synchronising data between the threads, as the data that the update might need might no longer be the same it was when the call was made
You could...
Use a SwingWorker. This provides a means to synchronise data changes between the background thread and the EDT as the data is passed through to the process method, so it can act on "relevant"/"related" data at the time it is called, this decreases (some) of the need for synchronising access to the data that the UI might need
UPDATE: If we configure the listener to invoke the job in an ExecutorService how does the working thread update the UI component in a safe manner.
SwingWorker itself is compatiable with ExecutorService, you can add instances of SwingWorker to it, neat trick ;)
For example
The EDT's only job is to call your handlers. The only way in which you can "communicate" with it is by registering handlers for it to call. (NOTE: The invokeLater(...) method is just a way to register a handler that the EDT will call immediately.)
i have read that other threads should not communicate with the UI because...
Don't think about it in terms of "communicating." Think about it in terms of threads operating on shared objects. What you ought to be saying is, "Other threads should never operate on Swing objects."
Other threads can operate on your objects, and then your objects can show their updated state on screen when the EDT calls their paint(g) methods.
I'm attempting to add a fancy InfiniteProgressPanel as a GlassPane for my big Swing program. However, it does not appear. It looks similar to this:
...
InfiniteProgressPanel glassPane = new InfiniteProgressPanel();
setGlassPane(glassPane);
...
glassPane.start();
doSomeStuff();
glassPane.stop();
...
I believe it is running in the same thread as the long process it is meant to cover up. I'll admit, I don't know nearly enough about threads, and I should probably figure out how to run that InfiniteProgressPanel GlassPane in a separate thread, and the long process in its own thread, too.
Be sure to:
Run all long running code in a background thread. This is a must.
Sounds great! How do I do so? Encapsulate all of the long-running code inside of an .invokeLater method? And should that be SwingUtilities.invokeLater or EventQueue.invokeLater? And what's the difference, anyway?
No, by using SwingUtilities.invokeLater(new MyRunnable) you're doing exactly the opposite -- you're guaranteeing that the long-running code will be called on the Swing event thread -- the exact opposite of what you want. Instead use a SwingWorker's doInBackground() method to run the long-running code. Regarding your second point, there's no difference whatsoever between SwingUtilities.invokeLater and EventQueue.invokeLater.
Make most all Swing calls on the Swing event thread, also a must.
Fantastic! Again, how do I do so? Same thing as above?
By using SwingUtilities.invokeLater(new MyRunnable) as noted above, or if you're using a SwingWorker then use its publish/process method pair as the SwingWorker tutorial will show you.
Call setVisible(true) on your glass pane since per the JRootPane API, all glasspanes are by default invisible.
Romain Guy's InfiniteProgressPanel doesn't seem to need a setVisible(true). It appears when the InfiniteProgressPanel.start() method is called.
I am not familiar with this, do you have a link?
Threads are different processes in the same program, per se.
In java, there are many different thread types, and the one you need for this job is SwingWorker.
The definition/use of this, from Oracle's docs, is:
When a Swing program needs to execute a long-running task, it usually uses one of the worker threads, also known as the background threads. Each task running on a worker thread is represented by an instance of javax.swing.SwingWorker. SwingWorker itself is an abstract class; you must define a subclass in order to create a SwingWorker object; anonymous inner classes are often useful for creating very simple SwingWorker objects.
As you can see, this is what you need; a background thread.
final InfiniteProgressPanel glassPane;
...
class GlassPaneHandler extends SwingWorker<String, Object> {
#Override
public String doInBackground() {
glassPane.start();
return setUpPaneAndStuff();
}
#Override
protected void done() {
try {
glassPane.stop();
} catch (Exception e) { } //ignore
}
private void setUpPaneAndStuff() {
//code
}
}
...
(new GlassPaneHandler()).execute(); //place this in your code where you want to initiate the pane
for more see:http://docs.oracle.com/javase/8/docs/api/javax/swing/SwingWorker.html
When you are updating a swing UI you need to do it in Swing's Event Thread. This includes creation of components or any sort of progress updates. You can do this via the SwingUtilities.invokeLater(Runnable) method.
Therefore, you should create the glasspane and show it via the invokeLater if in a background thread. Any progress updates to the glasspane from your long running process thread should be done via the invokeLater.
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).
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.
For what I can read, it is used to dispatch a new thread in a swing app to perform some "background" work, but what's the benefit from using this rather than a "normal" thread?
Is not the same using a new Thread and when it finish invoke some GUI method using SwingUtilities.invokeLater?...
What am I missing here?
http://en.wikipedia.org/wiki/SwingWorker
http://java.sun.com/products/jfc/tsc/articles/threads/threads2.html
Yes, you can accomplish what a SwingWorker does with vanilla threads + invokeLater. SwingWorker provides a predictable, integrated way to accomplish tasks on a background thread and report result on the EDT. SwingWorker additionally adds support for intermediate results. Again, you can do all of this yourself but sometimes it's easy to use the integrated and predictable solution especially when it comes to concurrency.
A code example:
import org.jdesktop.swingx.util.SwingWorker; // This one is from swingx
// another one is built in
// since JDK 1.6 AFAIK?
public class SwingWorkerTest {
public static void main( String[] args ) {
/**
* First method
*/
new Thread() {
public void run() {
/** Do work that would freeze GUI here */
final Object result = new Object();
java.awt.EventQueue.invokeLater( new Runnable() {
public void run() {
/** Update GUI here */
}
} );
}
}.start();
/**
* Second method
*/
new SwingWorker< Object , Object >() {
protected Object doInBackground() throws Exception {
/** Do work that would freeze GUI here */
return null;
}
protected void done() {
try {
Object result = get();
/** Update GUI here */
}
catch ( Exception ex ) {
ex.printStackTrace();
if ( ex instanceof java.lang.InterruptedException )
return;
}
}
}.execute();
}
}
The choice always depends on personal preference and use case.
The second method has an advantage when refactoring. You can more easily convert the anonymous class to an inner class when the method it's used in is too large.
My personal preference goes to the second, for we have built a framework where SwingWorkers can be added and are executed one after the other...
SwingWorker is an implementation of a common pattern (in .Net i read there is GuiWorker BackgroundWorker for this), where you have to do some work in a GUI program, but keep the GUI responsive. The problem is that often GUI libraries are not multi thread safe, so the common way to implement such workers is to use the message loop of the library to transfer messages into the event loop of the application.
These classes allow you to easily update your GUI. Usually, they have a update(int status) method that is called by the thread, dispatched by the class, and handled by the GUI, while the thread continues its work.
Using normal threads, you would need to code your own events or some other messaging mechanism for this task, which can be a pain if you need this functionality often. Using invokeLater in Java for example, you would intermix the code for updating the gui into the code for doing the work. The SwingWorker allows you to keep things separate.
to answer your question, you are not missing anything. this class is just a convenient utility for wrapping up the functionality you discribed (start another thread to do the background work and then invoking some final action on the EDT with the results).
When working with Swing, it is important to know that the main swing processing (ie. rendering) happens on a single thread (which is not your main thread). This is often called the Swing or awt event thread. Those familiar with the JDK pre 1.6 will remember the "grey rectangle" bug if you spent too much time in an event dispatcher for a swing component. What does this mean. In any swing application you will have 2 threads running that you will now have to deal with. Normally if all your operations within an event dispatcher (the code that gets fired say when a button is clicked) is short (ie. changing the state of a siwng button) you can just run this inside of the event dispatcher. If your application is going to call a web service or a database, or you application state is driven by external events (ie. jms) or you want to just make your UI more interactive (ie. build a list of items and be able to do something else) you should use a thread other than the awt event thread (the main swing one). So in these cases you spawn a new thread and do what you have to, and when the results finally come back, you then somehow have to create an event that can be executed by the awt/swing dispatcher. SwingWorker is a great little design pattern that allows you do to do this (the other way is SwingUtilities). It is particularly useful for doing fetch data from external sources or say long calculations (rendering a graphics scene). It helps automate the dispatch and subsequent re-integration of the results from an external thread (other than the awt thread). For async events (ie. an event from JMS needs to update a result, use SwingUtilities).
SwingWorker makes trivial example code much more concise. However it creates a ball of mud. Communications to and from the GUI and executed logic are all welded together. So, I'd not like to see it used in real production code.
SwingWorker is far easier than mucking with your own threads because it gives you two things that are painful to manually, thread coordination between the UI and the background process and doing loops effective, background work that keeps working and sending updates back to the UI incrementally, like process a large amount of data, or loading a large list. The disadvantage (or advantage) depends on how you look at it, is that it hides the underlying implementation, so future version may have different behavior, performance, etc, which may be undesirable. I've found it quite useful as the glue between a UI event and my own command code, the SwingWorker maintains the link to the UI and my code pumps data.