import javax.swing.*;
import java.awt.event.ActionEvent;
public class SwingWorkerExample extends JPanel {
private JLabel statusArea;
private DefaultListModel listModel;
public SwingWorkerExample() {
JButton button = new JButton(new LongRunningModelFillAction());
add(button);
JList list = new JList();
this.listModel = new DefaultListModel();
this.listModel.addElement("An Empty List Model");
list.setModel(listModel);
add(new JScrollPane(list));
add(new JLabel("Status:"));
this.statusArea = new JLabel();
add(this.statusArea);
}
private class LongRunningModelFillAction extends AbstractAction {
public LongRunningModelFillAction() {
super("Fill Model");
}
public void actionPerformed(ActionEvent e) {
PopulationWorker populationWorker = new PopulationWorker();
populationWorker.start();
}
}
private class PopulationWorker extends SwingWorker {
public Object construct() {
Object[] values = new Object[100];
for (int i = 1; i <= 100; i++) {
values[i - 1] = "Value" + i;
if ((i % 10) == 0) {
final int progress = i;
SwingUtilities.invokeLater(new Runnable() {
public void run() {
SwingWorkerExample.this.statusArea.setText("Calculated " + progress);
}
});
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
}
}
return values;
}
public void start() {
SwingWorkerExample.this.listModel.removeAllElements();
SwingWorkerExample.this.listModel.addElement("Calculating...");
super.start();
}
public void finished() {
SwingWorkerExample.this.statusArea.setText("");
SwingWorkerExample.this.listModel.removeAllElements();
Object[] values = (Object[]) getValue();
for (int i = 0; i < values.length; i++) {
SwingWorkerExample.this.listModel.addElement(values[i]);
}
}
}
public static void main(String[] a){
JFrame f = new JFrame();
f.setDefaultCloseOperation(1);
f.add(new SwingWorkerExample());
f.pack();
f.setVisible(true);
}
}
/*
* $Id: SwingWorker.java,v 1.1.1.1 2004/06/16 01:43:39 davidson1 Exp $
*
* Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
* Santa Clara, California 95054, U.S.A. All rights reserved.
*/
/**
* 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.
*/
abstract class SwingWorker {
private Object value; // see getValue(), setValue()
private Thread thread;
/**
* 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;
}
/**
* Set the value produced by worker thread
*/
private synchronized void setValue(Object x) {
value = x;
}
/**
* Compute the value to be returned by the <code>get</code> method.
*/
public abstract Object construct();
/**
* Called on the event dispatching thread (not on the worker thread)
* after the <code>construct</code> 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 <code>construct</code> 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 <code>construct</code> 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 <code>construct</code> 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();
}
}
}
|