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