Source code: com/xerox/VTM/engine/SwingWorkerParam.java
1 package com.xerox.VTM.engine;
2
3 import javax.swing.SwingUtilities;
4 import java.util.Vector;
5
6 /**
7 * An abstract class that you subclass to perform
8 * GUI-related work in a dedicated thread.
9 * For instructions on using this class, see
10 * http://java.sun.com/products/jfc/swingdoc-current/threads2.html
11 * Allow parameters for the <code>construct</code> method.
12 * @see com.xerox.VTM.engine.SwingWorker
13 */
14 public abstract class SwingWorkerParam implements Runnable{
15 private Object value; // see getValue(), setValue()
16 private Thread thread;
17 private Vector param; //parameters of the construct method
18 private Runnable doFinished;
19
20 /**
21 * Class to maintain reference to current worker thread
22 * under separate synchronization control.
23 */
24 private static class ThreadVar {
25 private Thread thread;
26 ThreadVar(Thread t) { thread = t; }
27 synchronized Thread get() { return thread; }
28 synchronized void clear() { thread = null; }
29 }
30
31 private ThreadVar threadVar;
32
33 /**
34 * Get the value produced by the worker thread, or null if it
35 * hasn't been constructed yet.
36 */
37 protected synchronized Object getValue() {
38 return value;
39 }
40
41 /**
42 * Set the value produced by worker thread
43 */
44 private synchronized void setValue(Object x) {
45 value = x;
46 }
47
48 /**
49 * Compute the value to be returned by the <code>get</code> method.
50 */
51 public abstract Object construct(Vector p);
52
53 /**
54 * Called on the event dispatching thread (not on the worker thread)
55 * after the <code>construct</code> method has returned.
56 */
57 public void finished() {
58 }
59
60 /**
61 * A new method that interrupts the worker thread. Call this method
62 * to force the worker to abort what it's doing.
63 */
64 public void interrupt() {
65 Thread t = threadVar.get();
66 if (t != null) {
67 t.interrupt();
68 }
69 threadVar.clear();
70 }
71
72 /**
73 * Return the value created by the <code>construct</code> method.
74 * Returns null if either the constructing thread or
75 * the current thread was interrupted before a value was produced.
76 *
77 * @return the value created by the <code>construct</code> method
78 */
79 public Object get() {
80 while (true) {
81 Thread t = threadVar.get();
82 if (t == null) {
83 return getValue();
84 }
85 try {
86 t.join();
87 }
88 catch (InterruptedException e) {
89 Thread.currentThread().interrupt(); // propagate
90 return null;
91 }
92 }
93 }
94
95 public void run() {
96 try {
97 this.setValue(this.construct(this.param));
98 }
99 finally {
100 this.threadVar.clear();
101 }
102 SwingUtilities.invokeLater(this.doFinished);
103 }
104
105 /**
106 * Start a thread that will call the <code>construct</code> method
107 * and then exit.
108 * @param constructParameters parameters the internal thread use
109 * when it calls the construct method.
110 */
111 public SwingWorkerParam(Vector constructParameters) {
112 this.param=constructParameters;
113 this.doFinished=new Runnable() {
114 public void run() { finished(); }
115 };
116
117 Thread doConstruct = new Thread(this);
118
119 this.threadVar = new ThreadVar(doConstruct);
120 doConstruct.start();
121 }
122 }