As I mentioned in my previous blog, during my experiments with JavaFX I needed to run certain tasks on a separate thread (e.g. calls to a remote web service via Jersey Client API). One can do it in JavaFX using JavaTaskBase class, but I wanted something simpler, something similar to what FXexperience blog suggested. So, I created a custom subclass of javafx.async.Task named AsyncTask that allowed me to make asynchronous calls as follows:
AsyncTask { run: function() { // add the code you want to run asynchronously } onDone: function() { // this is executed once the "run" method finishes running } }.start();
Here is the source code for the AsyncTask class together with the helper Java class it’s using. It should be self explanatory.
AsyncTask.fx
import javafx.async.Task; public class AsyncTask extends Task, AsyncTaskHelper.Task { /** Function that should be run asynchronously. */ public var run: function() = null; // the helper def peer = new AsyncTaskHelper(this); // used to start the task override function start() { started = true; if (onStart != null) onStart(); peer.start(); } // don't need stop - isn't implemented override function stop() { // do nothing } // called from the helper Java class from a different thread override function taskRun() { // run the code to be run asynchronously if (run != null) run(); // send a notification (on the dispatch thread) the code finished running FX.deferAction(function() { done = true; if (onDone != null) onDone(); }); } }
AsyncTaskHelper.java
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class AsyncTaskHelper implements Runnable { // Using a fixed threadpool to run the asynchronous task private static final ExecutorService QUEUE = Executors.newFixedThreadPool(10); // the "parent" JavaFX AsyncTask instance private final Task peer; public AsyncTaskHelper(Task peer) { this.peer = peer; } // called from AsyncTask.start() method - will add this task // to the thread pool queue public void start() { QUEUE.execute(this); } // called by the thread pool queue to start the task public void run() { peer.taskRun(); } // interface to be implemented by the "parent" JavaFX AsyncTask public static interface Task { public void taskRun(); } }
nice approach. thanks man!