BackgroundWorker

org.jdesktop.swingx
Class BackgroundWorker

java.lang.Object
  extended by org.jdesktop.beans.AbstractBean
      extended by org.jdesktop.swingx.BackgroundWorker

public class BackgroundWorker
extends org.jdesktop.beans.AbstractBean

A JavaBean to perform lengthy GUI-interacting tasks in a dedicated thread.

When writing a multi-threaded application using Swing, there are two constraints to keep in mind: (refer to How to Use Threads for more details):

These constraints mean that a GUI application with time intensive computing needs at least two threads: 1) a thread to perform the lengthy task and 2) the Event Dispatch Thread (EDT) for all GUI-related activities. This involves inter-thread communication which can be tricky to implement.

BackgroundWorker is a non visual JavaBean that simplifies writing these multithreaded tasks from within a GUI Builder environment. It is built upon SwingWorker, and exhibits most of the same API features as SwingWorker.

Workflow

There are two threads involved in the life cycle of a BackgroundWorker (unlike SwingWorker which can operate with three threads):

A single BackgroundWorker instance may be used more than once. You cannot however call execute while the BackgroundWorker is in progress.

You can retrieve and set progress information on the BackgroundWorker at any time. There are two complementary methods for doing so, setProgress(float) and setProgressPercent(int). The first method accepts a float between the range of 0 to 1 while the second method accepts an int between the values of 0 and 100.

You may also specify the exact ExecutorService to use for the background task. This allows you to specify a thread pool, default thread priority, and other such attributes of the background task. See the ExecutorService API for more information.

BackgroundWorker operates on the basis of callbacks. You first register a BackgroundListener with the BackgroundWorker, and implement the relevant methods. For example, you implement the doInBackground method if you have tasks that must be performed on the background thread.

From within the doInBackground method you may call the publish method of your BackgroundWorker to place some data on a queue to be processed on the Event Dispatch Thread. At some point the process event will be fired with this data available within the BackgroundEvent object. In this event handler you may freely modify the GUI.

Sample Usage

The following example illustrates the simplest use case. Some processing is done in the background and when done you update a Swing component.

Say we want to find the "Meaning of Life" and display the result in a JLabel.


   final JLabel label;
   class MeaningOfLifeFinder implements BackgroundListener {
       public void doInBackground(BackgroundEvent evt) {
           String meaningOfLife = findTheMeaningOfLife();
           evt.getWorker().publish(meaningOfLife);
       }

       public void process(BackgroundEvent evt) {
           label.setText("" + evt.getData());
       }

       public void done(BackgroundEvent evt) {}
       public void started(BackgroundEvent evt) {}
   }
 
   (new MeaningOfLifeFinder()).execute();
 


Constructor Summary
BackgroundWorker()
          Creates a new instance of BackgroundWorker
 
Method Summary
 void addBackgroundListener(BackgroundListener listener)
          Adds a BackgroundListener
 void execute()
          Executes the BackgroundWorker, causing it to begin processing.
 BackgroundListener[] getBackgroundListeners()
          Returns an array of all BackgroundListeners registered with this object
protected  java.util.concurrent.ExecutorService getExecutorService()
          Returns the executorService bound property.
 float getProgress()
          Returns the progress bound property.
 int getProgressPercent()
          Returns the progressPercent bound property.
 boolean isDone()
           
 boolean isRunning()
           
 void publish(java.lang.Object... chunks)
          Causes the given "chunks" of data to be published on the Event Dispatch Thread.
 void removeBackgroundListener(BackgroundListener listener)
          Removes the given BackgroundListener such that it will no longer be notified of background events.
protected  void setExecutorService(java.util.concurrent.ExecutorService svc)
          Sets the executorService bound property.
 void setProgress(float progress)
          Set the progress of this worker based on a value between 0 and 1 where 0 represents 0% and 1 represents 100%.
 void setProgressPercent(int percent)
          Set the progress of this worker based on a value between 0 and 100 where 0 represents 0% and 100 represents 100%.
 
Methods inherited from class org.jdesktop.beans.AbstractBean
addPropertyChangeListener, addPropertyChangeListener, addVetoableChangeListener, addVetoableChangeListener, clone, fireIndexedPropertyChange, firePropertyChange, firePropertyChange, fireVetoableChange, fireVetoableChange, getPropertyChangeListeners, getPropertyChangeListeners, getVetoableChangeListeners, getVetoableChangeListeners, hasPropertyChangeListeners, hasVetoableChangeListeners, removePropertyChangeListener, removePropertyChangeListener, removeVetoableChangeListener, removeVetoableChangeListener
 
Methods inherited from class java.lang.Object
equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

BackgroundWorker

public BackgroundWorker()
Creates a new instance of BackgroundWorker

Method Detail

isDone

public boolean isDone()

isRunning

public final boolean isRunning()
Returns:
true if the BackgroundWorker is currently running, false otherwise

setProgress

public final void setProgress(float progress)
Set the progress of this worker based on a value between 0 and 1 where 0 represents 0% and 1 represents 100%. If the progress has changed a percentage point, then a property change event will be fired. Not that changes from 0.1 to 0.11 will not be registered. This is a convenience method, and is analogous to the setProgressPercent method. This method may be called from any thread.


getProgress

public final float getProgress()
Returns the progress bound property. This method may be called from any thread.

Returns:
the progress bound property.

setProgressPercent

public final void setProgressPercent(int percent)
Set the progress of this worker based on a value between 0 and 100 where 0 represents 0% and 100 represents 100%. If the progress has changed a percentage point, then a property change event will be fired. This method may be called from any thread.


getProgressPercent

public final int getProgressPercent()
Returns the progressPercent bound property. This method may be called from any thread.

Returns:
the progressPercent bound property.

setExecutorService

protected final void setExecutorService(java.util.concurrent.ExecutorService svc)
Sets the executorService bound property. This property, if not null, will specify the ExecutorService to use for running the background task. If null, then the default ExecutorService of SwingWorker will be used instead. This method must only be called on the EDT, and may not be called while the BackgroundWorker is running.


getExecutorService

protected final java.util.concurrent.ExecutorService getExecutorService()
Returns the executorService bound property. This method may be called from any thread.

Returns:
the executorService bound property.

execute

public void execute()

Executes the BackgroundWorker, causing it to begin processing. This method MUST be called on the EDT, and MUST NOT be called if the BackgroundWorker is already running.

Execution follows these steps:

  1. The running and done states are updated and PropertyChangeEvents are fired for them if necessary
  2. The started event of the BackroundListener is called
  3. The doInBackground event of the BackgroundListener is called. This is where background tasks must be performed. If you want to publish some data to the Event Dispatch Thread (EDT), then you must call the publish method of the BackgroundWorker. Calling the publish method will in turn cause the process event handler to be called on the EDT. From this event handler you are free to update the Swing GUI in any way. If you need to update the progress state, you may do so directly from the doInBackground event handler. Updates to the progress will be set via PropertyChangeEvents on the EDT.
  4. Once concluded, the done event will be called. Subsequent to handling the event, the running and done states are updated and PropertyChangeEvents are fired for them if necessary


publish

public void publish(java.lang.Object... chunks)
Causes the given "chunks" of data to be published on the Event Dispatch Thread. This method causes the process event handler to be called. That event handler is guaranteed to be called on the EDT. This method MUST be called on the background thread.


addBackgroundListener

public void addBackgroundListener(BackgroundListener listener)
Adds a BackgroundListener


removeBackgroundListener

public void removeBackgroundListener(BackgroundListener listener)
Removes the given BackgroundListener such that it will no longer be notified of background events.


getBackgroundListeners

public BackgroundListener[] getBackgroundListeners()
Returns an array of all BackgroundListeners registered with this object