In multi-threaded Swing applications, always use the ''SwingUtilities'' class to perform visual updates (except when working directly in event handlers).
Remember three static methods of that class - invokeLater(Runnable), invokeAndWait(Runnable) and isEventDispatchThread(). First executes the run() method of the parameter asynchronously with the Event Dispatch Thread, the other executes it synchronously, and the third checks if the current Thread is the Event Dispatch Thread.
The first method waits for all pending events to be processed and then processes the visual update, but does not block. The second blocks until all pending events are processed, and the run() method of the parameter returns. Method invokeAndWait() should never be called from the event dispatch thread - it will throw an Exception in that case. If you are unsure about the current thread, use isEventDispatchThread() to check.
If you have a method that must be called on the Swing EventDispatchThread then you can use the following code template (note all the arguments must be declared as final).
public void someMethod(final String msg) { if (!SwingUtilities.isEventDispatchThread()) { SwingUtilities.invokeLater( new Runnable() { public void run() { someMethod(msg); } }); return; } // actual code for this someMethod goes here ..... // will always be run on the swing EventDispatchThread }
See also Swing Threading.