Spec-Zone .ru
спецификации, руководства, описания, API
001/*
002 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation.  Oracle designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Oracle in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
022 * or visit www.oracle.com if you need additional information or have any
023 * questions.
024 */
025
026package javafx.concurrent;
027
028import java.util.concurrent.Callable;
029import java.util.concurrent.FutureTask;
030import java.util.concurrent.atomic.AtomicReference;
031import javafx.application.Platform;
032import javafx.beans.property.*;
033import javafx.event.*;
034import static javafx.concurrent.WorkerStateEvent.*;
035
036/**
037 * <p>
038 *     A fully observable implementation of a {@link FutureTask}. Tasks exposes
039 *     additional state and observable properties useful for programming asynchronous
040 *     tasks in JavaFX, as defined in the {@link Worker} interface. An implementation
041 *     of Task must override the {@link javafx.concurrent.Task#call()} method. This method
042 *     is invoked on the background thread. Any state which is used in this method
043 *     must be safe to read and write from a background thread. For example, manipulating
044 *     a live scene graph from this method is unsafe and will result in runtime
045 *     exceptions.
046 * </p>
047 * <p>
048 *     Tasks are flexible and extremely useful for the encapsulation of "work". Because
049 *     {@link Service} is designed to execute a Task, any Tasks defined by the application
050 *     or library code can easily be used with a Service. Likewise, since Task extends
051 *     from FutureTask, it is very easy and natural to use a Task with the java concurrency
052 *     {@link java.util.concurrent.Executor} API. Since a Task is Runnable, you
053 *     can also call it directly (by invoking the {@link javafx.concurrent.Task#run()} method)
054 *     from another background thread. This allows for composition of work, or pass it to
055 *     a new Thread constructed and executed manually. Finally, since you can
056 *     manually create a new Thread, passing it a Runnable, it is possible to use
057 *     the following idiom:
058 *     <pre><code>
059 *         Thread th = new Thread(task);
060 *         th.setDaemon(true);
061 *         th.start();
062 *     </code></pre>
063 *     Note that this code sets the daemon flag of the Thread to true. If you
064 *     want a background thread to prevent the VM from existing after the last
065 *     stage is closed, then you would want daemon to be false. However, if
066 *     you want the background threads to simply terminate after all the
067 *     stages are closed, then you must set daemon to true.
068 * </p>
069 * <p>
070 *     Although {@link java.util.concurrent.ExecutorService} defines several methods which
071 *     take a Runnable, you should generally limit yourself to using the <code>execute</code>
072 *     method inherited from {@link java.util.concurrent.Executor}.
073 * </p>
074 * <p>
075 *     As with FutureTask, a Task is a one-shot class and cannot be reused. See {@link Service}
076 *     for a reusable {@link Worker}.
077 * </p>
078 * <p>
079 *     Because the Task is designed for use with JavaFX GUI applications, it ensures
080 *     that every change to its public properties, as well as change notifications
081 *     for state, errors, and for event handlers, all occur on the main JavaFX application
082 *     thread. Accessing these properties from a background thread (including the
083 *     {@link #call()} method) will result in runtime exceptions being raised.
084 * </p>
085 * <p>
086 *     It is <strong>strongly encouraged</strong> that all Tasks be initialized with
087 *     immutable state upon which the Task will operate. This should be done by providing
088 *     a Task constructor which takes the parameters necessary for execution of the Task.
089 *     Immutable state makes it easy and safe to use from any thread and ensures
090 *     correctness in the presence of multiple threads.
091 * </p>
092 * <p>
093 *     In Java there is no reliable way to "kill" a thread in process. However,
094 *     when <code>cancel</code> is called on a Task, it is important that
095 *     the Task stop processing. A "run-away" Task might continue processing
096 *     and updating the message, text, and progress properties even after the
097 *     Task has been cancelled! In Java, cancelling a Task is a cooperative
098 *     endeavor. The user of the Task will request that it be cancelled, and
099 *     the author of the Task must check whether is has been cancelled within
100 *     the body of the <code>call</code> method. There are two ways this can
101 *     be done. First, the Task author may check the isCancelled method,
102 *     inherited from <code>FutureTask</code>, to see whether the Task has
103 *     been cancelled. Second, if the Task implementation makes use of any
104 *     blocking calls (such as NIO InterruptibleChannels or Thread.sleep) and
105 *     the task is cancelled while in such a blocking call, an
106 *     InterruptedException is thrown. Task implementations which have blocking
107 *     calls should recognize that an interrupted thread may be the signal for
108 *     a cancelled task and should double check the isCancelled method to ensure
109 *     that the InterruptedException was thrown due to the cancellation of the
110 *     Task.
111 * </p>
112 * <h2>Examples</h2>
113 * <p>
114 *     The following set of examples demonstrate some of the most common uses of
115 *     Tasks.
116 * </p>
117 *
118 * <h3>A Simple Loop</h3>
119 *
120 * <p>
121 *     The first example is a simple loop that does nothing particularly useful,
122 *     but demonstrates the fundamental aspects of writing a Task correctly. This
123 *     example will simply loop and print to standard out on each loop iteration.
124 *     When it completes, it returns the number of times it iterated.
125 * </p>
126 *
127 * <pre><code>
128 *     Task&lt;Integer&gt; task = new Task&lt;Integer&gt;() {
129 *         &#64;Override protected Integer call() throws Exception {
130 *             int iterations;
131 *             for (iterations = 0; iterations &lt; 100000; iterations++) {
132 *                 if (isCancelled()) {
133 *                     break;
134 *                 }
135 *                 System.out.println("Iteration " + iterations);
136 *             }
137 *             return iterations;
138 *         }
139 *     };
140 * </code></pre>
141 *
142 * <p>
143 *     First, we define what type of value is returned from this Task. In this
144 *     case, we want to return the number of times we iterated, so we will
145 *     specify the Task to be of type Integer by using generics. Then, within
146 *     the implementation of the <code>call</code> method, we iterate from
147 *     0 to 100000. On each iteration, we check to see whether this Task has
148 *     been cancelled. If it has been, then we break out of the loop and return
149 *     the number of times we iterated. Otherwise a message is printed to
150 *     the console and the iteration count increased and we continue looping.
151 * </p>
152 *
153 * <p>
154 *     Checking for isCancelled() in the loop body is critical, otherwise the
155 *     developer may cancel the task, but the task will continue running
156 *     and updating both the progress and returning the incorrect result
157 *     from the end of the <code>call</code> method. A correct implementation
158 *     of a Task will always check for cancellation.
159 * </p>
160 *
161 * <h3>A Simple Loop With Progress Notification</h3>
162 *
163 * <p>
164 *     Similar to the previous example, except this time we will modify the
165 *     progress of the Task in each iteration. Note that we have a choice
166 *     to make in the case of cancellation. Do we want to set the progress back
167 *     to -1 (indeterminate) when the Task is cancelled, or do we want to leave
168 *     the progress where it was at? In this case, lets leave the progress alone
169 *     and only update the message on cancellation, though updating the
170 *     progress after cancellation is a perfectly valid choice.
171 * </p>
172 *
173 * <pre><code>
174 *     Task&lt;Integer&gt; task = new Task&lt;Integer&gt;() {
175 *         &#64;Override protected Integer call() throws Exception {
176 *             int iterations;
177 *             for (iterations = 0; iterations &lt; 10000000; iterations++) {
178 *                 if (isCancelled()) {
179 *                     updateMessage("Cancelled");
180 *                     break;
181 *                 }
182 *                 updateMessage("Iteration " + iterations);
183 *                 updateProgress(iterations, 10000000);
184 *             }
185 *             return iterations;
186 *         }
187 *     };
188 * </code></pre>
189 *
190 * <p>
191 *     As before, within the for loop we check whether the Task has been
192 *     cancelled. If it has been cancelled, we will update the Task's
193 *     message to indicate that it has been cancelled, and then break as
194 *     before. If the Task has not been cancelled, then we will update its
195 *     message to indicate the current iteration and then update the
196 *     progress to indicate the current progress.
197 * </p>
198 *
199 * <h3>A Simple Loop With Progress Notification And Blocking Calls</h3>
200 *
201 * <p>
202 *     This example adds to the previous examples a blocking call. Because a
203 *     blocking call may thrown an InterruptedException, and because an
204 *     InterruptedException may occur as a result of the Task being cancelled,
205 *     we need to be sure to handle the InterruptedException and check on the
206 *     cancel state.
207 * </p>
208 *
209 * <pre><code>
210 *     Task&lt;Integer&gt; task = new Task&lt;Integer&gt;() {
211 *         &#64;Override protected Integer call() throws Exception {
212 *             int iterations;
213 *             for (iterations = 0; iterations &lt; 1000; iterations++) {
214 *                 if (isCancelled()) {
215 *                     updateMessage("Cancelled");
216 *                     break;
217 *                 }
218 *                 updateMessage("Iteration " + iterations);
219 *                 updateProgress(iterations, 1000);
220 *
221 *                 // Now block the thread for a short time, but be sure
222 *                 // to check the interrupted exception for cancellation!
223 *                 try {
224 *                     Thread.sleep(100);
225 *                 } catch (InterruptedException interrupted) {
226 *                     if (isCancelled()) {
227 *                         updateMessage("Cancelled");
228 *                         break;
229 *                     }
230 *                 }
231 *             }
232 *             return iterations;
233 *         }
234 *     };
235 * </code></pre>
236 *
237 * <p>
238 *     Here we have added to the body of the loop a <code>Thread.sleep</code>
239 *     call. Since this is a blocking call, I have to handle the potential
240 *     InterruptedException. Within the catch block, I will check whether
241 *     the Task has been cancelled, and if so, update the message accordingly
242 *     and break out of the loop.
243 * </p>
244 *
245 * <h3>A Task Which Takes Parameters</h3>
246 *
247 * <p>
248 *     Most Tasks require some parameters in order to do useful work. For
249 *     example, a DeleteRecordTask needs the object or primary key to delete
250 *     from the database. A ReadFileTask needs the URI of the file to be read.
251 *     Because Tasks operate on a background thread, care must be taken to
252 *     make sure the body of the <code>call</code> method does not read or
253 *     modify any shared state. There are two techniques most useful for
254 *     doing this: using final variables, and passing variables to a Task
255 *     during construction.
256 * </p>
257 *
258 * <p>
259 *     When using a Task as an anonymous class, the most natural way to pass
260 *     parameters to the Task is by using final variables. In this example,
261 *     we pass to the Task the total number of times the Task should iterate.
262 * </p>
263 *
264 * <pre><code>
265 *     final int totalIterations = 9000000;
266 *     Task&lt;Integer&gt; task = new Task&lt;Integer&gt;() {
267 *         &#64;Override protected Integer call() throws Exception {
268 *             int iterations;
269 *             for (iterations = 0; iterations &lt; totalIterations; iterations++) {
270 *                 if (isCancelled()) {
271 *                     updateMessage("Cancelled");
272 *                     break;
273 *                 }
274 *                 updateMessage("Iteration " + iterations);
275 *                 updateProgress(iterations, totalIterations);
276 *             }
277 *             return iterations;
278 *         }
279 *     };
280 * </code></pre>
281 *
282 * <p>
283 *     Since <code>totalIterations</code> is final, the <code>call</code>
284 *     method can safely read it and refer to it from a background thread.
285 * </p>
286 *
287 * <p>
288 *     When writing Task libraries (as opposed to specific-use implementations),
289 *     we need to use a different technique. In this case, I will create an
290 *     IteratingTask which performs the same work as above. This time, since
291 *     the IteratingTask is defined in its own file, it will need to have
292 *     parameters passed to it in its constructor. These parameters are
293 *     assigned to final variables.
294 * </p>
295 *
296 * <pre><code>
297 *     public class IteratingTask extends Task&lt;Integer&gt; {
298 *         private final int totalIterations;
299 *
300 *         public IteratingTask(int totalIterations) {
301 *             this.totalIterations = totalIterations;
302 *         }
303 *
304 *         &#64;Override protected Integer call() throws Exception {
305 *             int iterations = 0;
306 *             for (iterations = 0; iterations &lt; totalIterations; iterations++) {
307 *                 if (isCancelled()) {
308 *                     updateMessage("Cancelled");
309 *                     break;
310 *                 }
311 *                 updateMessage("Iteration " + iterations);
312 *                 updateProgress(iterations, totalIterations);
313 *             }
314 *             return iterations;
315 *         }
316 *     }
317 * </code></pre>
318 *
319 * <p>And then when used:</p>
320 *
321 * <pre><code>
322 *     IteratingTask task = new IteratingTask(8000000);
323 * </code></pre>
324 *
325 * <p>In this way, parameters are passed to the IteratingTask in a safe
326 * manner, and again, are final. Thus, the <code>call</code> method can
327 * safely read this state from a background thread.</p>
328 *
329 * <p>WARNING: Do not pass mutable state to a Task and then operate on it
330 * from a background thread. Doing so may introduce race conditions. In
331 * particular, suppose you had a SaveCustomerTask which took a Customer
332 * in its constructor. Although the SaveCustomerTask may have a final
333 * reference to the Customer, if the Customer object is mutable, then it
334 * is possible that both the SaveCustomerTask and some other application code
335 * will be reading or modifying the state of the Customer from different
336 * threads. Be very careful in such cases, that while a mutable object such
337 * as this Customer is being used from a background thread, that it is
338 * not being used also from another thread. In particular, if the background
339 * thread is reading data from the database and updating the Customer object,
340 * and the Customer object is bound to scene graph nodes (such as UI
341 * controls), then there could be a violation of threading rules! For such
342 * cases, modify the Customer object from the FX Application Thread rather
343 * than from the background thread.</p>
344 *
345 * <pre><code>
346 *     public class UpdateCustomerTask extends Task&lt;Customer&gt; {
347 *         private final Customer customer;
348 *
349 *         public UpdateCustomerTask(Customer customer) {
350 *             this.customer = customer;
351 *         }
352 *
353 *         &#64;Override protected Customer call() throws Exception {
354 *             // pseudo-code:
355 *             //   query the database
356 *             //   read the values
357 *
358 *             // Now update the customer
359 *             Platform.runLater(new Runnable() {
360 *                 &#64;Override public void run() {
361 *                     customer.setF setFirstName(rs.getString("FirstName"));
362 *                     // etc
363 *                 }
364 *             });
365 *
366 *             return customer;
367 *         }
368 *     }
369 * </code></pre>
370 *
371 * <h3>A Task Which Returns No Value</h3>
372 *
373 * <p>
374 *     Many, if not most, Tasks should return a value upon completion. For
375 *     CRUD Tasks, one would expect that a "Create" Task would return the newly
376 *     created object or primary key, a "Read" Task would return the read
377 *     object, an "Update" task would return the number of records updated,
378 *     and a "Delete" task would return the number of records deleted.
379 * </p>
380 *
381 * <p>
382 *     However sometimes there just isn't anything truly useful to return.
383 *     For example, I might have a Task which writes to a file. Task has built
384 *     into it a mechanism for indicating whether it has succeeded or failed
385 *     along with the number of bytes written (the progress), and thus there is
386 *     nothing really for me to return. In such a case, you can use the Void
387 *     type. This is a special type in the Java language which can only be
388 *     assigned the value of <code>null</code>. You would use it as follows:
389 * </p>
390 *
391 * <pre><code>
392 *     final String filePath = "/foo.txt";
393 *     final String contents = "Some contents";
394 *     Task&lt;Void&gt; task = new Task&lt;Void&gt;() {
395 *         &#64;Override protected Void call() throws Exception {
396 *             File file = new File(filePath);
397 *             FileOutputStream out = new FileOutputStream(file);
398 *             // ... and other code to write the contents ...
399 *
400 *             // Return null at the end of a Task of type Void
401 *             return null;
402 *         }
403 *     };
404 * </code></pre>
405 *
406 * <h3>A Task Which Returns An ObservableList</h3>
407 *
408 * <p>Because the ListView, TableView, and other UI controls and scene graph
409 * nodes make use of ObservableList, it is common to want to create and return
410 * an ObservableList from a Task. When you do not care to display intermediate
411 * values, the easiest way to correctly write such a Task is simply to
412 * construct an ObservableList within the <code>call</code> method, and then
413 * return it at the conclusion of the Task.</p>
414 *
415 * <pre><code>
416 *     Task&lt;ObservableList&lt;Rectangle&gt;&gt; task = new Task&lt;ObservableList&lt;Rectangle&gt;&gt;() {
417 *         &#64;Override protected ObservableList&lt;Rectangle&gt; call() throws Exception {
418 *             updateMessage("Creating Rectangles");
419 *             ObservableList&lt;Rectangle&gt; results = FXCollections.observableArrayList();
420 *             for (int i=0; i<100; i++) {
421 *                 if (isCancelled()) break;
422 *                 Rectangle r = new Rectangle(10, 10);
423 *                 r.setX(10 * i);
424 *                 results.add(r);
425 *                 updateProgress(i, 100);
426 *             }
427 *             return results;
428 *         }
429 *     };
430 * </code></pre>
431 *
432 * <p>In the above example, we are going to create 100 rectangles and return
433 * them from this task. An ObservableList is created within the
434 * <code>call</code> method, populated, and then returned.</p>
435 *
436 * <h3>A Task Which Returns Partial Results</h3>
437 *
438 * <p>Sometimes you want to create a Task which will return partial results.
439 * Perhaps you are building a complex scene graph and want to show the
440 * scene graph as it is being constructed. Or perhaps you are reading a large
441 * amount of data over the network and want to display the entries in a
442 * TableView as the data is arriving. In such cases, there is some shared state
443 * available both to the FX Application Thread and the background thread.
444 * Great care must be taken to <strong>never update shared state from any
445 * thread other than the FX Application Thread</strong>.</p>
446 *
447 * <p>The easiest way to do this is to take advantage of the {@link #updateValue(Object)} method.
448 * This method may be called repeatedly from the background thread. Updates are coalesced to
449 * prevent saturation of the FX event queue. This means you can call it as frequently as
450 * you like from the background thread but only the most recent set is ultimately set.</p>
451 *
452 * <pre><code>
453 *     Task&lt;Long&gt; task = new Task&lt;Long&gt;() {
454 *         &#64;Override protected Long call() throws Exception {
455 *             long a=0;
456 *             long b=1;
457 *             for (long i = 0; i &lt; Long.MAX_VALUE; i++){
458 *                 updateValue(a);
459 *                 a += b;
460 *                 b = a - b;
461 *             }
462 *             return a;
463 *         }
464 *     };
465 * </code></pre>
466 *
467 * <p>Another way to do this is to expose a new property on the Task
468 * which will represent the partial result. Then make sure to use
469 * <code>Platform.runLater</code> when updating the partial result.</p>
470 *
471 * <pre><code>
472 *     Task&lt;Long&gt; task = new Task&lt;Long&gt;() {
473 *         &#64;Override protected Long call() throws Exception {
474 *             long a=0;
475 *             long b=1;
476 *             for (long i = 0; i &lt; Long.MAX_VALUE; i++){
477 *                 final long v = a;
478 *                 Platform.runLater(new Runnable() {
479 *                     &#64;Override public void run() {
480 *                         updateValue(v);
481 *                     }
482 *                 }
483 *                 a += b;
484 *                 b = a - b;
485 *             }
486 *             return a;
487 *         }
488 *     };
489 * </code></pre>
490 *
491 * <p>Suppose instead of updating a single value, you want to populate an ObservableList
492 * with results as they are obtained. One approach is to expose a new property on the Task
493 * which will represent the partial result. Then make sure to use
494 * <code>Platform.runLater</code> when adding new items to the partial
495 * result.</p>
496 *
497 * <pre><code>
498 *     public class PartialResultsTask extends Task&lt;ObservableList&lt;Rectangle&gt;&gt; {
499 *         // Uses Java 7 diamond operator
500 *         private ReadOnlyObjectWrapper<ObservableList<Rectangle>> partialResults =
501 *                 new ReadOnlyObjectWrapper<>(this, "partialResults",
502 *                         FXCollections.observableArrayList(new ArrayList<Rectangle>()));
503 *
504 *         public final ObservableList<Rectangle> getPartialResults() { return partialResults.get(); }
505 *         public final ReadOnlyObjectProperty<ObservableList<Rectangle>> partialResultsProperty() {
506 *             return partialResults.getReadOnlyProperty();
507 *         }
508 *
509 *         &#64;Override protected ObservableList<Rectangle> call() throws Exception {
510 *             updateMessage("Creating Rectangles...");
511 *             for (int i=0; i<100; i++) {
512 *                 if (isCancelled()) break;
513 *                 final Rectangle r = new Rectangle(10, 10);
514 *                 r.setX(10 * i);
515 *                 Platform.runLater(new Runnable() {
516 *                     &#64;Override public void run() {
517 *                         partialResults.get().add(r);
518 *                     }
519 *                 });
520 *                 updateProgress(i, 100);
521 *             }
522 *             return partialResults.get();
523 *         }
524 *     }
525 * </code></pre>
526 *
527 * <h3>A Task Which Modifies The Scene Graph</h3>
528 *
529 * <p>Generally, Tasks should not interact directly with the UI. Doing so
530 * creates a tight coupling between a specific Task implementation and a
531 * specific part of your UI. However, when you do want to create such a
532 * coupling, you must ensure that you use <code>Platform.runLater</code>
533 * so that any modifications of the scene graph occur on the
534 * FX Application Thread.</p>
535 *
536 * <pre><code>
537 *     final Group group = new Group();
538 *     Task&lt;Void&gt; task = new Task&lt;Void&gt;() {
539 *         &#64;Override protected Void call() throws Exception {
540 *             for (int i=0; i<100; i++) {
541 *                 if (isCancelled()) break;
542 *                 final Rectangle r = new Rectangle(10, 10);
543 *                 r.setX(10 * i);
544 *                 Platform.runLater(new Runnable() {
545 *                     &#64;Override public void run() {
546 *                         group.getChildren().add(r);
547 *                     }
548 *                 });
549 *             }
550 *             return null;
551 *         }
552 *     };
553 * </code></pre>
554 *
555 * <h3>Reacting To State Changes Generically</h3>
556 *
557 * <p>Sometimes you may want to write a Task which updates its progress,
558 * message, text, or in some other way reacts whenever a state change
559 * happens on the Task. For example, you may want to change the status
560 * message on the Task on Failure, Success, Running, or Cancelled state changes.
561 * </p>
562 * <pre><code>
563 *     Task&lt;Integer&gt; task = new Task&lt;Integer&gt;() {
564 *         &#64;Override protected Integer call() throws Exception {
565 *             int iterations = 0;
566 *             for (iterations = 0; iterations &lt; 100000; iterations++) {
567 *                 if (isCancelled()) {
568 *                     break;
569 *                 }
570 *                 System.out.println("Iteration " + iterations);
571 *             }
572 *             return iterations;
573 *         }
574 *
575 *         &#64;Override protected void succeeded() {
576 *             super.succeeded();
577 *             updateMessage("Done!");
578 *         }
579 *
580 *         &#64;Override protected void cancelled() {
581 *             super.cancelled();
582 *             updateMessage("Cancelled!");
583 *         }
584 *
585 *         &#64;Override protected void failed() {
586 *             super.failed();
587 *             updateMessage("Failed!");
588 *         }
589 *     };
590 * </code></pre>
591 */
592public abstract class Task<V> extends FutureTask<V> implements Worker<V>, EventTarget {
593    /**
594     * Used to send workDone updates in a thread-safe manner from the subclass
595     * to the FX application thread and workDone related properties. AtomicReference
596     * is used so as to coalesce updates such that we don't flood the event queue.
597     */
598    private AtomicReference<ProgressUpdate> progressUpdate = new AtomicReference<>();
599
600    /**
601     * Used to send message updates in a thread-safe manner from the subclass
602     * to the FX application thread. AtomicReference is used so as to coalesce
603     * updates such that we don't flood the event queue.
604     */
605    private AtomicReference<String> messageUpdate = new AtomicReference<>();
606
607    /**
608     * Used to send title updates in a thread-safe manner from the subclass
609     * to the FX application thread. AtomicReference is used so as to coalesce
610     * updates such that we don't flood the event queue.
611     */
612    private AtomicReference<String> titleUpdate = new AtomicReference<>();
613
614    /**
615     * Used to send value updates in a thread-safe manner from the subclass
616     * to the FX application thread. AtomicReference is used so as to coalesce
617     * updates such that we don't flood the event queue.
618     */
619    private AtomicReference<V> valueUpdate = new AtomicReference<>();
620
621    /**
622     * Creates a new Task.
623     */
624    public Task() {
625        this(new TaskCallable<V>());
626    }
627
628    /**
629     * This bit of construction trickery is necessary because otherwise there is
630     * no way for the main constructor to both create the callable and maintain
631     * a reference to it, which is necessary because an anonymous callable construction
632     * cannot reference the implicit "this". We leverage an internal Callable
633     * so that all the pre-built semantics around cancel and so forth are
634     * handled correctly.
635     *
636     * @param callableAdapter non-null implementation of the
637     *                        TaskCallable adapter
638     */
639    private Task(final TaskCallable<V> callableAdapter) {
640        super(callableAdapter);
641        callableAdapter.task = this;
642    }
643
644    /**
645     * Invoked when the Task is executed, the call method must be overridden and
646     * implemented by subclasses. The call method actually performs the
647     * background thread logic. Only the updateProgress, updateMessage, and
648     * updateTitle methods of Task may be called from code within this method.
649     * Any other interaction with the Task from the background thread will result
650     * in runtime exceptions.
651     *
652     * @return The result of the background work, if any.
653     * @throws Exception an unhandled exception which occurred during the
654     *         background operation
655     */
656    protected abstract V call() throws Exception;
657
658    private ObjectProperty<State> state = new SimpleObjectProperty<State>(this, "state", State.READY);
659    final void setState(State value) { // package access for the Service
660        checkThread();
661        final State s = getState();
662        if (s != State.CANCELLED) {
663            this.state.set(value);
664            // Make sure the running flag is set
665            setRunning(value == State.SCHEDULED || value == State.RUNNING);
666
667            // Invoke the event handlers, and then call the protected methods.
668            switch (state.get()) {
669                case CANCELLED:
670                    fireEvent(new WorkerStateEvent(this, WORKER_STATE_CANCELLED));
671                    cancelled();
672                    break;
673                case FAILED:
674                    fireEvent(new WorkerStateEvent(this, WORKER_STATE_FAILED));
675                    failed();
676                    break;
677                case READY:
678                    // This even can never meaningfully occur, because the
679                    // Task begins life as ready and can never go back to it!
680                    break;
681                case RUNNING:
682                    fireEvent(new WorkerStateEvent(this, WORKER_STATE_RUNNING));
683                    running();
684                    break;
685                case SCHEDULED:
686                    fireEvent(new WorkerStateEvent(this, WORKER_STATE_SCHEDULED));
687                    scheduled();
688                    break;
689                case SUCCEEDED:
690                    fireEvent(new WorkerStateEvent(this, WORKER_STATE_SUCCEEDED));
691                    succeeded();
692                    break;
693                default: throw new AssertionError("Should be unreachable");
694            }
695        }
696    }
697    @Override public final State getState() { checkThread(); return state.get(); }
698    @Override public final ReadOnlyObjectProperty<State> stateProperty() { checkThread(); return state; }
699
700    /**
701     * The onSchedule event handler is called whenever the Task state
702     * transitions to the SCHEDULED state.
703     *
704     * @return the onScheduled event handler property
705     */
706    public final ObjectProperty<EventHandler<WorkerStateEvent>> onScheduledProperty() {
707        return getEventHelper().onScheduledProperty();
708    }
709
710    /**
711     * The onSchedule event handler is called whenever the Task state
712     * transitions to the SCHEDULED state.
713     *
714     * @return the onScheduled event handler, if any
715     */
716    public final EventHandler<WorkerStateEvent> getOnScheduled() {
717        return eventHelper == null ? null : eventHelper.getOnScheduled();
718    }
719
720    /**
721     * The onSchedule event handler is called whenever the Task state
722     * transitions to the SCHEDULED state.
723     *
724     * @param value the event handler, can be null to clear it
725     */
726    public final void setOnScheduled(EventHandler<WorkerStateEvent> value) {
727        getEventHelper().setOnScheduled(value);
728    }
729
730    /**
731     * A protected convenience method for subclasses, called whenever the
732     * state of the Task has transitioned to the SCHEDULED state.
733     * This method is invoked on the FX Application Thread after any listeners
734     * of the state property and after the Task has been fully transitioned to
735     * the new state.
736     */
737    protected void scheduled() { }
738
739    /**
740     * The onRunning event handler is called whenever the Task state
741     * transitions to the RUNNING state.
742     *
743     * @return the onRunning event handler property
744     */
745    public final ObjectProperty<EventHandler<WorkerStateEvent>> onRunningProperty() {
746        return getEventHelper().onRunningProperty();
747    }
748
749    /**
750     * The onRunning event handler is called whenever the Task state
751     * transitions to the RUNNING state.
752     *
753     * @return the onRunning event handler, if any
754     */
755    public final EventHandler<WorkerStateEvent> getOnRunning() {
756        return eventHelper == null ? null : eventHelper.getOnRunning();
757    }
758
759    /**
760     * The onRunning event handler is called whenever the Task state
761     * transitions to the RUNNING state.
762     *
763     * @param value the event handler, can be null to clear it
764     */
765    public final void setOnRunning(EventHandler<WorkerStateEvent> value) {
766        getEventHelper().setOnRunning(value);
767    }
768
769    /**
770     * A protected convenience method for subclasses, called whenever the
771     * state of the Task has transitioned to the RUNNING state.
772     * This method is invoked on the FX Application Thread after any listeners
773     * of the state property and after the Task has been fully transitioned to
774     * the new state.
775     */
776    protected void running() { }
777
778    /**
779     * The onSucceeded event handler is called whenever the Task state
780     * transitions to the SUCCEEDED state.
781     *
782     * @return the onSucceeded event handler property
783     */
784    public final ObjectProperty<EventHandler<WorkerStateEvent>> onSucceededProperty() {
785        return getEventHelper().onSucceededProperty();
786    }
787
788    /**
789     * The onSucceeded event handler is called whenever the Task state
790     * transitions to the SUCCEEDED state.
791     *
792     * @return the onSucceeded event handler, if any
793     */
794    public final EventHandler<WorkerStateEvent> getOnSucceeded() {
795        return eventHelper == null ? null : eventHelper.getOnSucceeded();
796    }
797
798    /**
799     * The onSucceeded event handler is called whenever the Task state
800     * transitions to the SUCCEEDED state.
801     *
802     * @param value the event handler, can be null to clear it
803     */
804    public final void setOnSucceeded(EventHandler<WorkerStateEvent> value) {
805        getEventHelper().setOnSucceeded(value);
806    }
807
808    /**
809     * A protected convenience method for subclasses, called whenever the
810     * state of the Task has transitioned to the SUCCEEDED state.
811     * This method is invoked on the FX Application Thread after any listeners
812     * of the state property and after the Task has been fully transitioned to
813     * the new state.
814     */
815    protected void succeeded() { }
816
817    /**
818     * The onCancelled event handler is called whenever the Task state
819     * transitions to the CANCELLED state.
820     *
821     * @return the onCancelled event handler property
822     */
823    public final ObjectProperty<EventHandler<WorkerStateEvent>> onCancelledProperty() {
824        return getEventHelper().onCancelledProperty();
825    }
826
827    /**
828     * The onCancelled event handler is called whenever the Task state
829     * transitions to the CANCELLED state.
830     *
831     * @return the onCancelled event handler, if any
832     */
833    public final EventHandler<WorkerStateEvent> getOnCancelled() {
834        return eventHelper == null ? null : eventHelper.getOnCancelled();
835    }
836
837    /**
838     * The onCancelled event handler is called whenever the Task state
839     * transitions to the CANCELLED state.
840     *
841     * @param value the event handler, can be null to clear it
842     */
843    public final void setOnCancelled(EventHandler<WorkerStateEvent> value) {
844        getEventHelper().setOnCancelled(value);
845    }
846
847    /**
848     * A protected convenience method for subclasses, called whenever the
849     * state of the Task has transitioned to the CANCELLED state.
850     * This method is invoked on the FX Application Thread after any listeners
851     * of the state property and after the Task has been fully transitioned to
852     * the new state.
853     */
854    protected void cancelled() { }
855
856    /**
857     * The onFailed event handler is called whenever the Task state
858     * transitions to the FAILED state.
859     *
860     * @return the onFailed event handler property
861     */
862    public final ObjectProperty<EventHandler<WorkerStateEvent>> onFailedProperty() {
863        return getEventHelper().onFailedProperty();
864    }
865
866    /**
867     * The onFailed event handler is called whenever the Task state
868     * transitions to the FAILED state.
869     *
870     * @return the onFailed event handler, if any
871     */
872    public final EventHandler<WorkerStateEvent> getOnFailed() {
873        return eventHelper == null ? null : eventHelper.getOnFailed();
874    }
875
876    /**
877     * The onFailed event handler is called whenever the Task state
878     * transitions to the FAILED state.
879     *
880     * @param value the event handler, can be null to clear it
881     */
882    public final void setOnFailed(EventHandler<WorkerStateEvent> value) {
883        getEventHelper().setOnFailed(value);
884    }
885
886    /**
887     * A protected convenience method for subclasses, called whenever the
888     * state of the Task has transitioned to the FAILED state.
889     * This method is invoked on the FX Application Thread after any listeners
890     * of the state property and after the Task has been fully transitioned to
891     * the new state.
892     */
893    protected void failed() { }
894
895    private final ObjectProperty<V> value = new SimpleObjectProperty<V>(this, "value");
896    private void setValue(V v) { checkThread(); value.set(v); }
897    @Override public final V getValue() { checkThread(); return value.get(); }
898    @Override public final ReadOnlyObjectProperty<V> valueProperty() { checkThread(); return value; }
899
900    private final ObjectProperty<Throwable> exception = new SimpleObjectProperty<Throwable>(this, "exception");
901    private void _setException(Throwable value) { checkThread(); exception.set(value); }
902    @Override public final Throwable getException() { checkThread(); return exception.get(); }
903    @Override public final ReadOnlyObjectProperty<Throwable> exceptionProperty() { checkThread(); return exception; }
904
905    private final DoubleProperty workDone = new SimpleDoubleProperty(this, "workDone", -1);
906    private void setWorkDone(double value) { checkThread(); workDone.set(value); }
907    @Override public final double getWorkDone() { checkThread(); return workDone.get(); }
908    @Override public final ReadOnlyDoubleProperty workDoneProperty() { checkThread(); return workDone; }
909
910    private final DoubleProperty totalWork = new SimpleDoubleProperty(this, "totalWork", -1);
911    private void setTotalWork(double value) { checkThread(); totalWork.set(value); }
912    @Override public final double getTotalWork() { checkThread(); return totalWork.get(); }
913    @Override public final ReadOnlyDoubleProperty totalWorkProperty() { checkThread(); return totalWork; }
914
915    private final DoubleProperty progress = new SimpleDoubleProperty(this, "progress", -1);
916    private void setProgress(double value) { checkThread(); progress.set(value); }
917    @Override public final double getProgress() { checkThread(); return progress.get(); }
918    @Override public final ReadOnlyDoubleProperty progressProperty() { checkThread(); return progress; }
919
920    private final BooleanProperty running = new SimpleBooleanProperty(this, "running", false);
921    private void setRunning(boolean value) { checkThread(); running.set(value); }
922    @Override public final boolean isRunning() { checkThread(); return running.get(); }
923    @Override public final ReadOnlyBooleanProperty runningProperty() { checkThread(); return running; }
924
925    private final StringProperty message = new SimpleStringProperty(this, "message", "");
926    @Override public final String getMessage() { return message.get(); }
927    @Override public final ReadOnlyStringProperty messageProperty() { return message; }
928
929    private final StringProperty title = new SimpleStringProperty(this, "title", "");
930    @Override public final String getTitle() { return title.get(); }
931    @Override public final ReadOnlyStringProperty titleProperty() { return title; }
932
933    @Override public final boolean cancel() {
934        return cancel(true);
935    }
936
937    @Override public boolean cancel(boolean mayInterruptIfRunning) {
938        // Delegate to the super implementation to actually attempt to cancel this thing
939        boolean flag = super.cancel(mayInterruptIfRunning);
940        // If cancel succeeded (according to the semantics of the Future cancel method),
941        // then we need to make sure the State flag is set appropriately
942        if (flag) {
943            // If this method was called on the FX application thread, then we can
944            // just update the state directly and this will make sure that after
945            // the cancel method was called, the state will be set correctly
946            // (otherwise it would be indeterminate. However if the cancel method was
947            // called off the FX app thread, then we must use runLater, and the
948            // state flag will not be readable immediately after this call. However,
949            // that would be the case anyway since these properties are not thread-safe.
950            if (isFxApplicationThread()) {
951                setState(State.CANCELLED);
952            } else {
953                runLater(new Runnable() {
954                    @Override public void run() {
955                        setState(State.CANCELLED);
956                    }
957                });
958            }
959        }
960        // return the flag
961        return flag;
962    }
963
964    /**
965     * Updates the <code>workDone</code>, <code>totalWork</code>,
966     * and <code>progress</code> properties. Calls to updateProgress
967     * are coalesced and run later on the FX application thread, and calls
968     * to updateProgress, even from the FX Application thread, may not
969     * necessarily result in immediate updates to these properties, and
970     * intermediate workDone values may be coalesced to save on event
971     * notifications. <code>max</code> becomes the new value for
972     * <code>totalWork</code>.
973     * <p>
974     *     <em>This method is safe to be called from any thread.</em>
975     * </p>
976     *
977     * @param workDone A value from Long.MIN_VALUE up to max. If the value is greater
978     *                 than max, then it will be clamped at max.
979     *                 If the value passed is negative then the resulting percent
980     *                 done will be -1 (thus, indeterminate).
981     * @param max A value from Long.MIN_VALUE to Long.MAX_VALUE.
982     * @see #updateProgress(double, double)
983     */
984    protected void updateProgress(long workDone, long max) {
985        updateProgress((double)workDone, (double)max);
986    }
987
988    /**
989     * Updates the <code>workDone</code>, <code>totalWork</code>,
990     * and <code>progress</code> properties. Calls to updateProgress
991     * are coalesced and run later on the FX application thread, and calls
992     * to updateProgress, even from the FX Application thread, may not
993     * necessarily result in immediate updates to these properties, and
994     * intermediate workDone values may be coalesced to save on event
995     * notifications. <code>max</code> becomes the new value for
996     * <code>totalWork</code>.
997     * <p>
998     *     <em>This method is safe to be called from any thread.</em>
999     * </p>
1000     *
1001     * @param workDone A value from Double.MIN_VALUE up to max. If the value is greater
1002     *                 than max, then it will be clamped at max.
1003     *                 If the value passed is negative, or Infinity, or NaN,
1004     *                 then the resulting percentDone will be -1 (thus, indeterminate).
1005     * @param max A value from Double.MIN_VALUE to Double.MAX_VALUE. Infinity and NaN are treated as -1.
1006     * @since 2.2
1007     */
1008    protected void updateProgress(double workDone, double max) {
1009        // Adjust Infinity / NaN to be -1 for both workDone and max.
1010        if (Double.isInfinite(workDone) || Double.isNaN(workDone)) {
1011            workDone = -1;
1012        }
1013
1014        if (Double.isInfinite(max) || Double.isNaN(max)) {
1015            max = -1;
1016        }
1017
1018        if (workDone < 0) {
1019            workDone = -1;
1020        }
1021
1022        if (max < 0) {
1023            max = -1;
1024        }
1025
1026        // Clamp the workDone if necessary so as not to exceed max
1027        if (workDone > max) {
1028            workDone = max;
1029        }
1030
1031        if (isFxApplicationThread()) {
1032            _updateProgress(workDone, max);
1033        } else if (progressUpdate.getAndSet(new ProgressUpdate(workDone, max)) == null) {
1034            runLater(new Runnable() {
1035                @Override public void run() {
1036                    final ProgressUpdate update = progressUpdate.getAndSet(null);
1037                    _updateProgress(update.workDone, update.totalWork);
1038                }
1039            });
1040        }
1041    }
1042
1043    private void _updateProgress(double workDone, double max) {
1044        setTotalWork(max);
1045        setWorkDone(workDone);
1046        if (workDone == -1) {
1047            setProgress(-1);
1048        } else {
1049            setProgress(workDone / max);
1050        }
1051    }
1052
1053    /**
1054     * Updates the <code>message</code> property. Calls to updateMessage
1055     * are coalesced and run later on the FX application thread, so calls
1056     * to updateMessage, even from the FX Application thread, may not
1057     * necessarily result in immediate updates to this property, and
1058     * intermediate message values may be coalesced to save on event
1059     * notifications.
1060     * <p>
1061     *     <em>This method is safe to be called from any thread.</em>
1062     * </p>
1063     *
1064     * @param message the new message
1065     */
1066    protected void updateMessage(String message) {
1067        if (isFxApplicationThread()) {
1068            this.message.set(message);
1069        } else {
1070            // As with the workDone, it might be that the background thread
1071            // will update this message quite frequently, and we need
1072            // to throttle the updates so as not to completely clobber
1073            // the event dispatching system.
1074            if (messageUpdate.getAndSet(message) == null) {
1075                runLater(new Runnable() {
1076                    @Override public void run() {
1077                        final String message = messageUpdate.getAndSet(null);
1078                        Task.this.message.set(message);
1079                    }
1080                });
1081            }
1082        }
1083    }
1084
1085    /**
1086     * Updates the <code>title</code> property. Calls to updateTitle
1087     * are coalesced and run later on the FX application thread, so calls
1088     * to updateTitle, even from the FX Application thread, may not
1089     * necessarily result in immediate updates to this property, and
1090     * intermediate title values may be coalesced to save on event
1091     * notifications.
1092     * <p>
1093     *     <em>This method is safe to be called from any thread.</em>
1094     * </p>
1095     *
1096     * @param title the new title
1097     */
1098    protected void updateTitle(String title) {
1099        if (isFxApplicationThread()) {
1100            this.title.set(title);
1101        } else {
1102            // As with the workDone, it might be that the background thread
1103            // will update this title quite frequently, and we need
1104            // to throttle the updates so as not to completely clobber
1105            // the event dispatching system.
1106            if (titleUpdate.getAndSet(title) == null) {
1107                runLater(new Runnable() {
1108                    @Override public void run() {
1109                        final String title = titleUpdate.getAndSet(null);
1110                        Task.this.title.set(title);
1111                    }
1112                });
1113            }
1114        }
1115    }
1116
1117    /**
1118     * Updates the <code>value</code> property. Calls to updateValue
1119     * are coalesced and run later on the FX application thread, so calls
1120     * to updateValue, even from the FX Application thread, may not
1121     * necessarily result in immediate updates to this property, and
1122     * intermediate values may be coalesced to save on event
1123     * notifications.
1124     * <p>
1125     *     <em>This method is safe to be called from any thread.</em>
1126     * </p>
1127     *
1128     * @param value the new value
1129     * @since 8
1130     */
1131    protected void updateValue(V value) {
1132        if (isFxApplicationThread()) {
1133            this.value.set(value);
1134        } else {
1135            // As with the workDone, it might be that the background thread
1136            // will update this value quite frequently, and we need
1137            // to throttle the updates so as not to completely clobber
1138            // the event dispatching system.
1139            if (valueUpdate.getAndSet(value) == null) {
1140                runLater(new Runnable() {
1141                    @Override public void run() {
1142                        Task.this.value.set(valueUpdate.getAndSet(null));
1143                    }
1144                });
1145            }
1146        }
1147    }
1148
1149    /*
1150     * IMPLEMENTATION
1151     */
1152
1153    private void checkThread() {
1154        if (!isFxApplicationThread()) {
1155            throw new IllegalStateException("Task must only be used from the FX Application Thread");
1156        }
1157    }
1158
1159    // This method exists for the sake of testing, so I can subclass and override
1160    // this method in the test and not actually use Platform.runLater.
1161    void runLater(Runnable r) {
1162        Platform.runLater(r);
1163    }
1164
1165    // This method exists for the sake of testing, so I can subclass and override
1166    // this method in the test and not actually use Platform.isFxApplicationThread.
1167    boolean isFxApplicationThread() {
1168        return Platform.isFxApplicationThread();
1169    }
1170
1171    /***************************************************************************
1172     *                                                                         *
1173     *                         Event Dispatch                                  *
1174     *                                                                         *
1175     **************************************************************************/
1176
1177    private EventHelper eventHelper = null;
1178    private EventHelper getEventHelper() {
1179        if (eventHelper == null) {
1180            eventHelper = new EventHelper(this);
1181        }
1182        return eventHelper;
1183    }
1184
1185    /**
1186     * Registers an event handler to this task. Any event filters are first
1187     * processed, then the specified onFoo event handlers, and finally any
1188     * event handlers registered by this method. As with other events
1189     * in the scene graph, if an event is consumed, it will not continue
1190     * dispatching.
1191     *
1192     * @param <T> the specific event class of the handler
1193     * @param eventType the type of the events to receive by the handler
1194     * @param eventHandler the handler to register
1195     * @throws NullPointerException if the event type or handler is null
1196     */
1197    public final <T extends Event> void addEventHandler(
1198            final EventType<T> eventType,
1199            final EventHandler<? super T> eventHandler) {
1200        getEventHelper().addEventHandler(eventType, eventHandler);
1201    }
1202
1203    /**
1204     * Unregisters a previously registered event handler from this task. One
1205     * handler might have been registered for different event types, so the
1206     * caller needs to specify the particular event type from which to
1207     * unregister the handler.
1208     *
1209     * @param <T> the specific event class of the handler
1210     * @param eventType the event type from which to unregister
1211     * @param eventHandler the handler to unregister
1212     * @throws NullPointerException if the event type or handler is null
1213     */
1214    public final <T extends Event> void removeEventHandler(
1215            final EventType<T> eventType,
1216            final EventHandler<? super T> eventHandler) {
1217        getEventHelper().removeEventHandler(eventType, eventHandler);
1218    }
1219
1220    /**
1221     * Registers an event filter to this task. Registered event filters get
1222     * an event before any associated event handlers.
1223     *
1224     * @param <T> the specific event class of the filter
1225     * @param eventType the type of the events to receive by the filter
1226     * @param eventFilter the filter to register
1227     * @throws NullPointerException if the event type or filter is null
1228     */
1229    public final <T extends Event> void addEventFilter(
1230            final EventType<T> eventType,
1231            final EventHandler<? super T> eventFilter) {
1232        getEventHelper().addEventFilter(eventType, eventFilter);
1233    }
1234
1235    /**
1236     * Unregisters a previously registered event filter from this task. One
1237     * filter might have been registered for different event types, so the
1238     * caller needs to specify the particular event type from which to
1239     * unregister the filter.
1240     *
1241     * @param <T> the specific event class of the filter
1242     * @param eventType the event type from which to unregister
1243     * @param eventFilter the filter to unregister
1244     * @throws NullPointerException if the event type or filter is null
1245     */
1246    public final <T extends Event> void removeEventFilter(
1247            final EventType<T> eventType,
1248            final EventHandler<? super T> eventFilter) {
1249        getEventHelper().removeEventFilter(eventType, eventFilter);
1250    }
1251
1252    /**
1253     * Sets the handler to use for this event type. There can only be one such
1254     * handler specified at a time. This handler is guaranteed to be called
1255     * first. This is used for registering the user-defined onFoo event
1256     * handlers.
1257     *
1258     * @param <T> the specific event class of the handler
1259     * @param eventType the event type to associate with the given eventHandler
1260     * @param eventHandler the handler to register, or null to unregister
1261     * @throws NullPointerException if the event type is null
1262     */
1263    protected final <T extends Event> void setEventHandler(
1264            final EventType<T> eventType,
1265            final EventHandler<? super T> eventHandler) {
1266        getEventHelper().setEventHandler(eventType, eventHandler);
1267    }
1268
1269    /**
1270     * Fires the specified event. Any event filter encountered will
1271     * be notified and can consume the event. If not consumed by the filters,
1272     * the event handlers on this task are notified. If these don't consume the
1273     * event either, then all event handlers are called and can consume the
1274     * event.
1275     * <p>
1276     * This method must be called on the FX user thread.
1277     *
1278     * @param event the event to fire
1279     */
1280    public final void fireEvent(Event event) {
1281        checkThread();
1282        getEventHelper().fireEvent(event);
1283    }
1284
1285    @Override
1286    public EventDispatchChain buildEventDispatchChain(EventDispatchChain tail) {
1287        return getEventHelper().buildEventDispatchChain(tail);
1288    }
1289
1290    /**
1291     * A struct like class that contains the last workDone update information.
1292     * What we do when updateProgress is called, is we create a new ProgressUpdate
1293     * object and store it. If it was null, then we fire off a new Runnable
1294     * using RunLater, which will eventually read the latest and set it to null
1295     * atomically. If it was not null, then we simply update it.
1296     */
1297    private static final class ProgressUpdate {
1298        private final double workDone;
1299        private final double totalWork;
1300
1301        private ProgressUpdate(double p, double m) {
1302            this.workDone = p;
1303            this.totalWork = m;
1304        }
1305    }
1306
1307    /**
1308     *  TaskCallable actually implements the Callable contract as defined for
1309     *  the FutureTask class, and is necessary so as to allow us to intercept
1310     *  the call() operation to update state on the Task as appropriate.
1311     * @param <V>
1312     */
1313    private static final class TaskCallable<V> implements Callable<V> {
1314        /**
1315         * The Task that is going to use this TaskCallable
1316         */
1317        private Task<V> task;
1318
1319        /**
1320         * Create a TaskCallable. The concurrent and other fields MUST be set
1321         * immediately after creation.
1322         */
1323        private TaskCallable() { }
1324
1325        /**
1326         * Invoked by the system when it is time to run the client code. This
1327         * implementation is where we modify the state and other properties
1328         * and from which we invoke the events.
1329         *
1330         * @return The result of the Task call method
1331         * @throws Exception any exception which occurred
1332         */
1333        @Override public V call() throws Exception {
1334            // If the Task is sent to an ExecutorService for execution, then we
1335            // will need to make sure that we transition first to the SCHEDULED
1336            // state before then transitioning to the RUNNING state. If the
1337            // Task was executed by a Service, then it will have already been
1338            // in the SCHEDULED state and setting it again here has no negative
1339            // effect. But we must ensure that SCHEDULED is visited before RUNNING
1340            // in all cases so that developer code can be consistent.
1341            task.runLater(new Runnable() {
1342                @Override public void run() {
1343                    task.setState(State.SCHEDULED);
1344                    task.setState(State.RUNNING);
1345                }
1346            });
1347            // Go ahead and delegate to the wrapped callable
1348            try {
1349                final V result = task.call();
1350                if (!task.isCancelled()) {
1351                    // If it was not cancelled, then we take the return
1352                    // value and set it as the result.
1353                    task.runLater(new Runnable() {
1354                        @Override public void run() {
1355                            // The result must be set first, so that when the
1356                            // SUCCEEDED flag is set, the value will be available
1357                            // The alternative is not the case, because you
1358                            // can assume if the result is set, it has
1359                            // succeeded.
1360                            task.updateValue(result);
1361                            task.setState(State.SUCCEEDED);
1362                        }
1363                    });
1364                    return result;
1365                } else {
1366                    // There may have been some intermediate result in the
1367                    // task set from the background thread, so I want to be
1368                    // sure to return the most recent intermediate value
1369                    return task.getValue();
1370                }
1371            } catch (final Throwable th) {
1372                // Be sure to set the state after setting the cause of failure
1373                // so that developers handling the state change events have a
1374                // throwable to inspect when they get the FAILED state. Note
1375                // that the other way around is not important -- when a developer
1376                // observes the causeOfFailure is set to a non-null value, even
1377                // though the state has not yet been updated, he can infer that
1378                // it will be FAILED because it can be nothing other than FAILED
1379                // in that circumstance.
1380                task.runLater(new Runnable() {
1381                    @Override public void run() {
1382                        task._setException(th);
1383                        task.setState(State.FAILED);
1384                    }
1385                });
1386                // Some error occurred during the call (it might be
1387                // an exception (either runtime or checked), or it might
1388                // be an error. In any case, we capture the throwable,
1389                // record it as the causeOfFailure, and then rethrow. However
1390                // since the Callable interface requires that we throw an
1391                // Exception (not Throwable), we have to wrap the exception
1392                // if it is not already one.
1393                if (th instanceof Exception) {
1394                    throw (Exception) th;
1395                } else {
1396                    throw new Exception(th);
1397                }
1398            }
1399        }
1400    }
1401}