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: package org.cougaar.mlm.ui;
027:
028: import javax.swing.SwingUtilities;
029:
030: /**
031: * This is the 3rd version of SwingWorker (also known as
032: * SwingWorker 3), an abstract class that you subclass to
033: * perform GUI-related work in a dedicated thread. For
034: * instructions on using this class, see:
035: *
036: * http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html
037: *
038: * Note that the API changed slightly in the 3rd version:
039: * You must now invoke start() on the SwingWorker after
040: * creating it.
041: */
042:
043: public abstract class SwingWorker {
044: private Object value; // see getValue(), setValue()
045: private Thread thread;
046:
047: /**
048: * Class to maintain reference to current worker thread
049: * under separate synchronization control.
050: */
051: private static class ThreadVar {
052: private Thread thread;
053:
054: ThreadVar(Thread t) {
055: thread = t;
056: }
057:
058: synchronized Thread get() {
059: return thread;
060: }
061:
062: synchronized void clear() {
063: thread = null;
064: }
065: }
066:
067: private ThreadVar threadVar;
068:
069: /**
070: * Get the value produced by the worker thread, or null if it
071: * hasn't been constructed yet.
072: */
073: protected synchronized Object getValue() {
074: return value;
075: }
076:
077: /**
078: * Set the value produced by worker thread
079: */
080: private synchronized void setValue(Object x) {
081: value = x;
082: }
083:
084: /**
085: * Compute the value to be returned by the <code>get</code> method.
086: */
087: public abstract Object construct();
088:
089: /**
090: * Called on the event dispatching thread (not on the worker thread)
091: * after the <code>construct</code> method has returned.
092: */
093: public void finished() {
094: }
095:
096: /**
097: * A new method that interrupts the worker thread. Call this method
098: * to force the worker to stop what it's doing.
099: */
100: public void interrupt() {
101: Thread t = threadVar.get();
102: if (t != null) {
103: t.interrupt();
104: }
105: threadVar.clear();
106: }
107:
108: /**
109: * Return the value created by the <code>construct</code> method.
110: * Returns null if either the constructing thread or the current
111: * thread was interrupted before a value was produced.
112: *
113: * @return the value created by the <code>construct</code> method
114: */
115: public Object get() {
116: while (true) {
117: Thread t = threadVar.get();
118: if (t == null) {
119: return getValue();
120: }
121: try {
122: t.join();
123: } catch (InterruptedException e) {
124: Thread.currentThread().interrupt(); // propagate
125: return null;
126: }
127: }
128: }
129:
130: /**
131: * Start a thread that will call the <code>construct</code> method
132: * and then exit.
133: */
134: public SwingWorker() {
135: final Runnable doFinished = new Runnable() {
136: public void run() {
137: finished();
138: }
139: };
140:
141: Runnable doConstruct = new Runnable() {
142: public void run() {
143: try {
144: setValue(construct());
145: } finally {
146: threadVar.clear();
147: }
148:
149: SwingUtilities.invokeLater(doFinished);
150: }
151: };
152:
153: Thread t = new Thread(doConstruct);
154: threadVar = new ThreadVar(t);
155: }
156:
157: /**
158: * Start the worker thread.
159: */
160: public void start() {
161: Thread t = threadVar.get();
162: if (t != null) {
163: t.start();
164: }
165: }
166: }
|