View Javadoc

1   /*
2    * Created on 2005-maj-07
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; // see getValue(), setValue()
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(); // propagate
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 }