JAL-3446 AsyncSwingWorker upgrade
authorBobHanson <hansonr@stolaf.edu>
Wed, 3 Jun 2020 13:12:37 +0000 (08:12 -0500)
committerBobHanson <hansonr@stolaf.edu>
Wed, 3 Jun 2020 13:12:37 +0000 (08:12 -0500)
src/javajs/async/AsyncSwingWorker.java

index df103cd..703f7f5 100644 (file)
@@ -10,6 +10,8 @@ import javajs.async.SwingJSUtils.StateHelper;
 import javajs.async.SwingJSUtils.StateMachine;
 
 /**
+ * v. 2020.06.03 
+ * 
  * Executes synchronous or asynchronous tasks using a SwingWorker in Java or
  * JavaScript, equivalently.
  * 
@@ -38,18 +40,56 @@ import javajs.async.SwingJSUtils.StateMachine;
  * 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;
 
@@ -119,10 +159,12 @@ public abstract class AsyncSwingWorker extends SwingWorker<Void, Void> implement
        }
 
        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 {
@@ -244,7 +286,7 @@ public abstract class AsyncSwingWorker extends SwingWorker<Void, Void> implement
        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() {
@@ -255,6 +297,9 @@ public abstract class AsyncSwingWorker extends SwingWorker<Void, Void> implement
 
        protected void setPaused(boolean tf) {
                isPaused = tf;
+               firePropertyChange(PROPERTY_PAUSE, null, (tf ? PAUSED : RESUMED));
+               if (!tf)
+                       stateLoop();
        }
 
        protected boolean isPaused() {
@@ -292,7 +337,7 @@ public abstract class AsyncSwingWorker extends SwingWorker<Void, Void> implement
                        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) {
@@ -309,6 +354,7 @@ public abstract class AsyncSwingWorker extends SwingWorker<Void, Void> implement
                                }
                                continue;
                        case STATE_WAIT:
+                               // meaning "sleep" and then "loop"
                                helper.setState(STATE_LOOP);
                                helper.sleep(delayMillis);
                                return true;
@@ -343,7 +389,7 @@ public abstract class AsyncSwingWorker extends SwingWorker<Void, Void> implement
                @Override
                public void run() {
                        doneAsync();
-                       firePropertyChange("state", null, DONE_ASYNC);
+                       firePropertyChange(PROPERTY_STATE, null, DONE_ASYNC);
                }
 
        };