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