001: // This file is part of KeY - Integrated Deductive Software Design
002: // Copyright (C) 2001-2007 Universitaet Karlsruhe, Germany
003: // Universitaet Koblenz-Landau, Germany
004: // Chalmers University of Technology, Sweden
005: //
006: // The KeY system is protected by the GNU General Public License.
007: // See LICENSE.TXT for details.
008: //
009: //
010: package de.uka.ilkd.key.gui;
011:
012: import javax.swing.SwingUtilities;
013:
014: /**
015: * This is the 3rd version of SwingWorker (also known as
016: * SwingWorker 3), an abstract class that you subclass to
017: * perform GUI-related work in a dedicated thread. For
018: * instructions on using this class, see:
019: *
020: * http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html
021: *
022: * Note that the API changed slightly in the 3rd version:
023: * You must now invoke start() on the SwingWorker after
024: * creating it.
025: */
026: public abstract class SwingWorker {
027: private Object value; // see getValue(), setValue()
028:
029: //private Thread thread;
030:
031: /**
032: * Class to maintain reference to current worker thread
033: * under separate synchronization control.
034: */
035: private static class ThreadVar {
036: private Thread thread;
037:
038: ThreadVar(Thread t) {
039: thread = t;
040: }
041:
042: synchronized Thread get() {
043: return thread;
044: }
045:
046: synchronized void clear() {
047: thread = null;
048: }
049: }
050:
051: private ThreadVar threadVar;
052:
053: /**
054: * Get the value produced by the worker thread, or null if it
055: * hasn't been constructed yet.
056: */
057: protected synchronized Object getValue() {
058: return value;
059: }
060:
061: /**
062: * Set the value produced by worker thread
063: */
064: private synchronized void setValue(Object x) {
065: value = x;
066: }
067:
068: /**
069: * Compute the value to be returned by the <code>get</code> method.
070: */
071: public abstract Object construct();
072:
073: /**
074: * Called on the event dispatching thread (not on the worker thread)
075: * after the <code>construct</code> method has returned.
076: */
077: public void finished() {
078: }
079:
080: /**
081: * A new method that interrupts the worker thread. Call this method
082: * to force the worker to stop what it's doing.
083: */
084: public void interrupt() {
085: Thread t = threadVar.get();
086: if (t != null) {
087: t.interrupt();
088: }
089: threadVar.clear();
090: }
091:
092: /**
093: * Return the value created by the <code>construct</code> method.
094: * Returns null if either the constructing thread or the current
095: * thread was interrupted before a value was produced.
096: *
097: * @return the value created by the <code>construct</code> method
098: */
099: public Object get() {
100: while (true) {
101: Thread t = threadVar.get();
102: if (t == null) {
103: return getValue();
104: }
105: try {
106: t.join();
107: } catch (InterruptedException e) {
108: Thread.currentThread().interrupt(); // propagate
109: return null;
110: }
111: }
112: }
113:
114: /**
115: * Start a thread that will call the <code>construct</code> method
116: * and then exit.
117: */
118: public SwingWorker() {
119: final Runnable doFinished = new Runnable() {
120: public void run() {
121: finished();
122: }
123: };
124:
125: Runnable doConstruct = new Runnable() {
126: public void run() {
127: try {
128: setValue(construct());
129: } finally {
130: threadVar.clear();
131: }
132:
133: SwingUtilities.invokeLater(doFinished);
134: }
135: };
136:
137: Thread t = new Thread(doConstruct);
138: threadVar = new ThreadVar(t);
139: }
140:
141: /**
142: * Start the worker thread.
143: */
144: public void start() {
145: Thread t = threadVar.get();
146: if (t != null) {
147: t.start();
148: }
149: }
150: }
|