001: /*
002: * <copyright>
003: *
004: * Copyright 2003-2004 BBNT Solutions, LLC
005: * under sponsorship of the Defense Advanced Research Projects
006: * Agency (DARPA).
007: *
008: * You can redistribute this software and/or modify it under the
009: * terms of the Cougaar Open Source License as published on the
010: * Cougaar Open Source Website (www.cougaar.org).
011: *
012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023: *
024: * </copyright>
025: */
026: /**
027: * This is the 3rd version of SwingWorker (also known as
028: * SwingWorker 3), an abstract class that you subclass to
029: * perform GUI-related work in a dedicated thread. For
030: * instructions on using this class, see:
031: *
032: * http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html
033: *
034: * Note that the API changed slightly in the 3rd version:
035: * You must now invoke start() on the SwingWorker after
036: * creating it.
037: */package org.cougaar.tools.csmart.ui.console;
038:
039: import javax.swing.*;
040:
041: public abstract class SwingWorker {
042: private Object value; // see getValue(), setValue()
043:
044: // private Thread thread;
045:
046: /**
047: * Class to maintain reference to current worker thread
048: * under separate synchronization control.
049: */
050: private static class ThreadVar {
051: private Thread thread;
052:
053: ThreadVar(Thread t) {
054: thread = t;
055: }
056:
057: synchronized Thread get() {
058: return thread;
059: }
060:
061: synchronized void clear() {
062: thread = null;
063: }
064: }
065:
066: private ThreadVar threadVar;
067:
068: /**
069: * Get the value produced by the worker thread, or null if it
070: * hasn't been constructed yet.
071: */
072: protected synchronized Object getValue() {
073: return value;
074: }
075:
076: /**
077: * Set the value produced by worker thread
078: */
079: private synchronized void setValue(Object x) {
080: value = x;
081: }
082:
083: /**
084: * Compute the value to be returned by the <code>get</code> method.
085: */
086: public abstract Object construct();
087:
088: /**
089: * Called on the event dispatching thread (not on the worker thread)
090: * after the <code>construct</code> method has returned.
091: */
092: public void finished() {
093: }
094:
095: /**
096: * A new method that interrupts the worker thread. Call this method
097: * to force the worker to stop what it's doing.
098: */
099: public void interrupt() {
100: Thread t = threadVar.get();
101: if (t != null) {
102: t.interrupt();
103: }
104: threadVar.clear();
105: }
106:
107: /**
108: * Return the value created by the <code>construct</code> method.
109: * Returns null if either the constructing thread or the current
110: * thread was interrupted before a value was produced.
111: *
112: * @return the value created by the <code>construct</code> method
113: */
114: public Object get() {
115: while (true) {
116: Thread t = threadVar.get();
117: if (t == null) {
118: return getValue();
119: }
120: try {
121: t.join();
122: } catch (InterruptedException e) {
123: Thread.currentThread().interrupt(); // propagate
124: return null;
125: }
126: }
127: }
128:
129: /**
130: * Start a thread that will call the <code>construct</code> method
131: * and then exit.
132: */
133: public SwingWorker() {
134: final Runnable doFinished = new Runnable() {
135: public void run() {
136: finished();
137: }
138: };
139:
140: Runnable doConstruct = new Runnable() {
141: public void run() {
142: try {
143: setValue(construct());
144: } finally {
145: threadVar.clear();
146: }
147:
148: SwingUtilities.invokeLater(doFinished);
149: }
150: };
151:
152: Thread t = new Thread(doConstruct);
153: threadVar = new ThreadVar(t);
154: }
155:
156: /**
157: * Start the worker thread.
158: */
159: public void start() {
160: Thread t = threadVar.get();
161: if (t != null) {
162: t.start();
163: }
164: }
165: }
|