View Javadoc

1   /*
2    * Created on 2005-maj-07
3    */
4   package com.eviware.soapui.support;
5   
6   import javax.swing.SwingUtilities;
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;  // see getValue(), setValue()
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      protected synchronized Object getValue() { 
41          return value; 
42      }
43  
44      /*** 
45       * Set the value produced by worker thread 
46       */
47      private 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(); // propagate
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                 SwingUtilities.invokeLater(doFinished);
118             }
119         };
120 
121         Thread t = new Thread(doConstruct);
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 }