Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pattern for blocking Java Swing user in worker thread

As most Java programmers know, updates to Swing GUIs should only be done on the AWT event dispatching thread and the recommendation is that long-running processes be executed on a "worker" thread, with updates sent to the event dispatching thread using SwingUtilities.invokeAndWait() or SwingUtilities.invokeLater().

How do you stop the user from proceeding with the application while the long-running process is completed? Do you gray out the controls and then have the worker thread reenable them using the SwingUtilities calls mentioned above?

Is there a better alternative pattern?

like image 853
Ralph Avatar asked Mar 24 '11 11:03

Ralph


People also ask

What is SwingWorker thread in Java?

Worker Threads and SwingWorker 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.

What is the use of SwingWorker subclass in Java?

The SwingWorker subclass can define a method, done, which is automatically invoked on the event dispatch thread when the background task is finished. SwingWorker implements java.util.concurrent.Future. This interface allows the background task to provide a return value to the other thread.

Can I use multi-threading techniques in swing?

Join the DZone community and get the full member experience. If you're writing a desktop or Java Web Start program in Java using Swing, you might feel the need to run some stuff in the background by creating your own threads. There's nothing stopping you from using standard multi-threading techniques in Swing, and the usual considerations apply.

How do I communicate between UI and worker threads in swing?

Hopefully you can see from this example how you might use SwingUtilities.invokeLater () in order to communicate between UI and worker threads. You can think of invokeLater as a simple callback to the UI for sending whatever updates you need. SwingWorker<T,V> can be used similarly to invokeLater, but each has its strong points.


2 Answers

I would consider 3 solutions :

  • disable the components of the panel : it's generally what I do. Unfortunately, Swing does not provide a simple way to disable a panel and all its children, but it is easy to do the recursion (see this other SO answer for that). Another problem is that some Swing components look the same when enabled and disabled (JList, for example)
  • hide the panel with a CardLayout : in a panel with a CardLayout, add 2 components. The first is the panel that hosts the components to inactivate, and the second is a panel showing a "loading" or "please wait" message. A simple JLabel in a Gridbaglayout does the trick. Then, you just have to switch from one to another. I use this technique for places where a result of a computation/request is to be displayed.
  • put some kind of component on top of the panel that consumes the mouse events : you can do it yourself with a LayeredPane, or you can use a dedicated utility. JXLayer can do that (I read that JXLayer will be included in Java 7, so this may become the 'standard' solution to this kind of problem).
like image 179
barjak Avatar answered Oct 17 '22 03:10

barjak


There are several ways and the selection of which, mostly depends on the design and layout of your GUI.

  • Use a Progress Bar - Replace the panel or an area that you don't want a user touching with a progress bar. This will prevent you from having to deal with events you don't want yet, while still making it clear to the user that something is happening in the background.
  • Disable buttons and add a Wait Cursor - Use setEnable(false) while work is being done and nd possibly change the cursor to a Wait Cursor. This again makes it clear that an option is not available yet only for a temporary period.
  • Don't respond to events or throw up a GlassPane - This is less user-friend as it makes the application look unresponsive, however it can acceptable in some situations.
like image 38
jzd Avatar answered Oct 17 '22 02:10

jzd