This documentation differs from the official API. Jadeite adds extra features to the API including: variable font sizes, constructions examples, placeholders for classes and methods, and auto-generated “See Also” links. Additionally it is missing some items found in standard Javadoc documentation, including: generics type information, “Deprecated” tags and comments, “See Also” links, along with other minor differences. Please send any questions or feedback to bam@cs.cmu.edu.


javax.swing
class SwingWorker

java.lang.Object extended by javax.swing.SwingWorker
All Implemented Interfaces:
RunnableFuture

public abstract class SwingWorker
extends Object
implements RunnableFuture

An abstract class 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.

{@code SwingWorker} is designed for situations where you need to have a long running task run in a background thread and provide updates to the UI either when done, or while processing. Subclasses of {@code SwingWorker} must implement the {@link #doInBackground} method to perform the background computation.

Workflow

There are three threads involved in the life cycle of a {@code SwingWorker} :

Often, the Current thread is the Event Dispatch Thread.

Before the {@code doInBackground} method is invoked on a worker thread, {@code SwingWorker} notifies any {@code PropertyChangeListeners} about the {@code state} property change to {@code StateValue.STARTED}. After the {@code doInBackground} method is finished the {@code done} method is executed. Then {@code SwingWorker} notifies any {@code PropertyChangeListeners} about the {@code state} property change to {@code StateValue.DONE}.

{@code SwingWorker} is only designed to be executed once. Executing a {@code SwingWorker} more than once will not result in invoking the {@code doInBackground} method twice.

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 {@code JLabel}.

   final JLabel label;
   class MeaningOfLifeFinder extends SwingWorker<String, Object> {
       {@code @Override}
       public String doInBackground() {
           return findTheMeaningOfLife();
       }

       {@code @Override}
       protected void done() {
           try { 
               label.setText(get());
           } catch (Exception ignore) {
           }
       }
   }
 
   (new MeaningOfLifeFinder()).execute();
 

The next example is useful in situations where you wish to process data as it is ready on the Event Dispatch Thread.

Now we want to find the first N prime numbers and display the results in a {@code JTextArea}. While this is computing, we want to update our progress in a {@code JProgressBar}. Finally, we also want to print the prime numbers to {@code System.out}.

 class PrimeNumbersTask extends 
         SwingWorker<List<Integer>, Integer> {
     PrimeNumbersTask(JTextArea textArea, int numbersToFind) { 
         //initialize 
     }

     {@code @Override}
     public List<Integer> doInBackground() {
         while (! enough && ! isCancelled()) {
                 number = nextPrimeNumber();
                 publish(number);
                 setProgress(100 * numbers.size() / numbersToFind);
             }
         }
         return numbers;
     }

     {@code @Override}
     protected void process(List<Integer> chunks) {
         for (int number : chunks) {
             textArea.append(number + "\n");
         }
     }
 }

 JTextArea textArea = new JTextArea();
 final JProgressBar progressBar = new JProgressBar(0, 100);
 PrimeNumbersTask task = new PrimeNumbersTask(textArea, N);
 task.addPropertyChangeListener(
     new PropertyChangeListener() {
         public  void propertyChange(PropertyChangeEvent evt) {
             if ("progress".equals(evt.getPropertyName())) {
                 progressBar.setValue((Integer)evt.getNewValue());
             }
         }
     });

 task.execute();
 System.out.println(task.get()); //prints all prime numbers we have got
 

Because {@code SwingWorker} implements {@code Runnable}, a {@code SwingWorker} can be submitted to an {@link java.util.concurrent.Executor} for execution.


Nested Class Summary
static enum

           Values for the bound property.
 
Constructor Summary

          Constructs this .
 
Method Summary
 void

          Adds a to the listener list.
 boolean
cancel(boolean mayInterruptIfRunning)

          
protected abstract Object

          Computes a result, or throws an exception if unable to do so.
protected void

          Executed on the Event Dispatch Thread after the method is finished.
 void

          Schedules this for execution on a worker thread.
 void
firePropertyChange(String propertyName, Object oldValue, Object newValue)

          Reports a bound property update to any registered listeners.
 Object
get()

          
 Object
get(long timeout, TimeUnit unit)

          
 int

          Returns the bound property.
 PropertyChangeSupport

          Returns the for this .
 SwingWorker.StateValue

          Returns the state bound property.
 boolean

          
 boolean

          
protected void
process(List chunks)

          Receives data chunks from the method asynchronously on the Event Dispatch Thread.
protected void
publish(Object[] chunks)

          Sends data chunks to the javax.swing.SwingWorker.process method.
 void

          Removes a from the listener list.
 void
run()

          Sets this to the result of computation unless it has been cancelled.
protected void
setProgress(int progress)

          Sets the bound property.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

SwingWorker

public SwingWorker()
Constructs this {@code SwingWorker}.

Method Detail

addPropertyChangeListener

public final void addPropertyChangeListener(PropertyChangeListener listener)
Adds a {@code PropertyChangeListener} to the listener list. The listener is registered for all properties. The same listener object may be added more than once, and will be called as many times as it is added. If {@code listener} is {@code null}, no exception is thrown and no action is taken.

Note: This is merely a convenience wrapper. All work is delegated to {@code PropertyChangeSupport} from {@link #getPropertyChangeSupport}.

Parameters:
listener - the {@code PropertyChangeListener} to be added

cancel

public final boolean cancel(boolean mayInterruptIfRunning)
{@inheritDoc}

Parameters:
mayInterruptIfRunning

doInBackground

protected abstract Object doInBackground()
                                  throws Exception
Computes a result, or throws an exception if unable to do so.

Note that this method is executed only once.

Note: this method is executed in a background thread.

Returns:
the computed result
Throws:
Exception - if unable to compute a result

done

protected void done()
Executed on the Event Dispatch Thread after the {@code doInBackground} method is finished. The default implementation does nothing. Subclasses may override this method to perform completion actions on the Event Dispatch Thread. Note that you can query status inside the implementation of this method to determine the result of this task or whether this task has been cancelled.


execute

public final void execute()
Schedules this {@code SwingWorker} for execution on a worker thread. There are a number of worker threads available. In the event all worker threads are busy handling other {@code SwingWorkers} this {@code SwingWorker} is placed in a waiting queue.

Note: {@code SwingWorker} is only designed to be executed once. Executing a {@code SwingWorker} more than once will not result in invoking the {@code doInBackground} method twice.


firePropertyChange

public final void firePropertyChange(String propertyName,
                                     Object oldValue,
                                     Object newValue)
Reports a bound property update to any registered listeners. No event is fired if {@code old} and {@code new} are equal and non-null.

This {@code SwingWorker} will be the source for any generated events.

When called off the Event Dispatch Thread {@code PropertyChangeListeners} are notified asynchronously on the Event Dispatch Thread.

Note: This is merely a convenience wrapper. All work is delegated to {@code PropertyChangeSupport} from {@link #getPropertyChangeSupport}.

Parameters:
propertyName - the programmatic name of the property that was changed
oldValue - the old value of the property
newValue - the new value of the property

get

public final Object get()
                 throws InterruptedException,
                        ExecutionException
{@inheritDoc}

Note: calling {@code get} on the Event Dispatch Thread blocks all events, including repaints, from being processed until this {@code SwingWorker} is complete.

When you want the {@code SwingWorker} to block on the Event Dispatch Thread we recommend that you use a modal dialog.

For example:

 class SwingWorkerCompletionWaiter extends PropertyChangeListener {
     private JDialog dialog;
 
     public SwingWorkerCompletionWaiter(JDialog dialog) {
         this.dialog = dialog;
     }
 
     public void propertyChange(PropertyChangeEvent event) {
         if ("state".equals(event.getPropertyName())
                 && SwingWorker.StateValue.DONE == event.getNewValue()) {
             dialog.setVisible(false);
             dialog.dispose();
         }
     }
 }
 JDialog dialog = new JDialog(owner, true);
 swingWorker.addPropertyChangeListener(
     new SwingWorkerCompletionWaiter(dialog));
 swingWorker.execute();
 //the dialog will be visible until the SwingWorker is done
 dialog.setVisible(true); 
 

Throws:
InterruptedException
ExecutionException

get

public final Object get(long timeout,
                        TimeUnit unit)
                 throws InterruptedException,
                        ExecutionException,
                        TimeoutException
{@inheritDoc}

Please refer to {@link #get} for more details.

Parameters:
timeout
unit
Throws:
InterruptedException
ExecutionException
TimeoutException

getProgress

public final int getProgress()
Returns the {@code progress} bound property.

Returns:
the progress bound property.

getPropertyChangeSupport

public final PropertyChangeSupport getPropertyChangeSupport()
Returns the {@code PropertyChangeSupport} for this {@code SwingWorker}. This method is used when flexible access to bound properties support is needed.

This {@code SwingWorker} will be the source for any generated events.

Note: The returned {@code PropertyChangeSupport} notifies any {@code PropertyChangeListener}s asynchronously on the Event Dispatch Thread in the event that {@code firePropertyChange} or {@code fireIndexedPropertyChange} are called off the Event Dispatch Thread.

Returns:
{@code PropertyChangeSupport} for this {@code SwingWorker}

getState

public final SwingWorker.StateValue getState()
Returns the {@code SwingWorker} state bound property.

Returns:
the current state

isCancelled

public final boolean isCancelled()
{@inheritDoc}


isDone

public final boolean isDone()
{@inheritDoc}


process

protected void process(List chunks)
Receives data chunks from the {@code publish} method asynchronously on the Event Dispatch Thread.

Please refer to the {@link #publish} method for more details.

Parameters:
chunks - intermediate results to process

publish

protected final void publish(Object[] chunks)
Sends data chunks to the {@link #process} method. This method is to be used from inside the {@code doInBackground} method to deliver intermediate results for processing on the Event Dispatch Thread inside the {@code process} method.

Because the {@code process} method is invoked asynchronously on the Event Dispatch Thread multiple invocations to the {@code publish} method might occur before the {@code process} method is executed. For performance purposes all these invocations are coalesced into one invocation with concatenated arguments.

For example:

 publish("1");
 publish("2", "3");
 publish("4", "5", "6");
 
might result in:
 process("1", "2", "3", "4", "5", "6")
 

Sample Usage. This code snippet loads some tabular data and updates {@code DefaultTableModel} with it. Note that it safe to mutate the tableModel from inside the {@code process} method because it is invoked on the Event Dispatch Thread.

 class TableSwingWorker extends 
         SwingWorker<DefaultTableModel, Object[]> {
     private final DefaultTableModel tableModel;
 
     public TableSwingWorker(DefaultTableModel tableModel) {
         this.tableModel = tableModel;
     }
 
     {@code @Override}
     protected DefaultTableModel doInBackground() throws Exception {
         for (Object[] row = loadData(); 
                  ! isCancelled() && row != null; 
                  row = loadData()) {
             publish((Object[]) row);
         }
         return tableModel;
     }
 
     {@code @Override}
     protected void process(List<Object[]> chunks) {
         for (Object[] row : chunks) {
             tableModel.addRow(row);
         }
     }
 }
 

Parameters:
chunks - intermediate results to process

removePropertyChangeListener

public final void removePropertyChangeListener(PropertyChangeListener listener)
Removes a {@code PropertyChangeListener} from the listener list. This removes a {@code PropertyChangeListener} that was registered for all properties. If {@code listener} was added more than once to the same event source, it will be notified one less time after being removed. If {@code listener} is {@code null}, or was never added, no exception is thrown and no action is taken.

Note: This is merely a convenience wrapper. All work is delegated to {@code PropertyChangeSupport} from {@link #getPropertyChangeSupport}.

Parameters:
listener - the {@code PropertyChangeListener} to be removed

run

public final void run()
Sets this {@code Future} to the result of computation unless it has been cancelled.


setProgress

protected final void setProgress(int progress)
Sets the {@code progress} bound property. The value should be from 0 to 100.

Because {@code PropertyChangeListener}s are notified asynchronously on the Event Dispatch Thread multiple invocations to the {@code setProgress} method might occur before any {@code PropertyChangeListeners} are invoked. For performance purposes all these invocations are coalesced into one invocation with the last invocation argument only.

For example, the following invokations:

 setProgress(1);
 setProgress(2);
 setProgress(3);
 
might result in a single {@code PropertyChangeListener} notification with the value {@code 3}.

Parameters:
progress - the progress value to set


This documentation differs from the official API. Jadeite adds extra features to the API including: variable font sizes, constructions examples, placeholders for classes and methods, and auto-generated “See Also” links. Additionally it is missing some items found in standard Javadoc documentation, including: generics type information, “Deprecated” tags and comments, “See Also” links, along with other minor differences. Please send any questions or feedback to bam@cs.cmu.edu.
This page displays the Jadeite version of the documention, which is derived from the offical documentation that contains this copyright notice:
Copyright 2008 Sun Microsystems, Inc. All rights reserved. Use is subject to license terms. Also see the documentation redistribution policy.
The official Sun™ documentation can be found here at http://java.sun.com/javase/6/docs/api/.