import javajs.async.SwingJSUtils.StateMachine;
/**
+ * v. 2020.06.03
+ *
* Executes synchronous or asynchronous tasks using a SwingWorker in Java or
* JavaScript, equivalently.
*
* the subclass to update the progress field in both the SwingWorker and the
* ProgressMonitor.
*
- * If it is desired to run the AsyncSwingWorker synchonously, call the
+ * If it is desired to run the AsyncSwingWorker synchronously, call the
* executeSynchronously() method rather than execute(). Never call
* SwingWorker.run().
*
+ * Note that doInBackgroundAsync runs on the Java AWT event queue. This means
+ * that, unlike a true SwingWorker, it will run in event-queue sequence, after
+ * anything that that method itself adds to the queue. This is what SwingWorker itself
+ * does with its done() signal.
+ *
+ * If doInBackgroundAsync has tasks that are time intensive, the thing to do is to
+ *
+ * (a) pause this worker by setting the value of progress for the NEXT step:
+ *
+ * setProgressAsync(n);
+ *
+ * (b) pause the timer so that when doInBackgroundAsync returns, the timer is not fired:
+ *
+ * setPaused(true);
+ *
+ * (c) start your process as new Thread, which bypasses the AWT EventQueue:
+ *
+ * new Thread(Runnable).start();
+ *
+ * (d) have your thread, when it is done, return control to this worker:
+ *
+ * setPaused(false);
+ *
+ * This final call restarts the worker with the currently specified progress value.
*
* @author hansonr
*
*/
public abstract class AsyncSwingWorker extends SwingWorker<Void, Void> implements StateMachine {
+
+ // PropertyChangeEvent getPropertyName()
+
+ private static final String PROPERTY_STATE = "state";
+ private static final String PROPERTY_PAUSE = "pause";
+
+ // PropertyChangeEvent getNewValue()
+
+ public static final String STARTED_ASYNC = "STARTED_ASYNC";
+ public static final String STARTED_SYNC = "STARTED_SYNC";
+
public static final String DONE_ASYNC = "DONE_ASYNC";
public static final String CANCELED_ASYNC = "CANCELED_ASYNC";
+
+ public static final String PAUSED = "PAUSED";
+ public static final String RESUMED = "RESUMED";
protected int progressAsync;
}
public void executeAsync() {
+ firePropertyChange(PROPERTY_STATE, null, STARTED_ASYNC);
super.execute();
}
public void executeSynchronously() {
+ firePropertyChange(PROPERTY_STATE, null, STARTED_SYNC);
isAsync = false;
delayMillis = 0;
try {
private final static int STATE_LOOP = 1;
private final static int STATE_WAIT = 2;
private final static int STATE_DONE = 99;
-
+
private StateHelper helper;
protected StateHelper getHelper() {
protected void setPaused(boolean tf) {
isPaused = tf;
+ firePropertyChange(PROPERTY_PAUSE, null, (tf ? PAUSED : RESUMED));
+ if (!tf)
+ stateLoop();
}
protected boolean isPaused() {
case STATE_LOOP:
if (checkCanceled()) {
helper.setState(STATE_DONE);
- firePropertyChange("state", null, CANCELED_ASYNC);
+ firePropertyChange(PROPERTY_STATE, null, CANCELED_ASYNC);
} else {
int ret = doInBackgroundAsync(progressAsync);
if (!helper.isAlive() || isPaused) {
}
continue;
case STATE_WAIT:
+ // meaning "sleep" and then "loop"
helper.setState(STATE_LOOP);
helper.sleep(delayMillis);
return true;
@Override
public void run() {
doneAsync();
- firePropertyChange("state", null, DONE_ASYNC);
+ firePropertyChange(PROPERTY_STATE, null, DONE_ASYNC);
}
};