2 |
26 Feb 07 |
jari |
1 |
package org.tigr.microarray.mev.r; |
2 |
26 Feb 07 |
jari |
2 |
|
2 |
26 Feb 07 |
jari |
3 |
import javax.swing.SwingUtilities; |
2 |
26 Feb 07 |
jari |
4 |
|
2 |
26 Feb 07 |
jari |
5 |
/** |
2 |
26 Feb 07 |
jari |
* This is the 3rd version of SwingWorker (also known as |
2 |
26 Feb 07 |
jari |
* SwingWorker 3), an abstract class that you subclass to |
2 |
26 Feb 07 |
jari |
* perform GUI-related work in a dedicated thread. For |
2 |
26 Feb 07 |
jari |
* instructions on and examples of using this class, see: |
2 |
26 Feb 07 |
jari |
10 |
* |
2 |
26 Feb 07 |
jari |
* http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html |
2 |
26 Feb 07 |
jari |
12 |
* |
2 |
26 Feb 07 |
jari |
* Note that the API changed slightly in the 3rd version: |
2 |
26 Feb 07 |
jari |
* You must now invoke start() on the SwingWorker after |
2 |
26 Feb 07 |
jari |
* creating it. |
2 |
26 Feb 07 |
jari |
16 |
*/ |
2 |
26 Feb 07 |
jari |
17 |
public abstract class SwingWorker { |
2 |
26 Feb 07 |
jari |
18 |
private Object value; // see getValue(), setValue() |
2 |
26 Feb 07 |
jari |
19 |
|
2 |
26 Feb 07 |
jari |
20 |
/** |
2 |
26 Feb 07 |
jari |
* Class to maintain reference to current worker thread |
2 |
26 Feb 07 |
jari |
* under separate synchronization control. |
2 |
26 Feb 07 |
jari |
23 |
*/ |
2 |
26 Feb 07 |
jari |
24 |
private static class ThreadVar { |
2 |
26 Feb 07 |
jari |
25 |
private Thread thread; |
2 |
26 Feb 07 |
jari |
26 |
ThreadVar(Thread t) { thread = t; } |
2 |
26 Feb 07 |
jari |
27 |
synchronized Thread get() { return thread; } |
2 |
26 Feb 07 |
jari |
28 |
synchronized void clear() { thread = null; } |
2 |
26 Feb 07 |
jari |
29 |
} |
2 |
26 Feb 07 |
jari |
30 |
|
2 |
26 Feb 07 |
jari |
31 |
private ThreadVar threadVar; |
2 |
26 Feb 07 |
jari |
32 |
|
2 |
26 Feb 07 |
jari |
33 |
/** |
2 |
26 Feb 07 |
jari |
* Get the value produced by the worker thread, or null if it |
2 |
26 Feb 07 |
jari |
* hasn't been constructed yet. |
2 |
26 Feb 07 |
jari |
36 |
*/ |
2 |
26 Feb 07 |
jari |
37 |
protected synchronized Object getValue() { |
2 |
26 Feb 07 |
jari |
38 |
return value; |
2 |
26 Feb 07 |
jari |
39 |
} |
2 |
26 Feb 07 |
jari |
40 |
|
2 |
26 Feb 07 |
jari |
41 |
/** |
2 |
26 Feb 07 |
jari |
* Set the value produced by worker thread |
2 |
26 Feb 07 |
jari |
43 |
*/ |
2 |
26 Feb 07 |
jari |
44 |
private synchronized void setValue(Object x) { |
2 |
26 Feb 07 |
jari |
45 |
value = x; |
2 |
26 Feb 07 |
jari |
46 |
} |
2 |
26 Feb 07 |
jari |
47 |
|
2 |
26 Feb 07 |
jari |
48 |
/** |
2 |
26 Feb 07 |
jari |
* Compute the value to be returned by the <code>get</code> method. |
2 |
26 Feb 07 |
jari |
50 |
*/ |
2 |
26 Feb 07 |
jari |
51 |
public abstract Object construct(); |
2 |
26 Feb 07 |
jari |
52 |
|
2 |
26 Feb 07 |
jari |
53 |
/** |
2 |
26 Feb 07 |
jari |
* Called on the event dispatching thread (not on the worker thread) |
2 |
26 Feb 07 |
jari |
* after the <code>construct</code> method has returned. |
2 |
26 Feb 07 |
jari |
56 |
*/ |
2 |
26 Feb 07 |
jari |
57 |
public void finished() { |
2 |
26 Feb 07 |
jari |
58 |
} |
2 |
26 Feb 07 |
jari |
59 |
|
2 |
26 Feb 07 |
jari |
60 |
/** |
2 |
26 Feb 07 |
jari |
* A new method that interrupts the worker thread. Call this method |
2 |
26 Feb 07 |
jari |
* to force the worker to stop what it's doing. |
2 |
26 Feb 07 |
jari |
63 |
*/ |
2 |
26 Feb 07 |
jari |
64 |
public void interrupt() { |
2 |
26 Feb 07 |
jari |
65 |
Thread t = threadVar.get(); |
2 |
26 Feb 07 |
jari |
66 |
if (t != null) { |
2 |
26 Feb 07 |
jari |
67 |
t.interrupt(); |
2 |
26 Feb 07 |
jari |
68 |
} |
2 |
26 Feb 07 |
jari |
69 |
threadVar.clear(); |
2 |
26 Feb 07 |
jari |
70 |
} |
2 |
26 Feb 07 |
jari |
71 |
|
2 |
26 Feb 07 |
jari |
72 |
/** |
2 |
26 Feb 07 |
jari |
* Return the value created by the <code>construct</code> method. |
2 |
26 Feb 07 |
jari |
* Returns null if either the constructing thread or the current |
2 |
26 Feb 07 |
jari |
* thread was interrupted before a value was produced. |
2 |
26 Feb 07 |
jari |
76 |
* |
2 |
26 Feb 07 |
jari |
* @return the value created by the <code>construct</code> method |
2 |
26 Feb 07 |
jari |
78 |
*/ |
2 |
26 Feb 07 |
jari |
79 |
public Object get() { |
2 |
26 Feb 07 |
jari |
80 |
while (true) { |
2 |
26 Feb 07 |
jari |
81 |
Thread t = threadVar.get(); |
2 |
26 Feb 07 |
jari |
82 |
if (t == null) { |
2 |
26 Feb 07 |
jari |
83 |
return getValue(); |
2 |
26 Feb 07 |
jari |
84 |
} |
2 |
26 Feb 07 |
jari |
85 |
try { |
2 |
26 Feb 07 |
jari |
86 |
t.join(); |
2 |
26 Feb 07 |
jari |
87 |
} |
2 |
26 Feb 07 |
jari |
88 |
catch (InterruptedException e) { |
2 |
26 Feb 07 |
jari |
89 |
Thread.currentThread().interrupt(); // propagate |
2 |
26 Feb 07 |
jari |
90 |
return null; |
2 |
26 Feb 07 |
jari |
91 |
} |
2 |
26 Feb 07 |
jari |
92 |
} |
2 |
26 Feb 07 |
jari |
93 |
} |
2 |
26 Feb 07 |
jari |
94 |
|
2 |
26 Feb 07 |
jari |
95 |
|
2 |
26 Feb 07 |
jari |
96 |
/** |
2 |
26 Feb 07 |
jari |
* Start a thread that will call the <code>construct</code> method |
2 |
26 Feb 07 |
jari |
* and then exit. |
2 |
26 Feb 07 |
jari |
99 |
*/ |
2 |
26 Feb 07 |
jari |
100 |
public SwingWorker() { |
2 |
26 Feb 07 |
jari |
101 |
final Runnable doFinished = new Runnable() { |
2 |
26 Feb 07 |
jari |
102 |
public void run() { finished(); } |
2 |
26 Feb 07 |
jari |
103 |
}; |
2 |
26 Feb 07 |
jari |
104 |
|
2 |
26 Feb 07 |
jari |
105 |
Runnable doConstruct = new Runnable() { |
2 |
26 Feb 07 |
jari |
106 |
public void run() { |
2 |
26 Feb 07 |
jari |
107 |
try { |
2 |
26 Feb 07 |
jari |
108 |
setValue(construct()); |
2 |
26 Feb 07 |
jari |
109 |
} |
2 |
26 Feb 07 |
jari |
110 |
finally { |
2 |
26 Feb 07 |
jari |
111 |
threadVar.clear(); |
2 |
26 Feb 07 |
jari |
112 |
} |
2 |
26 Feb 07 |
jari |
113 |
|
2 |
26 Feb 07 |
jari |
114 |
SwingUtilities.invokeLater(doFinished); |
2 |
26 Feb 07 |
jari |
115 |
} |
2 |
26 Feb 07 |
jari |
116 |
}; |
2 |
26 Feb 07 |
jari |
117 |
|
2 |
26 Feb 07 |
jari |
118 |
Thread t = new Thread(doConstruct); |
2 |
26 Feb 07 |
jari |
119 |
threadVar = new ThreadVar(t); |
2 |
26 Feb 07 |
jari |
120 |
} |
2 |
26 Feb 07 |
jari |
121 |
|
2 |
26 Feb 07 |
jari |
122 |
/** |
2 |
26 Feb 07 |
jari |
* Start the worker thread. |
2 |
26 Feb 07 |
jari |
124 |
*/ |
2 |
26 Feb 07 |
jari |
125 |
public void start() { |
2 |
26 Feb 07 |
jari |
126 |
Thread t = threadVar.get(); |
2 |
26 Feb 07 |
jari |
127 |
if (t != null) { |
2 |
26 Feb 07 |
jari |
128 |
t.start(); |
2 |
26 Feb 07 |
jari |
129 |
} |
2 |
26 Feb 07 |
jari |
130 |
} |
2 |
26 Feb 07 |
jari |
131 |
} |