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