JAL-3848 add compbio and jalview to direct connection list for J2S
[jalview.git] / src / jalview / bin / Jalview.java
index f23ebfa..1c7e4ea 100755 (executable)
@@ -20,6 +20,7 @@
  */
 package jalview.bin;
 
+import java.awt.GraphicsEnvironment;
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileOutputStream;
@@ -37,7 +38,6 @@ import java.security.PermissionCollection;
 import java.security.Permissions;
 import java.security.Policy;
 import java.util.HashMap;
-import java.util.Hashtable;
 import java.util.Map;
 import java.util.Vector;
 
@@ -49,23 +49,13 @@ import com.threerings.getdown.util.LaunchUtil;
 import groovy.lang.Binding;
 import groovy.util.GroovyScriptEngine;
 import jalview.api.AlignCalcWorkerI;
-import jalview.api.AlignViewportI;
-import jalview.api.JalviewApp;
-import jalview.api.StructureSelectionManagerProvider;
-import jalview.datamodel.ColumnSelection;
-import jalview.datamodel.HiddenColumns;
-import jalview.datamodel.PDBEntry;
-import jalview.datamodel.SequenceGroup;
-import jalview.datamodel.SequenceI;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
 import jalview.ext.so.SequenceOntology;
 import jalview.gui.AlignFrame;
 import jalview.gui.AlignViewport;
-import jalview.gui.AlignmentPanel;
-import jalview.gui.CalculationChooser;
 import jalview.gui.Desktop;
 import jalview.gui.Preferences;
 import jalview.gui.PromptUserConfig;
-import jalview.gui.StructureViewer;
 import jalview.io.AppletFormatAdapter;
 import jalview.io.BioJsHTMLOutput;
 import jalview.io.DataSourceType;
@@ -78,17 +68,11 @@ import jalview.io.HtmlSvgOutput;
 import jalview.io.IdentifyFile;
 import jalview.io.NewickFile;
 import jalview.io.gff.SequenceOntologyFactory;
-import jalview.javascript.JSFunctionExec;
-import jalview.javascript.MouseOverStructureListener;
-import jalview.renderer.seqfeatures.FeatureRenderer;
 import jalview.schemes.ColourSchemeI;
 import jalview.schemes.ColourSchemeProperty;
-import jalview.structure.SelectionSource;
-import jalview.structure.VamsasSource;
 import jalview.util.MessageManager;
 import jalview.util.Platform;
 import jalview.ws.jws2.Jws2Discoverer;
-import netscape.javascript.JSObject;
 
 /**
  * Main class for Jalview Application <br>
@@ -105,30 +89,44 @@ import netscape.javascript.JSObject;
  * @author $author$
  * @version $Revision$
  */
-public class Jalview implements JalviewJSApi
+public class Jalview implements ApplicationSingletonI
 {
-  static
+
+  // for testing those nasty messages you cannot ever find.
+  // static
+  // {
+  // System.setOut(new PrintStream(new ByteArrayOutputStream())
+  // {
+  // @Override
+  // public void println(Object o)
+  // {
+  // if (o != null)
+  // {
+  // System.err.println(o);
+  // }
+  // }
+  //
+  // });
+  // }
+  public static Jalview getInstance()
   {
-    Platform.getURLCommandArguments();
+    return (Jalview) ApplicationSingletonProvider
+            .getInstance(Jalview.class);
   }
 
-  private boolean headless;
-
-  // singleton instance of this class
+  private Jalview()
+  {
+  }
 
-  private static Jalview instance;
+  private boolean headless;
 
   private Desktop desktop;
 
-  public static AlignFrame currentAlignFrame;
-
-  public boolean isJavaAppletTag;
+  public AlignFrame currentAlignFrame;
 
   public String appletResourcePath;
 
-  JalviewAppLoader appLoader;
-
-  protected JSFunctionExec jsFunctionExec;
+  public String j2sAppletID;
 
   private boolean noCalculation, noMenuBar, noStatus;
 
@@ -156,12 +154,9 @@ public class Jalview implements JalviewJSApi
 
   static
   {
-    if (!Platform.isJS())
-    /**
-     * Java only
-     * 
-     * @j2sIgnore
-     */
+    if (Platform.isJS()) {
+        Platform.getURLCommandArguments();
+    } else /** @j2sIgnore */
     {
       // grab all the rights we can for the JVM
       Policy.setPolicy(new Policy()
@@ -191,8 +186,8 @@ public class Jalview implements JalviewJSApi
   class FeatureFetcher
   {
     /*
-     * TODO: generalise to track all jalview events to orchestrate batch processing
-     * events.
+     * TODO: generalise to track all jalview events to orchestrate batch
+     * processing events.
      */
 
     private int queued = 0;
@@ -241,12 +236,6 @@ public class Jalview implements JalviewJSApi
 
   }
 
-  public static Jalview getInstance()
-  {
-    return instance;
-  }
-  
-  
   private final static boolean doPlatformLogging = false;
 
   /**
@@ -261,9 +250,7 @@ public class Jalview implements JalviewJSApi
     {
       Platform.startJavaLogging();
     }
-
-    instance = new Jalview();
-    instance.doMain(args);
+    getInstance().doMain(args);
   }
 
   /**
@@ -273,15 +260,16 @@ public class Jalview implements JalviewJSApi
   {
 
     boolean isJS = Platform.isJS();
-    if (isJS)
-    {
-      Platform.setAppClass(this);
-    }
-    else
+    if (!isJS)
     {
       System.setSecurityManager(null);
     }
 
+    /*
+     * @j2sNative J2S.db._DirectDatabaseCalls["compbio.dundee.ac.uk"]=null;
+     * @j2sNative J2S.db._DirectDatabaseCalls["jalview.org"]=null;
+     * 
+     */
     System.out
             .println("Java version: " + System.getProperty("java.version"));
     System.out.println("Java Home: " + System.getProperty("java.home"));
@@ -305,7 +293,7 @@ public class Jalview implements JalviewJSApi
     }
 
     // report Jalview version
-    Cache.loadBuildProperties(true);
+    Cache.getInstance().loadBuildProperties(true);
 
     ArgsParser aparser = new ArgsParser(args);
     headless = false;
@@ -314,18 +302,16 @@ public class Jalview implements JalviewJSApi
 
     Cache.loadProperties(usrPropsFile); // must do this before
 
+    boolean allowServices = true;
+    
     if (isJS)
     {
-      isJavaAppletTag = aparser.isApplet();
-      if (isJavaAppletTag)
-      {
-        Preferences.setAppletDefaults();
-        Cache.loadProperties(usrPropsFile); // again, because we
-        // might be changing defaults here?
-      }
-      System.out.println(
-              "<Applet> found: " + aparser.getValue("Info.j2sAppletID"));
-      appletResourcePath = aparser.getValue("Info.resourcePath");
+      j2sAppletID = Platform.getAppID(null);
+      Preferences.setAppletDefaults();
+      Cache.loadProperties(usrPropsFile); // again, because we
+      // might be changing defaults here?
+      appletResourcePath = (String) aparser.getAppletValue("resourcepath",
+              null, true);
     }
     else
     /**
@@ -345,19 +331,22 @@ public class Jalview implements JalviewJSApi
         showUsage();
         System.exit(0);
       }
-      // ?>>
+      // BH note: Only -nodisplay is official; others are deprecated?
       if (aparser.contains("nodisplay") || aparser.contains("nogui")
-              || aparser.contains("headless"))
+              || aparser.contains("headless")
+              || GraphicsEnvironment.isHeadless())
       {
-        System.setProperty("java.awt.headless", "true");
+        if (!isJS) {
+          // BH Definitely not a good idea in JavaScript; 
+          // probably should not be here for Java, either.  
+          System.setProperty("java.awt.headless", "true");
+        }
         headless = true;
       }
-      // <<?
-
-      // anything else!
 
       final String jabawsUrl = aparser.getValue(ArgsParser.JABAWS);
-      if (jabawsUrl != null)
+      allowServices = !("none".equals(jabawsUrl));
+      if (allowServices && jabawsUrl != null)
       {
         try
         {
@@ -390,11 +379,6 @@ public class Jalview implements JalviewJSApi
       }
       defs = aparser.getValue("setprop");
     }
-    if (System.getProperty("java.awt.headless") != null
-            && System.getProperty("java.awt.headless").equals("true"))
-    {
-      headless = true;
-    }
     System.setProperty("http.agent",
             "Jalview Desktop/" + Cache.getDefault("VERSION", "Unknown"));
     try
@@ -408,8 +392,6 @@ public class Jalview implements JalviewJSApi
       System.exit(0);
     }
 
-    desktop = null;
-
     if (!isJS)
     /** @j2sIgnore */
     {
@@ -464,17 +446,18 @@ public class Jalview implements JalviewJSApi
      * configure 'full' SO model if preferences say to, else use the default (full SO)
      * - as JS currently doesn't have OBO parsing, it must use 'Lite' version
      */
-    boolean soDefault = !Platform.isJS();
+    boolean soDefault = !isJS;
     if (Cache.getDefault("USE_FULL_SO", soDefault))
     {
-      SequenceOntologyFactory.setInstance(new SequenceOntology());
+      SequenceOntologyFactory.setSequenceOntology(new SequenceOntology());
     }
 
+
+    desktop = null;
     if (!headless)
     {
-      desktop = new Desktop();
+      desktop = Desktop.getInstance();
       desktop.setInBatchMode(true); // indicate we are starting up
-
       try
       {
         JalviewTaskbar.setTaskbar(this);
@@ -482,17 +465,20 @@ public class Jalview implements JalviewJSApi
       {
         System.out.println("Error setting Taskbar: " + t.getMessage());
       }
-
       desktop.setVisible(true);
-
-      if (!Platform.isJS())
+      if (Platform.isJS())
+        Cache.setProperty("SHOW_JWS2_SERVICES", "false");
+      if (allowServices)
+      {
+        desktop.startServiceDiscovery();
+      }
+      if (!isJS)
       /**
        * Java only
        * 
        * @j2sIgnore
        */
       {
-        desktop.startServiceDiscovery();
         if (!aparser.contains("nousagestats"))
         {
           startUsageStats(desktop);
@@ -544,37 +530,20 @@ public class Jalview implements JalviewJSApi
         BioJsHTMLOutput.updateBioJS();
       }
     }
-
     parseArguments(aparser, true);
   }
 
   /**
-   * Allow an outside entity to initiate the second half of argument parsing
-   * (only).
+   * Parse all command-line String[] arguments as well as all JavaScript-derived
+   * parameters from Info.
    * 
-   * @param args
-   * @return null is good
-   */
-  @Override
-  public Object parseArguments(String[] args)
-  {
-
-    try
-    {
-      parseArguments(new ArgsParser(args), false);
-      return null;
-    } catch (Throwable t)
-    {
-      return t;
-    }
-  }
-
-  /**
+   * We allow for this method to be run from JavaScript. Basically allowing
+   * simple scripting.
    * 
    * @param aparser
    * @param isStartup
    */
-  private void parseArguments(ArgsParser aparser, boolean isStartup)
+  public void parseArguments(ArgsParser aparser, boolean isStartup)
   {
 
     String groovyscript = null; // script to execute after all loading is
@@ -609,18 +578,82 @@ public class Jalview implements JalviewJSApi
 
     String file = aparser.getValue("open", true);
 
-    if (file == null && desktop == null)
+    if (!isJS && file == null && desktop == null)
     {
       System.out.println("No files to open!");
       System.exit(1);
     }
 
+    setDisplayParameters(aparser);
+    
+    // time to open a file.
+
     long progress = -1;
     DataSourceType protocol = null;
     FileLoader fileLoader = new FileLoader(!headless);
     FileFormatI format = null;
     // Finally, deal with the remaining input data.
-    if (file != null)
+    AlignFrame af = null;
+
+    JalviewJSApp jsApp = (isJS ? new JalviewJSApp(this, aparser) : null);
+
+    if (file == null)
+    {
+      if (isJS)
+      {
+        // JalviewJS allows sequence1 sequence2 ....
+        
+      }
+      else if (!headless && Cache.getDefault("SHOW_STARTUP_FILE", true))
+      /**
+       * Java only
+       * 
+       * @j2sIgnore
+       */
+      {
+
+        // We'll only open the default file if the desktop is visible.
+        // And the user
+        // ////////////////////
+
+        file = Cache.getDefault("STARTUP_FILE",
+                Cache.getDefault("www.jalview.org",
+                        "http://www.jalview.org")
+                        + "/examples/exampleFile_2_7.jar");
+        if (file.equals(
+                "http://www.jalview.org/examples/exampleFile_2_3.jar"))
+        {
+          // hardwire upgrade of the startup file
+          file.replace("_2_3.jar", "_2_7.jar");
+          // and remove the stale setting
+          Cache.removeProperty("STARTUP_FILE");
+        }
+
+        protocol = DataSourceType.FILE;
+
+        if (file.indexOf("http:") > -1)
+        {
+          protocol = DataSourceType.URL;
+        }
+
+        if (file.endsWith(".jar"))
+        {
+          format = FileFormat.Jalview;
+        }
+        else
+        {
+          try
+          {
+            format = new IdentifyFile().identify(file, protocol);
+          } catch (FileFormatException e)
+          {
+            // TODO what?
+          }
+        }
+        af = fileLoader.LoadFileWaitTillLoaded(file, protocol, format);
+      }
+    }
+    else
     {
       if (!headless)
       {
@@ -651,54 +684,30 @@ public class Jalview implements JalviewJSApi
           }
         }
       }
-      String fileFormat = (isJavaAppletTag
-              ? aparser.getAppletValue("format", null)
+      
+      String fileFormat = (isJS
+              ? (String) aparser.getAppletValue("format", null, true)
               : null);
       protocol = AppletFormatAdapter.checkProtocol(file);
       try
       {
-        format = (isJavaAppletTag && fileFormat != null
+        format = (fileFormat != null
                 ? FileFormats.getInstance().forName(fileFormat)
                 : null);
         if (format == null)
         {
           format = new IdentifyFile().identify(file, protocol);
         }
-        format = new IdentifyFile().identify(file, protocol);
       } catch (FileFormatException e1)
       {
         // TODO ?
       }
 
-      if (aparser.contains(ArgsParser.NOMENUBAR))
-      {
-        noMenuBar = true;
-        System.out.println("CMD [nomenu] executed successfully!");
-      }
-
-      if (aparser.contains(ArgsParser.NOSTATUS))
-      {
-        noStatus = true;
-        System.out.println("CMD [nostatus] executed successfully!");
-      }
-
-      if (aparser.contains(ArgsParser.NOANNOTATION)
-              || aparser.contains(ArgsParser.NOANNOTATION2))
-      {
-        noAnnotation = true;
-        System.out.println("CMD no-annotation executed successfully!");
-      }
-      if (aparser.contains(ArgsParser.NOCALCULATION))
-      {
-        noCalculation = true;
-        System.out.println("CMD [nocalculation] executed successfully!");
-      }
-
-      AlignFrame af = new FileLoader(!headless).LoadFileWaitTillLoaded(file,
-              protocol, format);
+      af = new FileLoader(!headless).LoadFileWaitTillLoaded(file, protocol,
+              format);
       if (af == null)
       {
-        System.out.println("error");
+        System.out.println("jalview error - AlignFrame was not created");
       }
       else
       {
@@ -733,135 +742,13 @@ public class Jalview implements JalviewJSApi
         }
         setCurrentAlignFrame(af);
 
-        String data = aparser.getValue(ArgsParser.COLOUR, true);
-        if (data != null)
-        {
-          data.replaceAll("%20", " ");
-
-          ColourSchemeI cs = ColourSchemeProperty.getColourScheme(
-                  af.getViewport(), af.getViewport().getAlignment(), data);
-
-          if (cs != null)
-          {
-            System.out.println(
-                    "CMD [-color " + data + "] executed successfully!");
-          }
-          af.changeColour(cs);
-        }
-
-        // Must maintain ability to use the groups flag
-        data = aparser.getValue(ArgsParser.GROUPS, true);
-        if (data != null)
-        {
-          af.parseFeaturesFile(data,
-                  AppletFormatAdapter.checkProtocol(data));
-          // System.out.println("Added " + data);
-          System.out.println(
-                  "CMD groups[-" + data + "]  executed successfully!");
-        }
-        data = aparser.getValue(ArgsParser.FEATURES, true);
-        if (data != null)
-        {
-          af.parseFeaturesFile(data,
-                  AppletFormatAdapter.checkProtocol(data));
-          // System.out.println("Added " + data);
-          System.out.println(
-                  "CMD [-features " + data + "]  executed successfully!");
-        }
-        data = aparser.getValue(ArgsParser.ANNOTATIONS, true);
-        if (data != null)
-        {
-          af.loadJalviewDataFile(data, null, null, null);
-          // System.out.println("Added " + data);
-          System.out.println(
-                  "CMD [-annotations " + data + "] executed successfully!");
-        }
-
-        // JavaScript feature
-
-        if (aparser.contains(ArgsParser.SHOWOVERVIEW))
-        {
-          af.overviewMenuItem_actionPerformed(null);
-          System.out.println("CMD [showoverview] executed successfully!");
-        }
-
-        // set or clear the sortbytree flag.
-        if (aparser.contains(ArgsParser.SORTBYTREE))
-        {
-          af.getViewport().setSortByTree(true);
-          if (af.getViewport().getSortByTree())
-          {
-            System.out.println("CMD [-sortbytree] executed successfully!");
-          }
-        }
-
-        boolean doUpdateAnnotation = false;
-        /**
-         * we do this earlier in JalviewJS because of a complication with
-         * SHOWOVERVIEW
-         * 
-         * For now, just fixing this in JalviewJS.
-         *
-         * 
-         * @j2sIgnore
-         * 
-         */
-        {
-          if (aparser.contains(ArgsParser.NOANNOTATION)
-                  || aparser.contains(ArgsParser.NOANNOTATION2))
-          {
-            af.getViewport().setShowAnnotation(false);
-            if (!af.getViewport().isShowAnnotation())
-            {
-              doUpdateAnnotation = true;
-              System.out
-                      .println("CMD no-annotation executed successfully!");
-            }
-          }
-        }
+        setFrameDependentProperties(aparser, af);
         
-        
-        if (aparser.contains(ArgsParser.NOSORTBYTREE))
-        {
-          af.getViewport().setSortByTree(false);
-          if (!af.getViewport().getSortByTree())
-          {
-            doUpdateAnnotation = true;
-            System.out
-                    .println("CMD [-nosortbytree] executed successfully!");
-          }
-        }
-        if (doUpdateAnnotation)
-        { // BH 2019.07.24
-          af.setMenusForViewport();
-          af.alignPanel.updateLayout();
-        }
-
-        data = aparser.getValue(ArgsParser.TREE, true);
-        if (data != null)
-        {
-          try
-          {
-            System.out.println(
-                    "CMD [-tree " + data + "] executed successfully!");
-            NewickFile nf = new NewickFile(data,
-                    AppletFormatAdapter.checkProtocol(data));
-            af.getViewport()
-                    .setCurrentTree(af.showNewickTree(nf, data).getTree());
-          } catch (IOException ex)
-          {
-            System.err.println("Couldn't add tree " + data);
-            ex.printStackTrace(System.err);
-          }
-        }
-        // TODO - load PDB structure(s) to alignment JAL-629
-        // (associate with identical sequence in alignment, or a specified
-        // sequence)
-        if (isJavaAppletTag)
+        if (isJS)
         {
-          loadAppletParams(aparser, af);
+          jsApp.initFromParams(af);
         }
-        else if (!isJS)
+        else
         /**
          * Java only
          * 
@@ -880,75 +767,23 @@ public class Jalview implements JalviewJSApi
             groovyscript = null;
           }
         }
-        createOutputFiles(aparser, af, format);
-        while (aparser.getSize() > 0)
-        {
-          System.out.println("Unknown arg: " + aparser.nextValue());
+        if (!isJS || !isStartup) {
+          createOutputFiles(aparser, format);
         }
       }
-    }
-    
-    
-    AlignFrame startUpAlframe = null;
-    // We'll only open the default file if the desktop is visible.
-    // And the user
-    // ////////////////////
-
-    if (!isJS && !headless && file == null
-            && Cache.getDefault("SHOW_STARTUP_FILE", true))
-    /**
-     * Java only
-     * 
-     * @j2sIgnore
-     */
-    {
-      file = Cache.getDefault("STARTUP_FILE",
-              Cache.getDefault("www.jalview.org", "http://www.jalview.org")
-                      + "/examples/exampleFile_2_7.jar");
-      if (file.equals(
-              "http://www.jalview.org/examples/exampleFile_2_3.jar"))
-      {
-        // hardwire upgrade of the startup file
-        file.replace("_2_3.jar", "_2_7.jar");
-        // and remove the stale setting
-        Cache.removeProperty("STARTUP_FILE");
-      }
-
-      protocol = DataSourceType.FILE;
-
-      if (file.indexOf("http:") > -1)
-      {
-        protocol = DataSourceType.URL;
-      }
-
-      if (file.endsWith(".jar"))
-      {
-        format = FileFormat.Jalview;
-      }
-      else
+      if (headless)
       {
-        try
-        {
-          format = new IdentifyFile().identify(file, protocol);
-        } catch (FileFormatException e)
-        {
-          // TODO what?
-        }
+        af.getViewport().getCalcManager().shutdown();
       }
-
-      startUpAlframe = fileLoader.LoadFileWaitTillLoaded(file, protocol,
-              format);
-
     }
-    
     // extract groovy arguments before anything else.
     // Once all other stuff is done, execute any groovy scripts (in order)
-    if (groovyscript != null)
+    if (!isJS && groovyscript != null)
     {
       if (Cache.groovyJarsPresent())
       {
         System.out.println("Executing script " + groovyscript);
-        executeGroovyScript(groovyscript, startUpAlframe);
+        executeGroovyScript(groovyscript, af);
       }
       else
       {
@@ -967,67 +802,219 @@ public class Jalview implements JalviewJSApi
       }
       desktop.setInBatchMode(false);
     }
+    
+    if (jsApp != null) {
+      jsApp.callInitCallback();
+    }
   }
-
+  
   /**
-   * Writes an output file for each format (if any) specified in the
-   * command-line arguments. Supported formats are currently
-   * <ul>
-   * <li>png</li>
-   * <li>svg</li>
-   * <li>html</li>
-   * <li>biojsmsa</li>
-   * <li>imgMap</li>
-   * <li>eps</li>
-   * </ul>
-   * A format parameter should be followed by a parameter specifying the output
-   * file name. {@code imgMap} parameters should follow those for the
-   * corresponding alignment image output.
+   * Set general display parameters irrespective of file loading or headlessness.
    * 
    * @param aparser
-   * @param af
-   * @param format
    */
-  private void createOutputFiles(ArgsParser aparser, AlignFrame af,
-          FileFormatI format)
+  private void setDisplayParameters(ArgsParser aparser)
   {
-    String imageName = "unnamed.png";
-    while (aparser.getSize() > 1)
+    if (aparser.contains(ArgsParser.NOMENUBAR))
     {
-      String outputFormat = aparser.nextValue();
-      String file = aparser.nextValue();
+      noMenuBar = true;
+      System.out.println("CMD [nomenu] executed successfully!");
+    }
+
+    if (aparser.contains(ArgsParser.NOSTATUS))
+    {
+      noStatus = true;
+      System.out.println("CMD [nostatus] executed successfully!");
+    }
+
+    if (aparser.contains(ArgsParser.NOANNOTATION)
+            || aparser.contains(ArgsParser.NOANNOTATION2))
+    {
+      noAnnotation = true;
+      System.out.println("CMD no-annotation executed successfully!");
+    }
+    if (aparser.contains(ArgsParser.NOCALCULATION))
+    {
+      noCalculation = true;
+      System.out.println("CMD [nocalculation] executed successfully!");
+    }
+  }
+
 
-      if (outputFormat.equalsIgnoreCase("png"))
+  private void setFrameDependentProperties(ArgsParser aparser,
+          AlignFrame af)
+  {
+    String data = aparser.getValue(ArgsParser.COLOUR, true);
+    if (data != null)
+    {
+      data.replaceAll("%20", " ");
+
+      ColourSchemeI cs = ColourSchemeProperty.getColourScheme(
+              af.getViewport(), af.getViewport().getAlignment(), data);
+
+      if (cs != null)
       {
-        af.createPNG(new File(file));
-        imageName = (new File(file)).getName();
-        System.out.println("Creating PNG image: " + file);
-        continue;
+        System.out.println(
+                "CMD [-color " + data + "] executed successfully!");
       }
-      else if (outputFormat.equalsIgnoreCase("svg"))
+      af.changeColour(cs);
+    }
+
+    // Must maintain ability to use the groups flag
+    data = aparser.getValue(ArgsParser.GROUPS, true);
+    if (data != null)
+    {
+      af.parseFeaturesFile(data,
+              AppletFormatAdapter.checkProtocol(data));
+      // System.out.println("Added " + data);
+      System.out.println(
+              "CMD groups[-" + data + "]  executed successfully!");
+    }
+    data = aparser.getValue(ArgsParser.FEATURES, true);
+    if (data != null)
+    {
+      af.parseFeaturesFile(data,
+              AppletFormatAdapter.checkProtocol(data));
+      // System.out.println("Added " + data);
+      System.out.println(
+              "CMD [-features " + data + "]  executed successfully!");
+    }
+    data = aparser.getValue(ArgsParser.ANNOTATIONS, true);
+    if (data != null)
+    {
+      af.loadJalviewDataFile(data, null, null, null);
+      // System.out.println("Added " + data);
+      System.out.println(
+              "CMD [-annotations " + data + "] executed successfully!");
+    }
+
+    // JavaScript feature
+
+    if (aparser.contains(ArgsParser.SHOWOVERVIEW))
+    {
+      af.overviewMenuItem_actionPerformed(null);
+      System.out.println("CMD [showoverview] executed successfully!");
+    }
+
+    // set or clear the sortbytree flag.
+    if (aparser.contains(ArgsParser.SORTBYTREE))
+    {
+      af.getViewport().setSortByTree(true);
+      if (af.getViewport().getSortByTree())
       {
-        File imageFile = new File(file);
-        imageName = imageFile.getName();
-        af.createSVG(imageFile);
-        System.out.println("Creating SVG image: " + file);
-        continue;
-      }
-      else if (outputFormat.equalsIgnoreCase("html"))
-      {
-        File imageFile = new File(file);
-        imageName = imageFile.getName();
-        HtmlSvgOutput htmlSVG = new HtmlSvgOutput(af.alignPanel);
-        htmlSVG.exportHTML(file);
-        System.out.println("Creating HTML image: " + file);
-        continue;
+        System.out.println("CMD [-sortbytree] executed successfully!");
       }
-      else if (outputFormat.equalsIgnoreCase("biojsmsa"))
+    }
+
+    boolean doUpdateAnnotation = false;
+    /**
+     * we do this earlier in JalviewJS because of a complication with
+     * SHOWOVERVIEW
+     * 
+     * For now, just fixing this in JalviewJS.
+     *
+     * 
+     * @j2sIgnore
+     * 
+     */
+    {
+      if (noAnnotation)
       {
-        if (file == null)
+        af.getViewport().setShowAnnotation(false);
+        if (!af.getViewport().isShowAnnotation())
         {
-          System.err.println("The output html file must not be null");
-          return;
+          doUpdateAnnotation = true;
         }
+      }
+    }
+
+    if (aparser.contains(ArgsParser.NOSORTBYTREE))
+    {
+      af.getViewport().setSortByTree(false);
+      if (!af.getViewport().getSortByTree())
+      {
+        doUpdateAnnotation = true;
+        System.out
+                .println("CMD [-nosortbytree] executed successfully!");
+      }
+    }
+    if (doUpdateAnnotation)
+    { // BH 2019.07.24
+      af.setMenusForViewport();
+      af.alignPanel.updateLayout();
+    }
+
+    data = aparser.getValue(ArgsParser.TREE, true);
+    if (data != null)
+    {
+      try
+      {
+        NewickFile nf = new NewickFile(data,
+                AppletFormatAdapter.checkProtocol(data));
+        af.getViewport()
+                .setCurrentTree(af.showNewickTree(nf, data).getTree());
+        System.out.println(
+                "CMD [-tree " + data + "] executed successfully!");
+      } catch (IOException ex)
+      {
+        System.err.println("Couldn't add tree " + data);
+        ex.printStackTrace(System.err);
+      }
+    }
+    // TODO - load PDB structure(s) to alignment JAL-629
+    // (associate with identical sequence in alignment, or a specified
+    // sequence)
+
+  }
+
+  /**
+   * Writes an output file for each format (if any) specified in the
+   * command-line arguments. Supported formats are currently
+   * <ul>
+   * <li>png</li>
+   * <li>svg</li>
+   * <li>html</li>
+   * <li>biojsmsa</li>
+   * <li>imgMap</li>
+   * <li>eps</li>
+   * </ul>
+   * A format parameter should be followed by a parameter specifying the output
+   * file name. {@code imgMap} parameters should follow those for the
+   * corresponding alignment image output.
+   * 
+   * @param aparser
+   * @param format
+   */
+  private void createOutputFiles(ArgsParser aparser, FileFormatI format)
+  {
+    AlignFrame af = currentAlignFrame;
+    while (aparser.getSize() >= 2)
+    {
+      String outputFormat = aparser.nextValue();
+      File imageFile;
+      String fname;
+      switch (outputFormat.toLowerCase())
+      {
+      case "png":
+        imageFile = new File(aparser.nextValue());
+        af.createPNG(imageFile);
+        System.out.println(
+                "Creating PNG image: " + imageFile.getAbsolutePath());
+        continue;
+      case "svg":
+        imageFile = new File(aparser.nextValue());
+        af.createSVG(imageFile);
+        System.out.println(
+                "Creating SVG image: " + imageFile.getAbsolutePath());
+        continue;
+      case "eps":
+        imageFile = new File(aparser.nextValue());
+        System.out.println(
+                "Creating EPS file: " + imageFile.getAbsolutePath());
+        af.createEPS(imageFile);
+        continue;
+      case "biojsmsa":
+        fname = new File(aparser.nextValue()).getAbsolutePath();
         try
         {
           BioJsHTMLOutput.refreshVersionInfo(
@@ -1037,39 +1024,68 @@ public class Jalview implements JalviewJSApi
           e.printStackTrace();
         }
         BioJsHTMLOutput bjs = new BioJsHTMLOutput(af.alignPanel);
-        bjs.exportHTML(file);
-        System.out.println("Creating BioJS MSA Viwer HTML file: " + file);
+        bjs.exportHTML(fname);
+        System.out.println("Creating BioJS MSA Viwer HTML file: " + fname);
         continue;
-      }
-      else if (outputFormat.equalsIgnoreCase("imgMap"))
-      {
-        af.createImageMap(new File(file), imageName);
-        System.out.println("Creating image map: " + file);
+      case "html":
+        fname = new File(aparser.nextValue()).getAbsolutePath();
+        HtmlSvgOutput htmlSVG = new HtmlSvgOutput(af.alignPanel);
+        htmlSVG.exportHTML(fname);
+        System.out.println("Creating HTML image: " + fname);
         continue;
-      }
-      else if (outputFormat.equalsIgnoreCase("eps"))
-      {
-        File outputFile = new File(file);
+      case "imgmap":
+        imageFile = new File(aparser.nextValue());
+        af.alignPanel.makePNGImageMap(imageFile, "unnamed.png");
         System.out.println(
-                "Creating EPS file: " + outputFile.getAbsolutePath());
-        af.createEPS(outputFile);
+                "Creating image map: " + imageFile.getAbsolutePath());
         continue;
+      default:
+        // fall through - try to parse as an alignment data export format
+        FileFormatI outFormat = null;
+        try
+        {
+          outFormat = FileFormats.getInstance().forName(outputFormat);
+        } catch (Exception formatP)
+        {
+        }
+        if (outFormat == null)
+        {
+          System.out.println("Couldn't parse " + outputFormat
+                  + " as a valid Jalview format string.");
+          continue;
+        }
+        if (!outFormat.isWritable())
+        {
+          System.out.println(
+                  "This version of Jalview does not support alignment export as "
+                          + outputFormat);
+          continue;
+        }
+        // record file as it was passed to Jalview so it is recognisable to the CLI
+        // caller
+        String file;
+        fname = new File(file = aparser.nextValue()).getAbsolutePath();
+        // JBPNote - yuck - really wish we did have a bean returned from this which gave
+        // success/fail like before !
+        af.saveAlignment(fname, outFormat);
+        if (!af.isSaveAlignmentSuccessful())
+        {
+          System.out.println("Written alignment in " + outputFormat
+                  + " format to " + file);
+          continue;
+        }
+        else
+        {
+          System.out.println("Error writing file " + file + " in "
+                  + outputFormat + " format!!");
+        }
       }
-
-      af.saveAlignment(file, format);
-      if (af.isSaveAlignmentSuccessful())
-      {
-        System.out.println(
-                "Written alignment in " + format + " format to " + file);
-      }
-      else
-      {
-        System.out.println("Error writing file " + file + " in " + format
-                + " format!!");
-      }
-
     }
-
+    // ??? Should report - 'ignoring' extra args here...
+    while (aparser.getSize() > 0)
+    {
+      System.out.println("Ignoring extra argument: " + aparser.nextValue());
+    }
   }
 
   private static void showUsage()
@@ -1118,7 +1134,7 @@ public class Jalview implements JalviewJSApi
     /**
      * start a User Config prompt asking if we can log usage statistics.
      */
-    PromptUserConfig prompter = new PromptUserConfig(Desktop.desktop,
+    PromptUserConfig prompter = new PromptUserConfig(Desktop.getDesktopPane(),
             "USAGESTATS", "Jalview Usage Statistics",
             "Do you want to help make Jalview better by enabling "
                     + "the collection of usage statistics with Google Analytics ?"
@@ -1297,813 +1313,32 @@ public class Jalview implements JalviewJSApi
 
   public static AlignFrame getCurrentAlignFrame()
   {
-    return Jalview.currentAlignFrame;
+    return Jalview.getInstance().currentAlignFrame;
   }
 
   public static void setCurrentAlignFrame(AlignFrame currentAlignFrame)
   {
-    Jalview.currentAlignFrame = currentAlignFrame;
-  }
-
-  /**
-   * Get the SwingJS applet ID and combine that with the frameType
-   * 
-   * @param frameType
-   *          "alignment", "desktop", etc., or null
-   * @return
-   */
-  public static String getAppID(String frameType)
-  {
-    String id = Cache.getProperty("Info.j2sAppletID");
-    if (id == null)
-    {
-      id = "jalview";
-    }
-    return id + (frameType == null ? "" : "-" + frameType);
-  }
-
-  /**
-   * Handle all JalviewLite applet parameters
-   * 
-   * @param aparser
-   * @param af
-   */
-  private void loadAppletParams(ArgsParser aparser, AlignFrame af)
-  {
-    JalviewApp app = new JalviewApp()
-    {
-
-      // TODO BH 2019
-      //
-      // These are methods that are in JalviewLite that various classes call
-      // but are not in JalviewLiteJsApi. Or, even if they are, other classes
-      // call
-      // them to JalviewLite directly. Some may not be necessary, but they have
-      // to
-      // be at least mentioned here, or the classes calling them should
-      // reference
-      // JalviewLite itself.
-
-      private boolean alignPDBStructures; // From JalviewLite; not implemented
-
-      private Hashtable<String, Hashtable<String, String[]>> jsmessages;
-
-      private Hashtable<String, int[]> jshashes;
-
-      @Override
-      public String getParameter(String name)
-      {
-        return aparser.getAppletValue(name, null);
-      }
-
-      @Override
-      public boolean getDefaultParameter(String name, boolean def)
-      {
-        String stn;
-        return ((stn = getParameter(name)) == null ? def
-                : "true".equalsIgnoreCase(stn));
-      }
-
-      /**
-       * Get the applet-like document base even though this is an application.
-       */
-      @Override
-      public URL getDocumentBase()
-      {
-        return Platform.getDocumentBase();
-      }
-
-      /**
-       * Get the applet-like code base even though this is an application.
-       */
-      @Override
-      public URL getCodeBase()
-      {
-        return Platform.getCodeBase();
-      }
-
-      @Override
-      public AlignViewportI getViewport()
-      {
-        return af.getViewport();
-      }
-
-      /**
-       * features
-       * 
-       */
-      @Override
-      public boolean parseFeaturesFile(String filename,
-              DataSourceType protocol)
-      {
-        return af.parseFeaturesFile(filename, protocol);
-      }
-
-      /**
-       * scorefile
-       * 
-       */
-      @Override
-      public boolean loadScoreFile(String sScoreFile) throws IOException
-      {
-        af.loadJalviewDataFile(sScoreFile, null, null, null);
-        return true;
-      }
-
-      /**
-       * annotations, jpredfile, jnetfile
-       * 
-       */
-      @Override
-      public void updateForAnnotations()
-      {
-        af.updateForAnnotations();
-      }
-
-      @Override
-      public void loadTree(NewickFile fin, String treeFile)
-              throws IOException
-      {
-        // n/a -- already done by standard Jalview command line processing
-      }
-
-      @Override
-      public void setAlignPdbStructures(boolean defaultParameter)
-      {
-        alignPDBStructures = true;
-      }
-
-      @Override
-      public void newStructureView(PDBEntry pdb, SequenceI[] seqs,
-              String[] chains, DataSourceType protocol)
-      {
-        StructureViewer.launchStructureViewer(af.alignPanel, pdb, seqs);
-      }
-
-      @Override
-      public void setFeatureGroupState(String[] groups, boolean state)
-      {
-        af.setFeatureGroupState(groups, state);
-      }
-
-      @Override
-      public void alignedStructureView(PDBEntry[] pdb, SequenceI[][] seqs,
-              String[][] chains, String[] protocols)
-      {
-        System.err.println(
-                "Jalview applet interface alignedStructureView not implemented");
-      }
-
-      @Override
-      public void newFeatureSettings()
-      {
-        System.err.println(
-                "Jalview applet interface newFeatureSettings not implemented");
-      }
-
-      private Vector<Runnable> jsExecQueue;
-
-      @Override
-      public Vector<Runnable> getJsExecQueue(JSFunctionExec exec)
-      {
-        jsFunctionExec = exec;
-        return (jsExecQueue == null ? (jsExecQueue = new Vector<>())
-                : jsExecQueue);
-      }
-
-// AppletContext deprecated 
-//
-//      @Override
-//      public AppletContext getAppletContext()
-//      {
-//        // TODO Auto-generated method stub
-//        return null;
-//      }
-//
-      @Override
-      public boolean isJsfallbackEnabled()
-      {
-        // TODO Auto-generated method stub
-        return false;
-      }
-
-      @Override
-      public JSObject getJSObject()
-      {
-        // TODO Auto-generated method stub
-        return null;
-      }
-
-      @Override
-      public StructureSelectionManagerProvider getStructureSelectionManagerProvider()
-      {
-        // TODO Q: what exactly is this? BH
-        return null;
-      }
-
-      @Override
-      public void updateColoursFromMouseOver(Object source,
-              MouseOverStructureListener mouseOverStructureListener)
-      {
-        // TODO Auto-generated method stub
-
-      }
-
-      @Override
-      public Object[] getSelectionForListener(SequenceGroup seqsel,
-              ColumnSelection colsel, HiddenColumns hidden,
-              SelectionSource source, Object alignFrame)
-      {
-        return appLoader.getSelectionForListener(getCurrentAlignFrame(),
-                seqsel, colsel, hidden, source, alignFrame);
-      }
-
-      @Override
-      public String arrayToSeparatorList(String[] array)
-      {
-        return appLoader.arrayToSeparatorList(array);
-      }
-
-      @Override
-      public Hashtable<String, int[]> getJSHashes()
-      {
-        return (jshashes == null ? (jshashes = new Hashtable<>())
-                : jshashes);
-      }
-
-      @Override
-      public Hashtable<String, Hashtable<String, String[]>> getJSMessages()
-      {
-        return (jsmessages == null ? (jsmessages = new Hashtable<>())
-                : jsmessages);
-      }
-
-      @Override
-      public Object getFrameForSource(VamsasSource source)
-      {
-        if (source != null)
-        {
-          AlignFrame af;
-          if (source instanceof jalview.gui.AlignViewport
-                  && source == (af = getCurrentAlignFrame()).getViewport())
-          {
-            // should be valid if it just generated an event!
-            return af;
-          }
-          // TODO: ensure that if '_af' is specified along with a handler
-          // function, then only events from that alignFrame are sent to that
-          // function
-        }
-        return null;
-      }
-
-      @Override
-      public FeatureRenderer getNewFeatureRenderer(AlignViewportI vp)
-      {
-        return new jalview.gui.FeatureRenderer((AlignmentPanel) vp);
-      }
-
-    };
-
-    appLoader = new JalviewAppLoader(true);
-    appLoader.load(app);
-  }
-
-  /**
-   * 
-   * @see jalview.bin.JalviewLiteJsApi#getSelectedSequences()
-   */
-  @Override
-  public String getSelectedSequences()
-  {
-    return getSelectedSequencesFrom(getCurrentAlignFrame());
+    Jalview.getInstance().currentAlignFrame = currentAlignFrame;
   }
 
-  /**
-   * 
-   * @see jalview.bin.JalviewLiteJsApi#getSelectedSequences(java.lang.String)
-   */
-  @Override
-  public String getSelectedSequences(String sep)
-  {
-    return getSelectedSequencesFrom(getCurrentAlignFrame(), sep);
-  }
-
-  /**
-   * 
-   * @see jalview.bin.JalviewLiteJsApi#getSelectedSequencesFrom(jalview.appletgui
-   *      .AlignFrame)
-   */
-  @Override
-  public String getSelectedSequencesFrom(AlignFrame alf)
-  {
-    if (alf == null)
-    {
-      alf = getCurrentAlignFrame();
-    }
-    return getSelectedSequencesFrom(alf, null);
-  }
-
-  /**
-   * 
-   * @see jalview.bin.JalviewLiteJsApi#getSelectedSequencesFrom(jalview.appletgui
-   *      .AlignFrame, java.lang.String)
-   */
-  @Override
-  public String getSelectedSequencesFrom(AlignFrame alf, String sep)
-  {
-    if (alf == null)
-    {
-      alf = getCurrentAlignFrame();
-    }
-    return appLoader.getSelectedSequencesFrom(alf, sep);
-  }
-
-  /**
-   * 
-   * @see jalview.bin.JalviewLiteJsApi#getSelectedSequencesFrom(jalview.appletgui
-   *      .AlignFrame, java.lang.String)
-   */
-  @Override
-  public void highlight(String sequenceId, String position,
-          String alignedPosition)
-  {
-    highlightIn(null, sequenceId, position, alignedPosition);
-  }
-
-  @Override
-  public void highlightIn(AlignFrame alf, String sequenceId,
-          String position, String alignedPosition)
-  {
-    if (alf == null)
-    {
-      alf = getCurrentAlignFrame();
-    }
-    appLoader.highlightIn(alf, sequenceId, position, alignedPosition);
-  }
-
-  @Override
-  public void select(String sequenceIds, String columns)
-  {
-    selectIn(getCurrentAlignFrame(), sequenceIds, columns, null);
-  }
-
-  @Override
-  public void select(String sequenceIds, String columns, String sep)
-  {
-    selectIn(null, sequenceIds, columns, sep);
-  }
-
-  @Override
-  public void selectIn(AlignFrame alf, String sequenceIds, String columns)
-  {
-    selectIn(alf, sequenceIds, columns, null);
-  }
-
-  @Override
-  public void selectIn(AlignFrame alf, String sequenceIds, String columns,
-          String sep)
-  {
-    if (alf == null)
-    {
-      alf = getCurrentAlignFrame();
-    }
-    appLoader.selectIn(alf, sequenceIds, columns, sep);
-  }
-
-  @Override
-  public String getSelectedSequencesAsAlignment(String format,
-          String suffix)
-  {
-    return getSelectedSequencesAsAlignmentFrom(null, format, suffix);
-  }
-
-  @Override
-  public String getSelectedSequencesAsAlignmentFrom(AlignFrame alf,
-          String format, String sep)
-  {
-    if (alf == null)
-    {
-      alf = getCurrentAlignFrame();
-    }
-    return appLoader.getSelectedSequencesAsAlignmentFrom(alf, format, sep);
-  }
-
-  @Override
-  public String getAlignmentOrder()
-  {
-    return getAlignmentFrom(getCurrentAlignFrame(), null);
-  }
-
-  @Override
-  public String getAlignmentOrderFrom(AlignFrame alf)
-  {
-    return getAlignmentFrom(alf, null);
-  }
-
-  @Override
-  public String getAlignmentOrderFrom(AlignFrame alf, String sep)
-  {
-    if (alf == null)
-    {
-      alf = getCurrentAlignFrame();
-    }
-    return appLoader.getAlignmentOrderFrom(alf, sep);
-  }
-
-  @Override
-  public String orderBy(String order, String undoName)
-  {
-    return orderBy(order, undoName, null);
-  }
-
-  @Override
-  public String orderBy(String order, String undoName, String sep)
-  {
-    return orderAlignmentBy(getCurrentAlignFrame(), order, undoName, sep);
-  }
-
-  @Override
-  public String orderAlignmentBy(AlignFrame alf, String order,
-          String undoName, String sep)
-  {
-    if (alf == null)
-    {
-      alf = getCurrentAlignFrame();
-    }
-    return appLoader.orderAlignmentBy(alf, order, undoName, sep);
-  }
-
-  @Override
-  public String getAlignment(String format)
-  {
-    return getAlignmentFrom(null, format, null);
-  }
-
-  @Override
-  public String getAlignmentFrom(AlignFrame alf, String format)
-  {
-    return getAlignmentFrom(alf, format, null);
-  }
-
-  @Override
-  public String getAlignment(String format, String suffix)
-  {
-    return getAlignmentFrom(getCurrentAlignFrame(), format, suffix);
-  }
-
-  @Override
-  public String getAlignmentFrom(AlignFrame alf, String format,
-          String suffix)
-  {
-    return appLoader.getAlignmentFrom(alf, format, suffix);
-  }
-
-  @Override
-  public void loadAnnotation(String annotation)
-  {
-    loadAnnotationFrom(getCurrentAlignFrame(), annotation);
-  }
-
-  @Override
-  public void loadAnnotationFrom(AlignFrame alf, String annotation)
-  {
-    if (alf == null)
-    {
-      alf = getCurrentAlignFrame();
-    }
-    appLoader.loadAnnotationFrom(alf, annotation);
-  }
-
-  @Override
-  public void loadFeatures(String features, boolean autoenabledisplay)
-  {
-    loadFeaturesFrom(currentAlignFrame, features, autoenabledisplay);
-  }
-
-  @Override
-  public boolean loadFeaturesFrom(AlignFrame alf, String features,
-          boolean autoenabledisplay)
-  {
-    if (alf == null)
-    {
-      alf = getCurrentAlignFrame();
-    }
-    return appLoader.loadFeaturesFrom(alf, features, autoenabledisplay);
-  }
-
-  @Override
-  public String getFeatures(String format)
-  {
-    return getFeaturesFrom(null, format);
-  }
-
-  @Override
-  public String getFeaturesFrom(AlignFrame alf, String format)
-  {
-    if (alf == null)
-    {
-      alf = getCurrentAlignFrame();
-    }
-    return appLoader.getFeaturesFrom(alf, format);
-  }
-
-  @Override
-  public String getAnnotation()
-  {
-    return getAnnotationFrom(null);
-  }
-
-  @Override
-  public String getAnnotationFrom(AlignFrame alf)
-  {
-    if (alf == null)
-    {
-      alf = getCurrentAlignFrame();
-    }
-    return appLoader.getAnnotationFrom(alf);
-  }
-
-  // @Override
-  // public AlignFrame newView()
-  // {
-  // return newViewFrom(null, null);
-  // }
-  //
-  // @Override
-  // public AlignFrame newView(String name)
-  // {
-  // return newViewFrom(null, name);
-  // }
-  //
-  // @Override
-  // public AlignFrame newViewFrom(AlignFrame alf)
-  // {
-  // return newViewFrom(alf, null);
-  // }
-  //
-  // @Override
-  // public AlignFrame newViewFrom(AlignFrame alf, String name)
-  // {
-  // if (alf == null)
-  // {
-  // alf = getCurrentAlignFrame();
-  // }
-  // return appLoader.newViewFrom(alf, name);
-  // }
-
-  @Override
-  public AlignFrame loadAlignment(String text, String title)
-  {
-    return appLoader.loadAlignment(text, AlignFrame.DEFAULT_WIDTH,
-            AlignFrame.DEFAULT_HEIGHT, title);
-  }
-
-  @Override
-  public boolean addPdbFile(AlignFrame alFrame, String sequenceId,
-          String pdbEntryString, String pdbFile)
-  {
-    if (alFrame == null)
-    {
-      alFrame = getCurrentAlignFrame();
-    }
-    return appLoader.addPdbFile(alFrame, sequenceId, pdbEntryString,
-            pdbFile);
-  }
-
-  @Override
-  public void scrollViewToIn(AlignFrame alf, String topRow,
-          String leftHandColumn)
-  {
-    if (alf == null)
-    {
-      alf = getCurrentAlignFrame();
-    }
-    appLoader.scrollViewToIn(alf, topRow, leftHandColumn);
-  }
-
-  @Override
-  public void scrollViewToRowIn(AlignFrame alf, String topRow)
-  {
-    if (alf == null)
-    {
-      alf = getCurrentAlignFrame();
-    }
-    appLoader.scrollViewToRowIn(alf, topRow);
-  }
-
-  @Override
-  public void scrollViewToColumnIn(AlignFrame alf, String leftHandColumn)
-  {
-    if (alf == null)
-    {
-      alf = getCurrentAlignFrame();
-    }
-    appLoader.scrollViewToColumnIn(alf, leftHandColumn);
-  }
-
-  @Override
-  public String getFeatureGroups()
-  {
-    return getFeatureGroupsOn(null);
-  }
-
-  @Override
-  public String getFeatureGroupsOn(AlignFrame alf)
-  {
-    if (alf == null)
-    {
-      alf = getCurrentAlignFrame();
-    }
-    return appLoader.getFeatureGroupsOn(alf);
-  }
-
-  @Override
-  public String getFeatureGroupsOfState(boolean visible)
-  {
-    return getFeatureGroupsOfStateOn(null, visible);
-  }
-
-  @Override
-  public String getFeatureGroupsOfStateOn(AlignFrame alf, boolean visible)
-  {
-    if (alf == null)
-    {
-      alf = getCurrentAlignFrame();
-    }
-    return appLoader.getFeatureGroupsOfStateOn(alf, visible);
-  }
-
-  @Override
-  public void setFeatureGroupState(String groups, boolean state)
-  { // JalviewLite API
-    setFeatureGroupStateOn(null, groups, state);
-  }
-
-  @Override
-  public void setFeatureGroupStateOn(AlignFrame alf, String groups,
-          boolean state)
-  {
-    if (alf == null)
-    {
-      alf = getCurrentAlignFrame();
-    }
-    appLoader.setFeatureGroupStateOn(alf, groups, state);
-  }
-
-  @Override
-  public String getSeparator()
-  {
-    return appLoader.getSeparator();
-  }
-
-  @Override
-  public void setSeparator(String separator)
-  {
-    appLoader.setSeparator(separator);
-  }
-
-  @Override
-  public String getJsMessage(String messageclass, String viewId)
-  {
-    // see http://www.jalview.org/examples/jalviewLiteJs.html
-    return null;
-  }
-
-  /**
-   * Open a new Tree panel on the desktop statically. Params are standard (not
-   * set by Groovy). No dialog is opened.
-   * 
-   * @param af
-   * @param treeType
-   * @param modelName
-   * @return null, or the string "label.you_need_at_least_n_sequences" if number
-   *         of sequences selected is inappropriate
-   */
-  @Override
-  public Object openTreePanel(AlignFrame af, String treeType,
-          String modelName)
-  { // JalviewJS api
-    if (af == null)
-    {
-      af = getCurrentAlignFrame();
-    }
-    return CalculationChooser.openTreePanel(af, treeType, modelName, null);
-  }
-
-  /**
-   * public static method for JalviewJS API to open a PCAPanel without
-   * necessarily using a dialog.
-   * 
-   * @param af
-   * @param modelName
-   * @return the PCAPanel, or the string "label.you_need_at_least_n_sequences"
-   *         if number of sequences selected is inappropriate
-   */
-  @Override
-  public Object openPcaPanel(AlignFrame af, String modelName)
-  {
-    if (af == null)
-    {
-      af = getCurrentAlignFrame();
-    }
-    return CalculationChooser.openPcaPanel(af, modelName, null);
-  }
-
-  @Override
-  public String getSelectedSequencesAsAlignment(String format,
-          boolean suffix)
-  {
-    return getSelectedSequencesAsAlignmentFrom(null, format, suffix);
-  }
-
-  @Override
-  public String getSelectedSequencesAsAlignmentFrom(AlignFrame alf,
-          String format, boolean suffix)
-  {
-    if (alf == null)
-    {
-      alf = getCurrentAlignFrame();
-    }
-    return appLoader.getSelectedSequencesAsAlignmentFrom(alf, format,
-            "" + suffix);
-  }
-
-  @Override
-  public String arrayToSeparatorList(String[] array)
-  {
-    return appLoader.arrayToSeparatorList(array);
-  }
-
-  @Override
-  public String[] separatorListToArray(String list)
-  {
-    return appLoader.separatorListToArray(list);
-  }
-
-  //// probably not needed in JalviewJS -- From when Jmol and Jalview did not
-  //// have a direct connection?
-
-  @Override
-  public void setMouseoverListener(String listener)
-  {
-    // TODO Auto-generated method stub
-
-  }
-
-  @Override
-  public void setMouseoverListener(AlignFrame af, String listener)
-  {
-    // TODO Auto-generated method stub
-
-  }
-
-  @Override
-  public void setSelectionListener(String listener)
-  {
-    // TODO Auto-generated method stub
-
-  }
-
-  @Override
-  public void setSelectionListener(AlignFrame af, String listener)
-  {
-    // TODO Auto-generated method stub
-
-  }
-
-  @Override
-  public void setStructureListener(String listener, String modelSet)
-  {
-    // TODO Auto-generated method stub
-
-  }
-
-  @Override
-  public void removeJavascriptListener(AlignFrame af, String listener)
+  
+  public void notifyWorker(AlignCalcWorkerI worker, String status)
   {
-    // TODO Auto-generated method stub
-
+    // System.out.println("Jalview worker " + worker.getClass().getSimpleName()
+    // + " " + status);
   }
 
-  @Override
-  public void mouseOverStructure(String pdbResNum, String chain,
-          String pdbfile)
-  {
-    // TODO Auto-generated method stub
 
-  }
+  private static boolean isInteractive = true;
 
-  @Override
-  public void showOverview()
+  public static boolean isInteractive()
   {
-    currentAlignFrame.overviewMenuItem_actionPerformed(null);
+    return isInteractive;
   }
 
-  public void notifyWorker(AlignCalcWorkerI worker, String status)
+  public static void setInteractive(boolean tf)
   {
-    // System.out.println("Jalview worker " + worker.getClass().getSimpleName()
-    // + " " + status);
+    isInteractive = tf;
   }
 
 }