001: package fr.aliacom.form.common;
002:
003: /**
004: * This is a rework of SwingWorker.
005: */
006: public class FormWorker {
007: private Object value; // see getValue(), setValue()
008: private IWorker worker;
009:
010: public FormWorker(IWorker worker) {
011: this .worker = worker;
012: }
013:
014: /**
015: * Class to maintain reference to current worker thread
016: * under separate synchronization control.
017: */
018: private static class ThreadVar {
019: private Thread thread;
020:
021: ThreadVar(Thread t) {
022: thread = t;
023: }
024:
025: synchronized Thread get() {
026: return thread;
027: }
028:
029: synchronized void clear() {
030: thread = null;
031: }
032: }
033:
034: private ThreadVar threadVar;
035:
036: /**
037: * Get the value produced by the worker thread, or null if it
038: * hasn't been constructed yet.
039: */
040: protected synchronized Object getValue() {
041: return value;
042: }
043:
044: /**
045: * Set the value produced by worker thread
046: */
047: private synchronized void setValue(Object x) {
048: value = x;
049: }
050:
051: /**
052: * Compute the value to be returned by the <code>get</code> method.
053: */
054: public Object construct() {
055: return worker.construct();
056: }
057:
058: /**
059: * Called on the event dispatching thread (not on the worker thread)
060: * after the <code>construct</code> method has returned.
061: */
062: public void finished() {
063: worker.finished();
064: }
065:
066: /**
067: * A new method that interrupts the worker thread. Call this method
068: * to force the worker to stop what it's doing.
069: */
070: public void interrupt() {
071: Thread t = threadVar.get();
072: if (t != null) {
073: t.interrupt();
074: }
075: threadVar.clear();
076: }
077:
078: /**
079: * Return the value created by the <code>construct</code> method.
080: * Returns null if either the constructing thread or the current
081: * thread was interrupted before a value was produced.
082: *
083: * @return the value created by the <code>construct</code> method
084: */
085: public Object get() {
086: while (true) {
087: Thread t = threadVar.get();
088: if (t == null) {
089: return getValue();
090: }
091: try {
092: t.join();
093: } catch (InterruptedException e) {
094: Thread.currentThread().interrupt(); // propagate
095: return null;
096: }
097: }
098: }
099:
100: /**
101: * Start a thread that will call the <code>construct</code> method
102: * and then exit.
103: */
104: public FormWorker() {
105: final Runnable doFinished = new Runnable() {
106: public void run() {
107: finished();
108: }
109: };
110:
111: Runnable doConstruct = new Runnable() {
112: public void run() {
113: try {
114: setValue(construct());
115: } finally {
116: threadVar.clear();
117: }
118:
119: ToolkitManager.getToolkit().asyncExec(doFinished);
120: }
121: };
122:
123: Thread t = new Thread(doConstruct);
124: threadVar = new ThreadVar(t);
125: }
126:
127: /**
128: * Start the worker thread.
129: */
130: public void start() {
131: Thread t = threadVar.get();
132: if (t != null) {
133: t.start();
134: }
135: }
136: }
|