001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.sql.framework.ui;
043:
044: import javax.swing.SwingUtilities;
045:
046: /**
047: * This is the 3rd version of SwingWorker (also known as SwingWorker 3), an abstract class
048: * that you subclass to perform GUI-related work in a dedicated thread. For instructions
049: * on and examples of using this class, see: <br>
050: * http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html <br>
051: * Note that the API changed slightly in the 3rd version: You must now invoke start() on
052: * the SwingWorker after creating it.
053: */
054: public abstract class SwingWorker {
055: private Object value; // see getValue(), setValue()
056:
057: /**
058: * Class to maintain reference to current worker thread under separate synchronization
059: * control.
060: */
061: private static class ThreadVar {
062: private Thread thread;
063:
064: ThreadVar(Thread t) {
065: thread = t;
066: }
067:
068: synchronized Thread get() {
069: return thread;
070: }
071:
072: synchronized void clear() {
073: thread = null;
074: }
075: }
076:
077: private ThreadVar threadVar;
078:
079: /**
080: * Get the value produced by the worker thread, or null if it hasn't been constructed
081: * yet.
082: */
083: protected synchronized Object getValue() {
084: return value;
085: }
086:
087: /**
088: * Set the value produced by worker thread
089: */
090: private synchronized void setValue(Object x) {
091: value = x;
092: }
093:
094: /**
095: * Compute the value to be returned by the <code>get</code> method.
096: */
097: public abstract Object construct();
098:
099: /**
100: * Called on the event dispatching thread (not on the worker thread) after the
101: * <code>construct</code> method has returned.
102: */
103: public void finished() {
104: }
105:
106: /**
107: * A new method that interrupts the worker thread. Call this method to force the
108: * worker to stop what it's doing.
109: */
110: public void interrupt() {
111: Thread t = threadVar.get();
112: if (t != null) {
113: t.interrupt();
114: }
115: threadVar.clear();
116: }
117:
118: /**
119: * Return the value created by the <code>construct</code> method. Returns null if
120: * either the constructing thread or the current thread was interrupted before a value
121: * was produced.
122: *
123: * @return the value created by the <code>construct</code> method
124: */
125: public Object get() {
126: while (true) {
127: Thread t = threadVar.get();
128: if (t == null) {
129: return getValue();
130: }
131: try {
132: t.join();
133: } catch (InterruptedException e) {
134: Thread.currentThread().interrupt(); // propagate
135: return null;
136: }
137: }
138: }
139:
140: /**
141: * Start a thread that will call the <code>construct</code> method and then exit.
142: */
143: public SwingWorker() {
144: final Runnable doFinished = new Runnable() {
145: public void run() {
146: finished();
147: }
148: };
149:
150: Runnable doConstruct = new Runnable() {
151: public void run() {
152: try {
153: setValue(construct());
154: } finally {
155: threadVar.clear();
156: }
157:
158: SwingUtilities.invokeLater(doFinished);
159: }
160: };
161:
162: Thread t = new Thread(doConstruct);
163: threadVar = new ThreadVar(t);
164: }
165:
166: /**
167: * Start the worker thread.
168: */
169: public void start() {
170: Thread t = threadVar.get();
171: if (t != null) {
172: t.start();
173: }
174: }
175: }
|