/* * File : SwingWorker.java * Created : 09-jan-2002 12:00 * By : fbusquets * * JClic - Authoring and playing system for educational activities * * Taken from: * The Java Tutorial * http://java.sun.com/docs/books/tutorial/ */ package edu.xtec.util; import javax.swing.SwingUtilities; /** * This is the 3rd version of SwingWorker (also known as SwingWorker 3), an * abstract class that you subclass to perform GUI-related work in a dedicated * thread. For instructions on using this class, see: * *
* http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html * *
* Note that the API changed slightly in the 3rd version: You must now invoke
* start() on the SwingWorker after creating it.
*/
public abstract class SwingWorker {
private Object value; // see getValue(), setValue()
private Thread thread;
private boolean cancelled;
/**
* Class to maintain reference to current worker thread under separate
* synchronization control.
*/
private static class ThreadVar {
private Thread thread;
ThreadVar(Thread t) {
thread = t;
}
synchronized Thread get() {
return thread;
}
synchronized void clear() {
thread = null;
}
}
private ThreadVar threadVar;
/**
* Get the value produced by the worker thread, or null if it hasn't been
* constructed yet.
*/
protected synchronized Object getValue() {
return value;
}
public void cancel() {
cancelled = true;
}
public boolean isCancelled() {
return cancelled;
}
/** Set the value produced by worker thread */
private synchronized void setValue(Object x) {
value = x;
}
/** Compute the value to be returned by the get
method. */
public abstract Object construct();
/**
* Called on the event dispatching thread (not on the worker thread) after the
* construct
*
method has returned.
*/
public void finished() {
}
/**
* A new method that interrupts the worker thread. Call this method to force the
* worker to stop what it's doing.
*/
public void interrupt() {
Thread t = threadVar.get();
if (t != null) {
t.interrupt();
}
threadVar.clear();
}
/**
* Return the value created by the construct
method. Returns null
* if either the constructing thread or the current thread was interrupted
* before a value was produced.
*
* @return the value created by the construct
method
*/
public Object get() {
while (true) {
Thread t = threadVar.get();
if (t == null) {
return getValue();
}
try {
t.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // propagate
return null;
}
}
}
/**
* Start a thread that will call the construct
method and then
* exit.
*/
public SwingWorker() {
final Runnable doFinished = new Runnable() {
public void run() {
finished();
}
};
Runnable doConstruct = new Runnable() {
public void run() {
try {
setValue(construct());
} finally {
threadVar.clear();
}
SwingUtilities.invokeLater(doFinished);
}
};
Thread t = new Thread(doConstruct);
threadVar = new ThreadVar(t);
}
/** Start the worker thread. */
public void start() {
Thread t = threadVar.get();
if (t != null) {
t.start();
}
}
public void startLater() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
start();
}
});
}
}