jdk/src/share/classes/javax/swing/SwingWorker.java
author ant
Thu, 17 May 2012 21:48:57 +0400
changeset 12661 6cf8b7116579
parent 10316 8d1ca7d93fb2
child 19199 4dfcc94aa1f2
permissions -rw-r--r--
7125044: [macosx] Test failure because Component.transferFocus() works differently in applet and application. Summary: forward port from 7u4 Reviewed-by: art
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
9035
1255eb81cc2f 7033660: Update copyright year to 2011 on any files changed in 2011
ohair
parents: 8151
diff changeset
     2
 * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 5443
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 5443
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 5443
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 5443
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 5443
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
package javax.swing;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
import java.lang.ref.WeakReference;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.security.AccessController;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.security.PrivilegedAction;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.beans.PropertyChangeListener;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.beans.PropertyChangeSupport;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import java.beans.PropertyChangeEvent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
import java.util.List;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
import java.util.concurrent.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
import java.util.concurrent.locks.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
import java.awt.event.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
import javax.swing.SwingUtilities;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
import sun.awt.AppContext;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
import sun.swing.AccumulativeRunnable;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
/**
5443
211dac3ede21 6880336: SwingWorker deadlocks due one thread in the swingworker-pool
art
parents: 2485
diff changeset
    45
 * An abstract class to perform lengthy GUI-interaction tasks in a
211dac3ede21 6880336: SwingWorker deadlocks due one thread in the swingworker-pool
art
parents: 2485
diff changeset
    46
 * background thread. Several background threads can be used to execute such
211dac3ede21 6880336: SwingWorker deadlocks due one thread in the swingworker-pool
art
parents: 2485
diff changeset
    47
 * tasks. However, the exact strategy of choosing a thread for any particular
211dac3ede21 6880336: SwingWorker deadlocks due one thread in the swingworker-pool
art
parents: 2485
diff changeset
    48
 * {@code SwingWorker} is unspecified and should not be relied on.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 * When writing a multi-threaded application using Swing, there are
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
 * two constraints to keep in mind:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
 * (refer to
10316
8d1ca7d93fb2 7075563: Broken link in "javax.swing.SwingWorker"
rupashka
parents: 9035
diff changeset
    53
 * <a href="http://download.oracle.com/javase/tutorial/uiswing/concurrency/index.html">
8d1ca7d93fb2 7075563: Broken link in "javax.swing.SwingWorker"
rupashka
parents: 9035
diff changeset
    54
 *   Concurrency in Swing
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
 * </a> for more details):
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
 * <ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
 *   <li> Time-consuming tasks should not be run on the <i>Event
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
 *        Dispatch Thread</i>. Otherwise the application becomes unresponsive.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
 *   </li>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
 *   <li> Swing components should be accessed  on the <i>Event
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
 *        Dispatch Thread</i> only.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
 *   </li>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
 * </ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
 * These constraints mean that a GUI application with time intensive
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
 * computing needs at least two threads:  1) a thread to perform the lengthy
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
 * task and 2) the <i>Event Dispatch Thread</i> (EDT) for all GUI-related
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
 * activities.  This involves inter-thread communication which can be
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
 * tricky to implement.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
 * {@code SwingWorker} is designed for situations where you need to have a long
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
 * running task run in a background thread and provide updates to the UI
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
 * either when done, or while processing.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
 * Subclasses of {@code SwingWorker} must implement
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
 * the {@link #doInBackground} method to perform the background computation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
 * <b>Workflow</b>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
 * There are three threads involved in the life cycle of a
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
 * {@code SwingWorker} :
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
 * <ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
 * <li>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
 * <i>Current</i> thread: The {@link #execute} method is
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
 * called on this thread. It schedules {@code SwingWorker} for the execution on a
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
 * <i>worker</i>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
 * thread and returns immediately. One can wait for the {@code SwingWorker} to
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
 * complete using the {@link #get get} methods.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
 * <li>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
 * <i>Worker</i> thread: The {@link #doInBackground}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
 * method is called on this thread.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
 * This is where all background activities should happen. To notify
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
 * {@code PropertyChangeListeners} about bound properties changes use the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
 * {@link #firePropertyChange firePropertyChange} and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
 * {@link #getPropertyChangeSupport} methods. By default there are two bound
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
 * properties available: {@code state} and {@code progress}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
 * <li>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
 * <i>Event Dispatch Thread</i>:  All Swing related activities occur
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
 * on this thread. {@code SwingWorker} invokes the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
 * {@link #process process} and {@link #done} methods and notifies
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
 * any {@code PropertyChangeListeners} on this thread.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
 * </ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
 * Often, the <i>Current</i> thread is the <i>Event Dispatch
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
 * Thread</i>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
 * Before the {@code doInBackground} method is invoked on a <i>worker</i> thread,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
 * {@code SwingWorker} notifies any {@code PropertyChangeListeners} about the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
 * {@code state} property change to {@code StateValue.STARTED}.  After the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
 * {@code doInBackground} method is finished the {@code done} method is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
 * executed.  Then {@code SwingWorker} notifies any {@code PropertyChangeListeners}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
 * about the {@code state} property change to {@code StateValue.DONE}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
 * {@code SwingWorker} is only designed to be executed once.  Executing a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
 * {@code SwingWorker} more than once will not result in invoking the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
 * {@code doInBackground} method twice.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
 * <b>Sample Usage</b>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
 * The following example illustrates the simplest use case.  Some
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
 * processing is done in the background and when done you update a Swing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
 * component.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
 * Say we want to find the "Meaning of Life" and display the result in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
 * a {@code JLabel}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
 * <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
 *   final JLabel label;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
 *   class MeaningOfLifeFinder extends SwingWorker&lt;String, Object&gt; {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
 *       {@code @Override}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
 *       public String doInBackground() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
 *           return findTheMeaningOfLife();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
 *       }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
 *       {@code @Override}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
 *       protected void done() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
 *           try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
 *               label.setText(get());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
 *           } catch (Exception ignore) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
 *           }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
 *       }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
 *   }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
 *   (new MeaningOfLifeFinder()).execute();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
 * </pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
 * The next example is useful in situations where you wish to process data
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
 * as it is ready on the <i>Event Dispatch Thread</i>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
 * Now we want to find the first N prime numbers and display the results in a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
 * {@code JTextArea}.  While this is computing, we want to update our
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
 * progress in a {@code JProgressBar}.  Finally, we also want to print
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
 * the prime numbers to {@code System.out}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
 * <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
 * class PrimeNumbersTask extends
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
 *         SwingWorker&lt;List&lt;Integer&gt;, Integer&gt; {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
 *     PrimeNumbersTask(JTextArea textArea, int numbersToFind) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
 *         //initialize
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
 *     }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
 *     {@code @Override}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
 *     public List&lt;Integer&gt; doInBackground() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
 *         while (! enough &amp;&amp; ! isCancelled()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
 *                 number = nextPrimeNumber();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
 *                 publish(number);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
 *                 setProgress(100 * numbers.size() / numbersToFind);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
 *             }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
 *         }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
 *         return numbers;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
 *     }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
 *     {@code @Override}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
 *     protected void process(List&lt;Integer&gt; chunks) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
 *         for (int number : chunks) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
 *             textArea.append(number + &quot;\n&quot;);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
 *         }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
 *     }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
 * }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
 * JTextArea textArea = new JTextArea();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
 * final JProgressBar progressBar = new JProgressBar(0, 100);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
 * PrimeNumbersTask task = new PrimeNumbersTask(textArea, N);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
 * task.addPropertyChangeListener(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
 *     new PropertyChangeListener() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
 *         public  void propertyChange(PropertyChangeEvent evt) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
 *             if (&quot;progress&quot;.equals(evt.getPropertyName())) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
 *                 progressBar.setValue((Integer)evt.getNewValue());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
 *             }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
 *         }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
 *     });
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
 * task.execute();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
 * System.out.println(task.get()); //prints all prime numbers we have got
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
 * </pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
 * Because {@code SwingWorker} implements {@code Runnable}, a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
 * {@code SwingWorker} can be submitted to an
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
 * {@link java.util.concurrent.Executor} for execution.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
 * @author Igor Kushnirskiy
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
 * @param <T> the result type returned by this {@code SwingWorker's}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
 *        {@code doInBackground} and {@code get} methods
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
 * @param <V> the type used for carrying out intermediate results by this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
 *        {@code SwingWorker's} {@code publish} and {@code process} methods
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
 * @since 1.6
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
public abstract class SwingWorker<T, V> implements RunnableFuture<T> {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
     * number of worker threads.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
    private static final int MAX_WORKER_THREADS = 10;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
     * current progress.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
    private volatile int progress;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
     * current state.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
    private volatile StateValue state;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
     * everything is run inside this FutureTask. Also it is used as
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
     * a delegatee for the Future API.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
    private final FutureTask<T> future;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
     * all propertyChangeSupport goes through this.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
    private final PropertyChangeSupport propertyChangeSupport;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
     * handler for {@code process} mehtod.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
    private AccumulativeRunnable<V> doProcess;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
     * handler for progress property change notifications.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
    private AccumulativeRunnable<Integer> doNotifyProgressChange;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
    private final AccumulativeRunnable<Runnable> doSubmit = getDoSubmit();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
     * Values for the {@code state} bound property.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
     * @since 1.6
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
    public enum StateValue {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
         * Initial {@code SwingWorker} state.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
        PENDING,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
         * {@code SwingWorker} is {@code STARTED}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
         * before invoking {@code doInBackground}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
        STARTED,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
         * {@code SwingWorker} is {@code DONE}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
         * after {@code doInBackground} method
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
         * is finished.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
        DONE
1843
267cc4de4221 6776095: Code improvement and warnings removing from swing packages
rupashka
parents: 2
diff changeset
   286
    }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
     * Constructs this {@code SwingWorker}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
    public SwingWorker() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
        Callable<T> callable =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
                new Callable<T>() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
                    public T call() throws Exception {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
                        setState(StateValue.STARTED);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
                        return doInBackground();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
                };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
        future = new FutureTask<T>(callable) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
                       @Override
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
                       protected void done() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
                           doneEDT();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
                           setState(StateValue.DONE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
                       }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
                   };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
       state = StateValue.PENDING;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
       propertyChangeSupport = new SwingWorkerPropertyChangeSupport(this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
       doProcess = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
       doNotifyProgressChange = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
     * Computes a result, or throws an exception if unable to do so.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
     * Note that this method is executed only once.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
     * Note: this method is executed in a background thread.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
     * @return the computed result
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
     * @throws Exception if unable to compute a result
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
    protected abstract T doInBackground() throws Exception ;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
     * Sets this {@code Future} to the result of computation unless
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
     * it has been cancelled.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
    public final void run() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
        future.run();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
     * Sends data chunks to the {@link #process} method. This method is to be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
     * used from inside the {@code doInBackground} method to deliver
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
     * intermediate results
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
     * for processing on the <i>Event Dispatch Thread</i> inside the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
     * {@code process} method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
     * Because the {@code process} method is invoked asynchronously on
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
     * the <i>Event Dispatch Thread</i>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
     * multiple invocations to the {@code publish} method
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
     * might occur before the {@code process} method is executed. For
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
     * performance purposes all these invocations are coalesced into one
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
     * invocation with concatenated arguments.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
     * For example:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
     * <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
     * publish(&quot;1&quot;);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
     * publish(&quot;2&quot;, &quot;3&quot;);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
     * publish(&quot;4&quot;, &quot;5&quot;, &quot;6&quot;);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
     * </pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
     * might result in:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
     * <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
     * process(&quot;1&quot;, &quot;2&quot;, &quot;3&quot;, &quot;4&quot;, &quot;5&quot;, &quot;6&quot;)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
     * </pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
     * <b>Sample Usage</b>. This code snippet loads some tabular data and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
     * updates {@code DefaultTableModel} with it. Note that it safe to mutate
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
     * the tableModel from inside the {@code process} method because it is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
     * invoked on the <i>Event Dispatch Thread</i>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
     * <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
     * class TableSwingWorker extends
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
     *         SwingWorker&lt;DefaultTableModel, Object[]&gt; {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
     *     private final DefaultTableModel tableModel;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
     *     public TableSwingWorker(DefaultTableModel tableModel) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
     *         this.tableModel = tableModel;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
     *     }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
     *     {@code @Override}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
     *     protected DefaultTableModel doInBackground() throws Exception {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
     *         for (Object[] row = loadData();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
     *                  ! isCancelled() &amp;&amp; row != null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
     *                  row = loadData()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
     *             publish((Object[]) row);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
     *         }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
     *         return tableModel;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
     *     }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
     *     {@code @Override}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
     *     protected void process(List&lt;Object[]&gt; chunks) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
     *         for (Object[] row : chunks) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
     *             tableModel.addRow(row);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
     *         }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
     *     }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
     * }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
     * </pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
     * @param chunks intermediate results to process
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
     * @see #process
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
     */
8151
88b01a6d5f51 7006578: Project Coin: Retrofit JDK libraries with @SafeVarargs
darcy
parents: 5506
diff changeset
   407
    @SafeVarargs
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
    protected final void publish(V... chunks) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
        synchronized (this) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
            if (doProcess == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
                doProcess = new AccumulativeRunnable<V>() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
                    @Override
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
                    public void run(List<V> args) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
                        process(args);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
                    @Override
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
                    protected void submit() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
                        doSubmit.add(this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
                };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
        doProcess.add(chunks);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
     * Receives data chunks from the {@code publish} method asynchronously on the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
     * <i>Event Dispatch Thread</i>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
     * Please refer to the {@link #publish} method for more details.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
     * @param chunks intermediate results to process
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
     * @see #publish
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
    protected void process(List<V> chunks) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
     * Executed on the <i>Event Dispatch Thread</i> after the {@code doInBackground}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
     * method is finished. The default
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
     * implementation does nothing. Subclasses may override this method to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
     * perform completion actions on the <i>Event Dispatch Thread</i>. Note
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
     * that you can query status inside the implementation of this method to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
     * determine the result of this task or whether this task has been cancelled.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
     * @see #doInBackground
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
     * @see #isCancelled()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
     * @see #get
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
    protected void done() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
     * Sets the {@code progress} bound property.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
     * The value should be from 0 to 100.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
     * Because {@code PropertyChangeListener}s are notified asynchronously on
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
     * the <i>Event Dispatch Thread</i> multiple invocations to the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
     * {@code setProgress} method might occur before any
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
     * {@code PropertyChangeListeners} are invoked. For performance purposes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
     * all these invocations are coalesced into one invocation with the last
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
     * invocation argument only.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
     * For example, the following invokations:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
     * <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
     * setProgress(1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
     * setProgress(2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
     * setProgress(3);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
     * </pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
     * might result in a single {@code PropertyChangeListener} notification with
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
     * the value {@code 3}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
     * @param progress the progress value to set
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
     * @throws IllegalArgumentException is value not from 0 to 100
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
    protected final void setProgress(int progress) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
        if (progress < 0 || progress > 100) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
            throw new IllegalArgumentException("the value should be from 0 to 100");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
        if (this.progress == progress) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
        int oldProgress = this.progress;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
        this.progress = progress;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
        if (! getPropertyChangeSupport().hasListeners("progress")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
        synchronized (this) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
            if (doNotifyProgressChange == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
                doNotifyProgressChange =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
                    new AccumulativeRunnable<Integer>() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
                        @Override
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
                        public void run(List<Integer> args) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
                            firePropertyChange("progress",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
                               args.get(0),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
                               args.get(args.size() - 1));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
                        @Override
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
                        protected void submit() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
                            doSubmit.add(this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
                    };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
        doNotifyProgressChange.add(oldProgress, progress);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
     * Returns the {@code progress} bound property.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
     * @return the progress bound property.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
    public final int getProgress() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
        return progress;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
     * Schedules this {@code SwingWorker} for execution on a <i>worker</i>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
     * thread. There are a number of <i>worker</i> threads available. In the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
     * event all <i>worker</i> threads are busy handling other
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
     * {@code SwingWorkers} this {@code SwingWorker} is placed in a waiting
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
     * queue.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
     * Note:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
     * {@code SwingWorker} is only designed to be executed once.  Executing a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
     * {@code SwingWorker} more than once will not result in invoking the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
     * {@code doInBackground} method twice.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
    public final void execute() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
        getWorkersExecutorService().execute(this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
    // Future methods START
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
     * {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
    public final boolean cancel(boolean mayInterruptIfRunning) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
        return future.cancel(mayInterruptIfRunning);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
     * {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
    public final boolean isCancelled() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
        return future.isCancelled();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
     * {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
    public final boolean isDone() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
        return future.isDone();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
     * {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
     * Note: calling {@code get} on the <i>Event Dispatch Thread</i> blocks
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
     * <i>all</i> events, including repaints, from being processed until this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
     * {@code SwingWorker} is complete.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
     * When you want the {@code SwingWorker} to block on the <i>Event
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
     * Dispatch Thread</i> we recommend that you use a <i>modal dialog</i>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
     * For example:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
     * <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
     * class SwingWorkerCompletionWaiter extends PropertyChangeListener {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
     *     private JDialog dialog;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
     *     public SwingWorkerCompletionWaiter(JDialog dialog) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
     *         this.dialog = dialog;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
     *     }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
     *     public void propertyChange(PropertyChangeEvent event) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
     *         if (&quot;state&quot;.equals(event.getPropertyName())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
     *                 &amp;&amp; SwingWorker.StateValue.DONE == event.getNewValue()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
     *             dialog.setVisible(false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
     *             dialog.dispose();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
     *         }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
     *     }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
     * }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
     * JDialog dialog = new JDialog(owner, true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
     * swingWorker.addPropertyChangeListener(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
     *     new SwingWorkerCompletionWaiter(dialog));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
     * swingWorker.execute();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
     * //the dialog will be visible until the SwingWorker is done
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
     * dialog.setVisible(true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
     * </pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
    public final T get() throws InterruptedException, ExecutionException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
        return future.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
     * {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
     * Please refer to {@link #get} for more details.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
    public final T get(long timeout, TimeUnit unit) throws InterruptedException,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
            ExecutionException, TimeoutException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
        return future.get(timeout, unit);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
    // Future methods END
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
    // PropertyChangeSupports methods START
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
     * Adds a {@code PropertyChangeListener} to the listener list. The listener
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
     * is registered for all properties. The same listener object may be added
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
     * more than once, and will be called as many times as it is added. If
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
     * {@code listener} is {@code null}, no exception is thrown and no action is taken.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
     * Note: This is merely a convenience wrapper. All work is delegated to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
     * {@code PropertyChangeSupport} from {@link #getPropertyChangeSupport}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
     * @param listener the {@code PropertyChangeListener} to be added
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
    public final void addPropertyChangeListener(PropertyChangeListener listener) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
        getPropertyChangeSupport().addPropertyChangeListener(listener);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
     * Removes a {@code PropertyChangeListener} from the listener list. This
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
     * removes a {@code PropertyChangeListener} that was registered for all
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
     * properties. If {@code listener} was added more than once to the same
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
     * event source, it will be notified one less time after being removed. If
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
     * {@code listener} is {@code null}, or was never added, no exception is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
     * thrown and no action is taken.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
     * Note: This is merely a convenience wrapper. All work is delegated to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
     * {@code PropertyChangeSupport} from {@link #getPropertyChangeSupport}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
     * @param listener the {@code PropertyChangeListener} to be removed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
    public final void removePropertyChangeListener(PropertyChangeListener listener) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
        getPropertyChangeSupport().removePropertyChangeListener(listener);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
     * Reports a bound property update to any registered listeners. No event is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
     * fired if {@code old} and {@code new} are equal and non-null.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
     * This {@code SwingWorker} will be the source for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
     * any generated events.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
     * When called off the <i>Event Dispatch Thread</i>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
     * {@code PropertyChangeListeners} are notified asynchronously on
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
     * the <i>Event Dispatch Thread</i>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
     * Note: This is merely a convenience wrapper. All work is delegated to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
     * {@code PropertyChangeSupport} from {@link #getPropertyChangeSupport}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
     * @param propertyName the programmatic name of the property that was
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
     *        changed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
     * @param oldValue the old value of the property
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
     * @param newValue the new value of the property
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
    public final void firePropertyChange(String propertyName, Object oldValue,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
            Object newValue) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
        getPropertyChangeSupport().firePropertyChange(propertyName,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
            oldValue, newValue);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
     * Returns the {@code PropertyChangeSupport} for this {@code SwingWorker}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
     * This method is used when flexible access to bound properties support is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
     * needed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
     * This {@code SwingWorker} will be the source for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
     * any generated events.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
     * Note: The returned {@code PropertyChangeSupport} notifies any
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
     * {@code PropertyChangeListener}s asynchronously on the <i>Event Dispatch
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
     * Thread</i> in the event that {@code firePropertyChange} or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
     * {@code fireIndexedPropertyChange} are called off the <i>Event Dispatch
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
     * Thread</i>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
     * @return {@code PropertyChangeSupport} for this {@code SwingWorker}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
    public final PropertyChangeSupport getPropertyChangeSupport() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
        return propertyChangeSupport;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
    // PropertyChangeSupports methods END
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
     * Returns the {@code SwingWorker} state bound property.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
     * @return the current state
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
    public final StateValue getState() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
         * DONE is a speacial case
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
         * to keep getState and isDone is sync
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
        if (isDone()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
            return StateValue.DONE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
            return state;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
     * Sets this {@code SwingWorker} state bound property.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
     * @param state the state to set
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
    private void setState(StateValue state) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
        StateValue old = this.state;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
        this.state = state;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
        firePropertyChange("state", old, state);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
     * Invokes {@code done} on the EDT.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
    private void doneEDT() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
        Runnable doDone =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
            new Runnable() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
                public void run() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
                    done();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
            };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
        if (SwingUtilities.isEventDispatchThread()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
            doDone.run();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
            doSubmit.add(doDone);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
     * returns workersExecutorService.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
     * returns the service stored in the appContext or creates it if
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
     * necessary.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
     * @return ExecutorService for the {@code SwingWorkers}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
    private static synchronized ExecutorService getWorkersExecutorService() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
        final AppContext appContext = AppContext.getAppContext();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
        ExecutorService executorService =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
            (ExecutorService) appContext.get(SwingWorker.class);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
        if (executorService == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
            //this creates daemon threads.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
            ThreadFactory threadFactory =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
                new ThreadFactory() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
                    final ThreadFactory defaultFactory =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
                        Executors.defaultThreadFactory();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
                    public Thread newThread(final Runnable r) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
                        Thread thread =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
                            defaultFactory.newThread(r);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
                        thread.setName("SwingWorker-"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
                            + thread.getName());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
                        thread.setDaemon(true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
                        return thread;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
                };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
            executorService =
5443
211dac3ede21 6880336: SwingWorker deadlocks due one thread in the swingworker-pool
art
parents: 2485
diff changeset
   777
                new ThreadPoolExecutor(MAX_WORKER_THREADS, MAX_WORKER_THREADS,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
                                       10L, TimeUnit.MINUTES,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
                                       new LinkedBlockingQueue<Runnable>(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
                                       threadFactory);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
            appContext.put(SwingWorker.class, executorService);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
2485
dc7165666847 6799345: JFC demos threw exception in the Java Console when applets are closed
art
parents: 1843
diff changeset
   783
            // Don't use ShutdownHook here as it's not enough. We should track
dc7165666847 6799345: JFC demos threw exception in the Java Console when applets are closed
art
parents: 1843
diff changeset
   784
            // AppContext disposal instead of JVM shutdown, see 6799345 for details
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
            final ExecutorService es = executorService;
2485
dc7165666847 6799345: JFC demos threw exception in the Java Console when applets are closed
art
parents: 1843
diff changeset
   786
            appContext.addPropertyChangeListener(AppContext.DISPOSED_PROPERTY_NAME,
dc7165666847 6799345: JFC demos threw exception in the Java Console when applets are closed
art
parents: 1843
diff changeset
   787
                new PropertyChangeListener() {
dc7165666847 6799345: JFC demos threw exception in the Java Console when applets are closed
art
parents: 1843
diff changeset
   788
                    @Override
dc7165666847 6799345: JFC demos threw exception in the Java Console when applets are closed
art
parents: 1843
diff changeset
   789
                    public void propertyChange(PropertyChangeEvent pce) {
dc7165666847 6799345: JFC demos threw exception in the Java Console when applets are closed
art
parents: 1843
diff changeset
   790
                        boolean disposed = (Boolean)pce.getNewValue();
dc7165666847 6799345: JFC demos threw exception in the Java Console when applets are closed
art
parents: 1843
diff changeset
   791
                        if (disposed) {
dc7165666847 6799345: JFC demos threw exception in the Java Console when applets are closed
art
parents: 1843
diff changeset
   792
                            final WeakReference<ExecutorService> executorServiceRef =
dc7165666847 6799345: JFC demos threw exception in the Java Console when applets are closed
art
parents: 1843
diff changeset
   793
                                new WeakReference<ExecutorService>(es);
dc7165666847 6799345: JFC demos threw exception in the Java Console when applets are closed
art
parents: 1843
diff changeset
   794
                            final ExecutorService executorService =
dc7165666847 6799345: JFC demos threw exception in the Java Console when applets are closed
art
parents: 1843
diff changeset
   795
                                executorServiceRef.get();
dc7165666847 6799345: JFC demos threw exception in the Java Console when applets are closed
art
parents: 1843
diff changeset
   796
                            if (executorService != null) {
dc7165666847 6799345: JFC demos threw exception in the Java Console when applets are closed
art
parents: 1843
diff changeset
   797
                                AccessController.doPrivileged(
dc7165666847 6799345: JFC demos threw exception in the Java Console when applets are closed
art
parents: 1843
diff changeset
   798
                                    new PrivilegedAction<Void>() {
dc7165666847 6799345: JFC demos threw exception in the Java Console when applets are closed
art
parents: 1843
diff changeset
   799
                                        public Void run() {
dc7165666847 6799345: JFC demos threw exception in the Java Console when applets are closed
art
parents: 1843
diff changeset
   800
                                            executorService.shutdown();
dc7165666847 6799345: JFC demos threw exception in the Java Console when applets are closed
art
parents: 1843
diff changeset
   801
                                            return null;
dc7165666847 6799345: JFC demos threw exception in the Java Console when applets are closed
art
parents: 1843
diff changeset
   802
                                        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
                                    }
2485
dc7165666847 6799345: JFC demos threw exception in the Java Console when applets are closed
art
parents: 1843
diff changeset
   804
                                );
dc7165666847 6799345: JFC demos threw exception in the Java Console when applets are closed
art
parents: 1843
diff changeset
   805
                            }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
                    }
2485
dc7165666847 6799345: JFC demos threw exception in the Java Console when applets are closed
art
parents: 1843
diff changeset
   808
                }
dc7165666847 6799345: JFC demos threw exception in the Java Console when applets are closed
art
parents: 1843
diff changeset
   809
            );
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
        return executorService;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
    private static final Object DO_SUBMIT_KEY = new StringBuilder("doSubmit");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
    private static AccumulativeRunnable<Runnable> getDoSubmit() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
        synchronized (DO_SUBMIT_KEY) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
            final AppContext appContext = AppContext.getAppContext();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
            Object doSubmit = appContext.get(DO_SUBMIT_KEY);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
            if (doSubmit == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
                doSubmit = new DoSubmitAccumulativeRunnable();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
                appContext.put(DO_SUBMIT_KEY, doSubmit);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
            return (AccumulativeRunnable<Runnable>) doSubmit;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
    private static class DoSubmitAccumulativeRunnable
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
          extends AccumulativeRunnable<Runnable> implements ActionListener {
1843
267cc4de4221 6776095: Code improvement and warnings removing from swing packages
rupashka
parents: 2
diff changeset
   828
        private final static int DELAY = 1000 / 30;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
        @Override
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
        protected void run(List<Runnable> args) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
            for (Runnable runnable : args) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   832
                runnable.run();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
        @Override
90ce3da70b43 Initial load
duke
parents:
diff changeset
   836
        protected void submit() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
            Timer timer = new Timer(DELAY, this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
            timer.setRepeats(false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
            timer.start();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
        public void actionPerformed(ActionEvent event) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
            run();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
    private class SwingWorkerPropertyChangeSupport
90ce3da70b43 Initial load
duke
parents:
diff changeset
   847
            extends PropertyChangeSupport {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
        SwingWorkerPropertyChangeSupport(Object source) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   849
            super(source);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
        @Override
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
        public void firePropertyChange(final PropertyChangeEvent evt) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
            if (SwingUtilities.isEventDispatchThread()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
                super.firePropertyChange(evt);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
                doSubmit.add(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   857
                    new Runnable() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   858
                        public void run() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
                            SwingWorkerPropertyChangeSupport.this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
                                .firePropertyChange(evt);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
                    });
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   865
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   866
}