JAL-845 first rough applet SplitFrame (add parameter file2)
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Fri, 13 Feb 2015 17:10:22 +0000 (17:10 +0000)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Fri, 13 Feb 2015 17:10:22 +0000 (17:10 +0000)
help/html/features/multipleViews.html
resources/lang/Messages.properties
src/jalview/appletgui/AlignFrame.java
src/jalview/appletgui/AlignmentPanel.java
src/jalview/appletgui/EmbmenuFrame.java
src/jalview/appletgui/SplitFrame.java [new file with mode: 0644]
src/jalview/bin/JalviewLite.java
src/jalview/gui/AlignFrame.java
src/jalview/gui/SplitFrame.java

index b1ccf4b..725f9d0 100644 (file)
@@ -47,8 +47,8 @@ something more meaningful.</p>
 as tabs within a single alignment window. They can be viewed
 simultanously by pressing <strong>X</strong> (or via <strong>&quot;View&#8594;Expand&quot;</strong>)
 to expand each view into its own linked alignment window. Expanded views
-are gathered back into into a single tabbed alignment window by pressing
-<strong>G</strong>, or by selecting <strong>&quot;View&#8594;Gather&quot;</strong>).
+are gathered back into a single tabbed alignment window by pressing
+<strong>G</strong>, or by selecting <strong>&quot;View&#8594;Gather&quot;</strong>.
 </p>
 <p><strong>Hidden Sequence Representatives and Multiple
 Views</strong></p>
index 0319c9d..801d7a0 100644 (file)
@@ -237,6 +237,7 @@ label.except_selected_sequences = All except selected sequences
 label.all_but_selected_region = All but Selected Region (Shift+Ctrl+H)
 label.selected_region = Selected Region
 label.all_sequences_columns = All Sequences and Columns
+label.hide_insertions = Hide columns gapped for selection
 label.hide_selected_annotations = Hide selected annotations
 label.show_selected_annotations = Show selected annotations
 label.group_consensus = Group Consensus
@@ -1217,4 +1218,4 @@ label.search_filter = Search Filter
 label.display_name = Display Label
 label.description = Description
 label.include_description= Include Description
-
+label.start_jalview = Start Jalview
index 5599695..aa7aed3 100644 (file)
@@ -113,9 +113,33 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
 
   String jalviewServletURL;
 
-  public AlignFrame(AlignmentI al, jalview.bin.JalviewLite applet,
+  /**
+   * Constructor that creates the frame and adds it to the display.
+   * 
+   * @param al
+   * @param applet
+   * @param title
+   * @param embedded
+   */
+  public AlignFrame(AlignmentI al, JalviewLite applet,
           String title, boolean embedded)
   {
+    this(al, applet, title, embedded, true);
+  }
+
+  /**
+   * Constructor that optionally allows the frame to be displayed or only
+   * created.
+   * 
+   * @param al
+   * @param applet
+   * @param title
+   * @param embedded
+   * @param addToDisplay
+   */
+  public AlignFrame(AlignmentI al, JalviewLite applet,
+          String title, boolean embedded, boolean addToDisplay)
+  {
     if (applet != null)
     {
       jalviewServletURL = applet.getParameter("APPLICATION_URL");
@@ -233,8 +257,19 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     alignPanel.annotationPanelHolder.addKeyListener(this);
     alignPanel.annotationSpaceFillerHolder.addKeyListener(this);
     alignPanel.alabels.addKeyListener(this);
-    createAlignFrameWindow(embedded, title);
 
+    if (addToDisplay)
+    {
+      addToDisplay(embedded);
+    }
+  }
+
+  /**
+   * @param embedded
+   */
+  public void addToDisplay(boolean embedded)
+  {
+    createAlignFrameWindow(embedded);
     validate();
     alignPanel.adjustAnnotationHeight();
     alignPanel.paintAlignment(true);
@@ -3515,46 +3550,11 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
    *          true to attach the view to the applet area on the page rather than
    *          in a new window
    */
-  public void createAlignFrameWindow(boolean reallyEmbedded, String title)
+  public void createAlignFrameWindow(boolean reallyEmbedded)
   {
     if (reallyEmbedded)
     {
-      // ////
-      // Explicly build the embedded menu panel for the on-page applet
-      //
-      // view cannot be closed if its actually on the page
-      fileMenu.remove(closeMenuItem);
-      fileMenu.remove(3); // Remove Seperator
-      embeddedMenu = makeEmbeddedPopupMenu(alignFrameMenuBar, "Arial",
-              Font.PLAIN, 11, false); // use our own fonts.
-      // and actually add the components to the applet area
-      viewport.applet.setLayout(new BorderLayout());
-      viewport.applet.add(embeddedMenu, BorderLayout.NORTH);
-      viewport.applet.add(statusBar, BorderLayout.SOUTH);
-      alignPanel.setSize(viewport.applet.getSize().width,
-              viewport.applet.getSize().height - embeddedMenu.HEIGHT
-                      - statusBar.HEIGHT);
-      viewport.applet.add(alignPanel, BorderLayout.CENTER);
-      final AlignFrame me = this;
-      viewport.applet.addFocusListener(new FocusListener()
-      {
-
-        @Override
-        public void focusLost(FocusEvent e)
-        {
-          if (me.viewport.applet.currentAlignFrame == me)
-          {
-            me.viewport.applet.currentAlignFrame = null;
-          }
-        }
-
-        @Override
-        public void focusGained(FocusEvent e)
-        {
-          me.viewport.applet.currentAlignFrame = me;
-        }
-      });
-      viewport.applet.validate();
+      embedAlignFrameInApplet(viewport.applet);
     }
     else
     {
@@ -3563,19 +3563,69 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
       //
       if (embedMenuIfNeeded(alignPanel))
       {
-        // adjust for status bar height too
-        alignPanel.setSize(getSize().width, getSize().height
-                - statusBar.HEIGHT);
+        /*
+         * adjust for status bar height too. ? pointless as overridden by layout
+         * manager
+         */
+        alignPanel.setSize(getSize().width,
+                getSize().height - statusBar.getHeight());
       }
       add(statusBar, BorderLayout.SOUTH);
       add(alignPanel, BorderLayout.CENTER);
       // and register with the applet so it can pass external API calls to us
-      jalview.bin.JalviewLite.addFrame(this, title, DEFAULT_WIDTH,
+      jalview.bin.JalviewLite.addFrame(this, this.getTitle(),
+              DEFAULT_WIDTH,
               DEFAULT_HEIGHT);
     }
   }
 
   /**
+   * Add the components of this AlignFrame to the applet container.
+   * 
+   * @param theApplet
+   */
+  public void embedAlignFrameInApplet(final JalviewLite theApplet)
+  {
+    // ////
+    // Explicitly build the embedded menu panel for the on-page applet
+    //
+    // view cannot be closed if its actually on the page
+    fileMenu.remove(closeMenuItem);
+    fileMenu.remove(3); // Remove Separator
+    embeddedMenu = makeEmbeddedPopupMenu(alignFrameMenuBar,
+            FONT_ARIAL_PLAIN_11, false, false); // use our own fonts.
+    // and actually add the components to the applet area
+    theApplet.setLayout(new BorderLayout());
+    theApplet.add(embeddedMenu, BorderLayout.NORTH);
+    theApplet.add(statusBar, BorderLayout.SOUTH);
+    // TODO should size be left to the layout manager?
+    alignPanel.setSize(theApplet.getSize().width,
+            theApplet.getSize().height - embeddedMenu.getHeight()
+                    - statusBar.getHeight());
+    theApplet.add(alignPanel, BorderLayout.CENTER);
+    final AlignFrame me = this;
+    theApplet.addFocusListener(new FocusListener()
+    {
+
+      @Override
+      public void focusLost(FocusEvent e)
+      {
+        if (theApplet.currentAlignFrame == me)
+        {
+          theApplet.currentAlignFrame = null;
+        }
+      }
+
+      @Override
+      public void focusGained(FocusEvent e)
+      {
+        theApplet.currentAlignFrame = me;
+      }
+    });
+    theApplet.validate();
+  }
+
+  /**
    * create a new binding between structures in an existing jmol viewer instance
    * and an alignpanel with sequences that have existing PDBFile entries. Note,
    * this does not open a new Jmol window, or modify the display of the
index 61e8f12..6f843d0 100644 (file)
@@ -480,7 +480,8 @@ public class AlignmentPanel extends Panel implements AdjustmentListener,
     // this is called after loading new annotation onto alignment
     if (alignFrame.getSize().height == 0)
     {
-      System.out.println("NEEDS FIXING");
+      System.out
+              .println("adjustAnnotationHeight frame size zero NEEDS FIXING");
     }
     fontChanged();
     validateAnnotationDimensions(true);
index c527308..4eb3086 100644 (file)
@@ -39,8 +39,8 @@ import java.util.Enumeration;
 import java.util.Hashtable;
 
 /**
- * This class implements a pattern form embedding toolbars as a panel with
- * popups for situations where the system menu bar is either invisible or
+ * This class implements a pattern for embedding toolbars as a panel with popups
+ * for situations where the system menu bar is either invisible or
  * inappropriate. It was derived from the code for embedding the jalview applet
  * alignFrame as a component on the web-page, which requires the local
  * alignFrame menu to be attached to that panel rather than placed on the parent
@@ -53,6 +53,9 @@ import java.util.Hashtable;
  */
 public class EmbmenuFrame extends Frame implements MouseListener
 {
+  protected static final Font FONT_ARIAL_PLAIN_11 = new Font(
+            "Arial", Font.PLAIN, 11);
+
   /**
    * map from labels to popup menus for the embedded menubar
    */
@@ -95,57 +98,33 @@ public class EmbmenuFrame extends Frame implements MouseListener
     if (new jalview.util.Platform().isAMac())
     {
       // Build the embedded menu panel
-      embeddedMenu = makeEmbeddedPopupMenu(topMenuBar, "Arial", Font.PLAIN,
-              11, true); // try to pickup system font.
+      embeddedMenu = makeEmbeddedPopupMenu(topMenuBar, FONT_ARIAL_PLAIN_11,
+              true, false); // try to pickup system font.
       setMenuBar(null);
-      // add the components to the TreePanel area.
+      // add the components to the Panel area.
       add(embeddedMenu, BorderLayout.NORTH);
-      tobeAdjusted.setSize(getSize().width, getSize().height
-              - embeddedMenu.HEIGHT);
+      tobeAdjusted.setSize(getSize().width,
+              getSize().height - embeddedMenu.getHeight());
       return true;
     }
     return false;
   }
 
   /**
-   * move all menus on menuBar onto embeddedMenu. embeddedPopup is used to store
-   * the popups for each menu removed from the menuBar and added to the panel.
-   * NOTE: it is up to the caller to remove menuBar from the Frame if it is
-   * already attached.
-   * 
-   * @param menuBar
-   * @param fn
-   * @param fstyle
-   * @param fsz
-   * @param overrideFonts
-   *          true if we take the menuBar fonts in preference to the supplied
-   *          defaults
-   * @return the embedded menu instance to be added to the frame.
-   */
-  protected Panel makeEmbeddedPopupMenu(MenuBar menuBar, String fn,
-          int fstyle, int fsz, boolean overrideFonts)
-  {
-    return makeEmbeddedPopupMenu(menuBar, fn, fstyle, fsz, overrideFonts,
-            false);
-  }
-
-  /**
    * Create or add elements to the embedded menu from menuBar. This removes all
    * menu from menuBar and it is up to the caller to remove the now useless
    * menuBar from the Frame if it is already attached.
    * 
    * @param menuBar
-   * @param fn
-   * @param fstyle
-   * @param fsz
+   * @param font
    * @param overrideFonts
    * @param append
    *          true means existing menu will be emptied before adding new
    *          elements
    * @return
    */
-  protected Panel makeEmbeddedPopupMenu(MenuBar menuBar, String fn,
-          int fstyle, int fsz, boolean overrideFonts, boolean append)
+  protected Panel makeEmbeddedPopupMenu(MenuBar menuBar, Font font,
+          boolean overrideFonts, boolean append)
   {
     if (!append)
     {
@@ -163,7 +142,7 @@ public class EmbmenuFrame extends Frame implements MouseListener
       embeddedPopup = new Hashtable();
     }
 
-    embeddedMenu = makeEmbeddedPopupMenu(menuBar, fn, fstyle, fsz,
+    embeddedMenu = makeEmbeddedPopupMenu(menuBar, font,
             overrideFonts, embeddedPopup, new Panel(), this);
     return embeddedMenu;
   }
@@ -177,9 +156,7 @@ public class EmbmenuFrame extends Frame implements MouseListener
    * 
    * @param menuBar
    *          must be non-null
-   * @param fn
-   * @param fstyle
-   * @param fsz
+   * @param font
    * @param overrideFonts
    * @param embeddedPopup
    *          must be non-null
@@ -190,8 +167,8 @@ public class EmbmenuFrame extends Frame implements MouseListener
    *          embeddedPopup and embeddedMenu
    * @return the panel instance for convenience.
    */
-  protected Panel makeEmbeddedPopupMenu(MenuBar menuBar, String fn,
-          int fstyle, int fsz, boolean overrideFonts,
+  protected Panel makeEmbeddedPopupMenu(MenuBar menuBar, Font font,
+          boolean overrideFonts,
           Hashtable embeddedPopup, Panel embeddedMenu,
           MouseListener clickHandler)
   {
@@ -204,13 +181,13 @@ public class EmbmenuFrame extends Frame implements MouseListener
       Font mbf = menuBar.getFont();
       if (mbf != null)
       {
-        fn = mbf.getName();
-        fstyle = mbf.getStyle();
-        fsz = mbf.getSize();
+        font = mbf;
       }
     }
     if (embeddedMenu == null)
+    {
       embeddedMenu = new Panel();
+    }
     FlowLayout flowLayout1 = new FlowLayout();
     embeddedMenu.setBackground(Color.lightGray);
     embeddedMenu.setLayout(flowLayout1);
@@ -219,7 +196,7 @@ public class EmbmenuFrame extends Frame implements MouseListener
     {
       Menu mi = menuBar.getMenu(mbi);
       Label elab = new Label(mi.getLabel());
-      elab.setFont(new java.awt.Font(fn, fstyle, fsz));
+      elab.setFont(font);
       // add the menu entries
       PopupMenu popup = new PopupMenu();
       int m, mSize = mi.getItemCount();
diff --git a/src/jalview/appletgui/SplitFrame.java b/src/jalview/appletgui/SplitFrame.java
new file mode 100644 (file)
index 0000000..d77f331
--- /dev/null
@@ -0,0 +1,107 @@
+package jalview.appletgui;
+
+import jalview.bin.JalviewLite;
+
+import java.awt.BorderLayout;
+import java.awt.GridLayout;
+import java.awt.Panel;
+
+public class SplitFrame extends EmbmenuFrame
+{
+  private static final long serialVersionUID = 1L;
+
+  private AlignFrame topFrame;
+
+  private AlignFrame bottomFrame;
+
+  private Panel outermost;
+
+  /**
+   * Constructor
+   */
+  public SplitFrame(AlignFrame af1, AlignFrame af2)
+  {
+    topFrame = af1;
+    bottomFrame = af2;
+    init();
+  }
+
+  /**
+   * Creates a Panel containing two Panels, and adds the first and second
+   * AlignFrame's components to each. At this stage we have not yet committed to
+   * whether the enclosing panel will be added to this frame, for display as a
+   * separate frame, or added to the applet (embedded mode).
+   */
+  public void init()
+  {
+    setMenuBar(null);
+    outermost = new Panel();
+    outermost.setLayout(new GridLayout(2, 1));
+
+    Panel topPanel = new Panel();
+    Panel bottomPanel = new Panel();
+    outermost.add(topPanel);
+    outermost.add(bottomPanel);
+
+    addAlignFrameComponents(topFrame, topPanel);
+    addAlignFrameComponents(bottomFrame, bottomPanel);
+  }
+
+  /**
+   * Add the menu bar, alignment panel and status bar from the AlignFrame to the
+   * panel. The menu bar is a panel 'reconstructed' from the AlignFrame's frame
+   * menu bar. This allows each half of the SplitFrame to have its own menu bar.
+   * 
+   * @param af
+   * @param panel
+   */
+  private void addAlignFrameComponents(AlignFrame af, Panel panel)
+  {
+    panel.setLayout(new BorderLayout());
+    Panel menuPanel = makeEmbeddedPopupMenu(af.getMenuBar(), FONT_ARIAL_PLAIN_11, true, false);
+    panel.add(menuPanel, BorderLayout.NORTH);
+    panel.add(af.statusBar, BorderLayout.SOUTH);
+    panel.add(af.alignPanel, BorderLayout.CENTER);
+  }
+
+  /**
+   * Display the content panel either as a new frame or embedded in the applet.
+   * 
+   * @param embedded
+   * @param applet
+   */
+  public void addToDisplay(boolean embedded, JalviewLite applet)
+  {
+    createAlignFrameWindow(embedded, applet);
+    validate();
+    topFrame.alignPanel.adjustAnnotationHeight();
+    topFrame.alignPanel.paintAlignment(true);
+    bottomFrame.alignPanel.adjustAnnotationHeight();
+    bottomFrame.alignPanel.paintAlignment(true);
+  }
+
+  /**
+   * Either show the content panel in this frame as a new frame, or (if
+   * embed=true) add it to the applet container instead.
+   * 
+   * @param embed
+   * @param applet
+   */
+  public void createAlignFrameWindow(boolean embed, JalviewLite applet)
+  {
+    if (embed)
+    {
+      applet.add(outermost);
+      applet.validate();
+    }
+    else
+    {
+      this.add(outermost);
+      int width = Math.max(topFrame.DEFAULT_WIDTH,
+              bottomFrame.DEFAULT_WIDTH);
+      int height = topFrame.DEFAULT_HEIGHT + bottomFrame.DEFAULT_HEIGHT;
+      jalview.bin.JalviewLite
+              .addFrame(this, this.getTitle(), width, height);
+    }
+  }
+}
index ada49cc..ca3de8b 100644 (file)
@@ -25,6 +25,7 @@ import jalview.appletgui.AlignFrame;
 import jalview.appletgui.AlignViewport;
 import jalview.appletgui.EmbmenuFrame;
 import jalview.appletgui.FeatureSettings;
+import jalview.appletgui.SplitFrame;
 import jalview.datamodel.Alignment;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.AlignmentOrder;
@@ -37,7 +38,9 @@ import jalview.io.AnnotationFile;
 import jalview.io.AppletFormatAdapter;
 import jalview.io.FileParse;
 import jalview.io.IdentifyFile;
+import jalview.io.JPredFile;
 import jalview.io.JnetAnnotationMaker;
+import jalview.io.NewickFile;
 import jalview.javascript.JSFunctionExec;
 import jalview.javascript.JalviewLiteJsApi;
 import jalview.javascript.JsCallBack;
@@ -57,6 +60,8 @@ import java.awt.event.ActionEvent;
 import java.awt.event.WindowAdapter;
 import java.awt.event.WindowEvent;
 import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.net.URL;
 import java.util.Hashtable;
@@ -77,6 +82,10 @@ public class JalviewLite extends Applet implements
         StructureSelectionManagerProvider, JalviewLiteJsApi
 {
 
+  private static final String TRUE = "true";
+
+  private static final String FALSE = "false";
+
   public StructureSelectionManager getStructureSelectionManager()
   {
     return StructureSelectionManager.getStructureSelectionManager(this);
@@ -494,7 +503,7 @@ public class JalviewLite extends Applet implements
   {
     try
     {
-      boolean seqlimits = suffix.equalsIgnoreCase("true");
+      boolean seqlimits = suffix.equalsIgnoreCase(TRUE);
       if (alf.viewport.getSelectionGroup() != null)
       {
         // JBPNote: getSelectionAsNewSequence behaviour has changed - this
@@ -630,7 +639,7 @@ public class JalviewLite extends Applet implements
     final String _undoName = undoName;
     // TODO: deal with synchronization here: cannot raise any events until after
     // this has returned.
-    return alf.sortBy(aorder, _undoName) ? "true" : "";
+    return alf.sortBy(aorder, _undoName) ? TRUE : "";
   }
 
   /*
@@ -640,7 +649,7 @@ public class JalviewLite extends Applet implements
    */
   public String getAlignment(String format)
   {
-    return getAlignmentFrom(getDefaultTargetFrame(), format, "true");
+    return getAlignmentFrom(getDefaultTargetFrame(), format, TRUE);
   }
 
   /*
@@ -652,7 +661,7 @@ public class JalviewLite extends Applet implements
    */
   public String getAlignmentFrom(AlignFrame alf, String format)
   {
-    return getAlignmentFrom(alf, format, "true");
+    return getAlignmentFrom(alf, format, TRUE);
   }
 
   /*
@@ -678,7 +687,7 @@ public class JalviewLite extends Applet implements
   {
     try
     {
-      boolean seqlimits = suffix.equalsIgnoreCase("true");
+      boolean seqlimits = suffix.equalsIgnoreCase(TRUE);
 
       String reply = new AppletFormatAdapter().formatSequences(format,
               alf.viewport.getAlignment(), seqlimits);
@@ -1233,7 +1242,10 @@ public class JalviewLite extends Applet implements
 
   String file = "No file";
 
-  Button launcher = new Button("Start Jalview");
+  String file2 = "No file";
+
+  Button launcher = new Button(
+          MessageManager.getString("label.start_jalview"));
 
   /**
    * The currentAlignFrame is static, it will change if and when the user
@@ -1361,11 +1373,7 @@ public class JalviewLite extends Applet implements
     /**
      * turn on extra applet debugging
      */
-    String dbg = getParameter("debug");
-    if (dbg != null)
-    {
-      debug = dbg.toLowerCase().equals("true");
-    }
+    debug = TRUE.equalsIgnoreCase(getParameter("debug"));
     if (debug)
     {
 
@@ -1378,7 +1386,7 @@ public class JalviewLite extends Applet implements
     if (externalsviewer != null)
     {
       useXtrnalSviewer = externalsviewer.trim().toLowerCase()
-              .equals("true");
+              .equals(TRUE);
     }
     /**
      * if true disable the check for jmol
@@ -1386,7 +1394,7 @@ public class JalviewLite extends Applet implements
     String chkforJmol = getParameter("nojmol");
     if (chkforJmol != null)
     {
-      checkForJmol = !chkforJmol.equals("true");
+      checkForJmol = !chkforJmol.equals(TRUE);
     }
     /**
      * get the separator parameter if present
@@ -1451,38 +1459,37 @@ public class JalviewLite extends Applet implements
         file = data.toString();
       }
     }
+    file2 = getParameter("file2");
 
-    final JalviewLite jvapplet = this;
-    if (getParameter("embedded") != null
-            && getParameter("embedded").equalsIgnoreCase("true"))
+    embedded = TRUE.equalsIgnoreCase(getParameter("embedded"));
+    if (embedded)
     {
-      // Launch as embedded applet in page
-      embedded = true;
-      LoadingThread loader = new LoadingThread(file, jvapplet);
+      LoadingThread loader = new LoadingThread(file, file2, this);
       loader.start();
     }
     else if (file != null)
     {
-      if (getParameter("showbutton") == null
-              || !getParameter("showbutton").equalsIgnoreCase("false"))
+      /*
+       * Start the applet immediately or show a button to start it
+       */
+      if (FALSE.equalsIgnoreCase(getParameter("showbutton")))
+      {
+        LoadingThread loader = new LoadingThread(file, file2, this);
+        loader.start();
+      }
+      else
       {
-        // Add the JalviewLite 'Button' to the page
         add(launcher);
         launcher.addActionListener(new java.awt.event.ActionListener()
         {
           public void actionPerformed(ActionEvent e)
           {
-            LoadingThread loader = new LoadingThread(file, jvapplet);
+            LoadingThread loader = new LoadingThread(file, file2,
+                    JalviewLite.this);
             loader.start();
           }
         });
       }
-      else
-      {
-        // Open jalviewLite immediately.
-        LoadingThread loader = new LoadingThread(file, jvapplet);
-        loader.start();
-      }
     }
     else
     {
@@ -1756,27 +1763,19 @@ public class JalviewLite extends Applet implements
   class LoadingThread extends Thread
   {
     /**
-     * State variable: File source
-     */
-    String file;
-
-    /**
      * State variable: protocol for access to file source
      */
     String protocol;
 
-    /**
-     * State variable: format of file source
-     */
-    String format;
+    String _file; // alignment file or URL spec
 
-    String _file;
+    String _file2; // second alignment file or URL spec
 
     JalviewLite applet;
 
     private void dbgMsg(String msg)
     {
-      if (applet.debug)
+      if (JalviewLite.debug)
       {
         System.err.println(msg);
       }
@@ -1809,9 +1808,16 @@ public class JalviewLite extends Applet implements
       return file;
     }
 
-    public LoadingThread(String _file, JalviewLite _applet)
+    // public LoadingThread(String _file, JalviewLite _applet)
+    // {
+    // this._file = _file;
+    // applet = _applet;
+    // }
+
+    public LoadingThread(String file, String file2, JalviewLite _applet)
     {
-      this._file = _file;
+      this._file = file;
+      this._file2 = file2;
       applet = _applet;
     }
 
@@ -1828,25 +1834,111 @@ public class JalviewLite extends Applet implements
         } catch (Exception e)
         {
         }
-        ;
       }
       startLoading();
       // applet.callInitCallback();
     }
 
+    /**
+     * Load the alignment and any related files as specified by applet
+     * parameters
+     */
     private void startLoading()
     {
-      AlignFrame newAlignFrame;
       dbgMsg("Loading thread started with:\n>>file\n" + _file + ">>endfile");
-      file = setProtocolState(_file);
 
-      format = new jalview.io.IdentifyFile().Identify(file, protocol);
-      dbgMsg("File identified as '" + format + "'");
       dbgMsg("Loading started.");
-      Alignment al = null;
+
+      AlignFrame newAlignFrame = readAlignment(_file);
+      AlignFrame newAlignFrame2 = readAlignment(_file2);
+      if (newAlignFrame != null)
+      {
+        addToDisplay(newAlignFrame, newAlignFrame2);
+        loadTree(newAlignFrame);
+
+        loadScoreFile(newAlignFrame);
+
+        loadFeatures(newAlignFrame);
+
+        loadAnnotations(newAlignFrame);
+
+        loadJnetFile(newAlignFrame);
+
+        loadPdbFiles(newAlignFrame);
+      }
+      else
+      {
+        fileFound = false;
+        applet.remove(launcher);
+        applet.repaint();
+      }
+      callInitCallback();
+    }
+
+    /**
+     * Add an AlignFrame to the display; or if two are provided, a SplitFrame.
+     * 
+     * @param af
+     * @param af2
+     */
+    public void addToDisplay(AlignFrame af, AlignFrame af2)
+    {
+      if (af2 == null)
+      {
+        af.addToDisplay(embedded);
+      }
+      else
+      {
+        SplitFrame sf = new SplitFrame(af, af2);
+        sf.addToDisplay(embedded, JalviewLite.this);
+      }
+    }
+
+    /**
+     * Read the alignment file (from URL, text 'paste', or archive by
+     * classloader).
+     * 
+     * @return
+     */
+    protected AlignFrame readAlignment(String fileParam)
+    {
+      if (fileParam == null)
+      {
+        return null;
+      }
+      String resolvedFile = setProtocolState(fileParam);
+      String format = new IdentifyFile().Identify(resolvedFile, protocol);
+      dbgMsg("File identified as '" + format + "'");
+      AlignmentI al = null;
       try
       {
-        al = new AppletFormatAdapter().readFile(file, protocol, format);
+        al = new AppletFormatAdapter().readFile(resolvedFile, protocol, format);
+        if ((al != null) && (al.getHeight() > 0))
+        {
+          dbgMsg("Successfully loaded file.");
+          AlignFrame newAlignFrame = new AlignFrame(al, applet,
+                  resolvedFile, embedded, false);
+          newAlignFrame.setTitle(resolvedFile);
+          if (initialAlignFrame == null)
+          {
+            initialAlignFrame = newAlignFrame;
+          }
+          // update the focus.
+          currentAlignFrame = newAlignFrame;
+
+          if (protocol == AppletFormatAdapter.PASTE)
+          {
+            newAlignFrame.setTitle(MessageManager.formatMessage(
+                    "label.sequences_from", new Object[]
+                    { applet.getDocumentBase().toString() }));
+          }
+
+          newAlignFrame.statusBar.setText(MessageManager.formatMessage(
+                  "label.successfully_loaded_file", new Object[]
+                  { resolvedFile }));
+
+          return newAlignFrame;
+        }
       } catch (java.io.IOException ex)
       {
         dbgMsg("File load exception.");
@@ -1855,9 +1947,9 @@ public class JalviewLite extends Applet implements
         {
           try
           {
-            FileParse fp = new FileParse(file, protocol);
+            FileParse fp = new FileParse(resolvedFile, protocol);
             String ln = null;
-            dbgMsg(">>>Dumping contents of '" + file + "' " + "("
+            dbgMsg(">>>Dumping contents of '" + resolvedFile + "' " + "("
                     + protocol + ")");
             while ((ln = fp.nextLine()) != null)
             {
@@ -1872,350 +1964,378 @@ public class JalviewLite extends Applet implements
           }
         }
       }
-      if ((al != null) && (al.getHeight() > 0))
+      return null;
+    }
+
+    /**
+     * Load PDBFiles if any specified by parameter(s). Returns true if loaded,
+     * else false.
+     * 
+     * @param alignFrame
+     * @return
+     */
+    protected boolean loadPdbFiles(AlignFrame alignFrame)
+    {
+      boolean result = false;
+      /*
+       * <param name="alignpdbfiles" value="false/true"/> Undocumented for 2.6 -
+       * related to JAL-434
+       */
+
+      applet.setAlignPdbStructures(getDefaultParameter("alignpdbfiles",
+              false));
+      /*
+       * <param name="PDBfile" value="1gaq.txt PDB|1GAQ|1GAQ|A PDB|1GAQ|1GAQ|B
+       * PDB|1GAQ|1GAQ|C">
+       * 
+       * <param name="PDBfile2" value="1gaq.txt A=SEQA B=SEQB C=SEQB">
+       * 
+       * <param name="PDBfile3" value="1q0o Q45135_9MICO">
+       */
+
+      int pdbFileCount = 0;
+      // Accumulate pdbs here if they are heading for the same view (if
+      // alignPdbStructures is true)
+      Vector pdbs = new Vector();
+      // create a lazy matcher if we're asked to
+      jalview.analysis.SequenceIdMatcher matcher = (applet
+              .getDefaultParameter("relaxedidmatch", false)) ? new jalview.analysis.SequenceIdMatcher(
+              alignFrame.getAlignViewport().getAlignment()
+                      .getSequencesArray()) : null;
+
+      String param;
+      do
       {
-        dbgMsg("Successfully loaded file.");
-        newAlignFrame = new AlignFrame(al, applet, file, embedded);
-        if (initialAlignFrame == null)
+        if (pdbFileCount > 0)
         {
-          initialAlignFrame = newAlignFrame;
+          param = applet.getParameter("PDBFILE" + pdbFileCount);
         }
-        // update the focus.
-        currentAlignFrame = newAlignFrame;
-
-        if (protocol == jalview.io.AppletFormatAdapter.PASTE)
+        else
         {
-          newAlignFrame.setTitle(MessageManager.formatMessage(
-                  "label.sequences_from", new String[]
-                  { applet.getDocumentBase().toString() }));
+          param = applet.getParameter("PDBFILE");
         }
 
-        newAlignFrame.statusBar.setText(MessageManager.formatMessage(
-                "label.successfully_loaded_file", new String[]
-                { file }));
-
-        String treeFile = applet.getParameter("tree");
-        if (treeFile == null)
+        if (param != null)
         {
-          treeFile = applet.getParameter("treeFile");
-        }
+          PDBEntry pdb = new PDBEntry();
 
-        if (treeFile != null)
-        {
-          try
+          String seqstring;
+          SequenceI[] seqs = null;
+          String[] chains = null;
+
+          StringTokenizer st = new StringTokenizer(param, " ");
+
+          if (st.countTokens() < 2)
           {
-            treeFile = setProtocolState(treeFile);
-            /*
-             * if (inArchive(treeFile)) { protocol =
-             * AppletFormatAdapter.CLASSLOADER; } else { protocol =
-             * AppletFormatAdapter.URL; treeFile = addProtocol(treeFile); }
-             */
-            jalview.io.NewickFile fin = new jalview.io.NewickFile(treeFile,
-                    protocol);
-
-            fin.parse();
-
-            if (fin.getTree() != null)
+            String sequence = applet.getParameter("PDBSEQ");
+            if (sequence != null)
             {
-              newAlignFrame.loadTree(fin, treeFile);
-              dbgMsg("Successfuly imported tree.");
+              seqs = new SequenceI[]
+              { matcher == null ? (Sequence) alignFrame.getAlignViewport()
+                      .getAlignment().findName(sequence) : matcher
+                      .findIdMatch(sequence) };
             }
-            else
+
+          }
+          else
+          {
+            param = st.nextToken();
+            Vector tmp = new Vector();
+            Vector tmp2 = new Vector();
+
+            while (st.hasMoreTokens())
+            {
+              seqstring = st.nextToken();
+              StringTokenizer st2 = new StringTokenizer(seqstring, "=");
+              if (st2.countTokens() > 1)
+              {
+                // This is the chain
+                tmp2.addElement(st2.nextToken());
+                seqstring = st2.nextToken();
+              }
+              tmp.addElement(matcher == null ? (Sequence) alignFrame
+                      .getAlignViewport().getAlignment()
+                      .findName(seqstring) : matcher.findIdMatch(seqstring));
+            }
+
+            seqs = new SequenceI[tmp.size()];
+            tmp.copyInto(seqs);
+            if (tmp2.size() == tmp.size())
             {
-              dbgMsg("Tree parameter did not resolve to a valid tree.");
+              chains = new String[tmp2.size()];
+              tmp2.copyInto(chains);
             }
-          } catch (Exception ex)
+          }
+          param = setProtocolState(param);
+
+          if (// !jmolAvailable
+          // &&
+          protocol == AppletFormatAdapter.CLASSLOADER && !useXtrnalSviewer)
           {
-            ex.printStackTrace();
+            // Re: JAL-357 : the bug isn't a problem if we are using an
+            // external viewer!
+            // TODO: verify this Re:
+            // https://mantis.lifesci.dundee.ac.uk/view.php?id=36605
+            // This exception preserves the current behaviour where, even if
+            // the local pdb file was identified in the class loader
+            protocol = AppletFormatAdapter.URL; // this is probably NOT
+            // CORRECT!
+            param = addProtocol(param); //
           }
-        }
 
-        /*
-         * Try to load T-Coffee score file
-         */
-        String sScoreFile = applet.getParameter("scoreFile");
-        if (sScoreFile != null && !"".equals(sScoreFile))
-        {
-          try
+          pdb.setFile(param);
+
+          if (seqs != null)
           {
-            if (debug)
+            for (int i = 0; i < seqs.length; i++)
             {
-              System.err
-                      .println("Attempting to load T-COFFEE score file from the scoreFile parameter");
+              if (seqs[i] != null)
+              {
+                ((Sequence) seqs[i]).addPDBId(pdb);
+                StructureSelectionManager.getStructureSelectionManager(
+                        applet).registerPDBEntry(pdb);
+              }
+              else
+              {
+                if (JalviewLite.debug)
+                {
+                  // this may not really be a problem but we give a warning
+                  // anyway
+                  System.err
+                          .println("Warning: Possible input parsing error: Null sequence for attachment of PDB (sequence "
+                                  + i + ")");
+                }
+              }
             }
-            if (!newAlignFrame.loadScoreFile(sScoreFile))
+
+            if (!alignPdbStructures)
             {
-              System.err
-                      .println("Failed to parse T-COFFEE parameter as a valid score file ('"
-                              + sScoreFile + "')");
+              alignFrame.newStructureView(applet, pdb, seqs, chains,
+                      protocol);
+            }
+            else
+            {
+              pdbs.addElement(new Object[]
+              { pdb, seqs, chains, new String(protocol) });
             }
-          } catch (Exception e)
-          {
-            System.err.printf("Cannot read score file: '%s'. Cause: %s \n",
-                    sScoreFile, e.getMessage());
           }
         }
 
-        // ///////////////////////////
-        // modify display of features
-        // we do this before any features have been loaded, ensuring any hidden
-        // groups are hidden when features first displayed
-        //
-        // hide specific groups
-        //
-        String param = applet.getParameter("hidefeaturegroups");
-        if (param != null)
-        {
-          newAlignFrame.setFeatureGroupState(separatorListToArray(param),
-                  false);
-          // applet.setFeatureGroupStateOn(newAlignFrame, param, false);
-        }
-        // show specific groups
-        param = applet.getParameter("showfeaturegroups");
-        if (param != null)
-        {
-          newAlignFrame.setFeatureGroupState(separatorListToArray(param),
-                  true);
-          // applet.setFeatureGroupStateOn(newAlignFrame, param, true);
+        pdbFileCount++;
+      } while (param != null || pdbFileCount < 10);
+      if (pdbs.size() > 0)
+      {
+        SequenceI[][] seqs = new SequenceI[pdbs.size()][];
+        PDBEntry[] pdb = new PDBEntry[pdbs.size()];
+        String[][] chains = new String[pdbs.size()][];
+        String[] protocols = new String[pdbs.size()];
+        for (int pdbsi = 0, pdbsiSize = pdbs.size(); pdbsi < pdbsiSize; pdbsi++)
+        {
+          Object[] o = (Object[]) pdbs.elementAt(pdbsi);
+          pdb[pdbsi] = (PDBEntry) o[0];
+          seqs[pdbsi] = (SequenceI[]) o[1];
+          chains[pdbsi] = (String[]) o[2];
+          protocols[pdbsi] = (String) o[3];
         }
-        // and now load features
-        param = applet.getParameter("features");
-        if (param != null)
+        alignFrame.alignedStructureView(applet, pdb, seqs, chains,
+                protocols);
+        result = true;
+      }
+      return result;
+    }
+
+    /**
+     * Load in a Jnetfile if specified by parameter. Returns true if loaded,
+     * else false.
+     * 
+     * @param alignFrame
+     * @return
+     */
+    protected boolean loadJnetFile(AlignFrame alignFrame)
+    {
+      boolean result = false;
+      String param = applet.getParameter("jnetfile");
+      if (param != null)
+      {
+        try
         {
           param = setProtocolState(param);
-
-          newAlignFrame.parseFeaturesFile(param, protocol);
+          JPredFile predictions = new JPredFile(param, protocol);
+          JnetAnnotationMaker.add_annotation(predictions,
+                  alignFrame.viewport.getAlignment(), 0, false);
+          // false == do not add sequence profile from concise output
+          SequenceI repseq = alignFrame.viewport.getAlignment()
+                  .getSequenceAt(0);
+          alignFrame.viewport.getAlignment().setSeqrep(repseq);
+          ColumnSelection cs = new ColumnSelection();
+          cs.hideInsertionsFor(repseq);
+          alignFrame.viewport.setColumnSelection(cs);
+          alignFrame.alignPanel.fontChanged();
+          alignFrame.alignPanel.setScrollValues(0, 0);
+          result = true;
+        } catch (Exception ex)
+        {
+          ex.printStackTrace();
         }
+      }
+      return result;
+    }
+
+    /**
+     * Load annotations if specified by parameter. Returns true if loaded, else
+     * false.
+     * 
+     * @param alignFrame
+     * @return
+     */
+    protected boolean loadAnnotations(AlignFrame alignFrame)
+    {
+      boolean result = false;
+      String param = applet.getParameter("annotations");
+      if (param != null)
+      {
+        param = setProtocolState(param);
 
-        param = applet.getParameter("showFeatureSettings");
-        if (param != null && param.equalsIgnoreCase("true"))
+        if (new AnnotationFile().annotateAlignmentView(alignFrame.viewport,
+                param, protocol))
         {
-          newAlignFrame.viewport.setShowSequenceFeatures(true);
-          new FeatureSettings(newAlignFrame.alignPanel);
+          alignFrame.alignPanel.fontChanged();
+          alignFrame.alignPanel.setScrollValues(0, 0);
+          result = true;
         }
-
-        param = applet.getParameter("annotations");
-        if (param != null)
+        else
         {
-          param = setProtocolState(param);
+          System.err
+                  .println("Annotations were not added from annotation file '"
+                          + param + "'");
+        }
+      }
+      return result;
+    }
 
-          if (new AnnotationFile().annotateAlignmentView(
-                  newAlignFrame.viewport, param, protocol))
-          {
-            newAlignFrame.alignPanel.fontChanged();
-            newAlignFrame.alignPanel.setScrollValues(0, 0);
-          }
-          else
-          {
-            System.err
-                    .println("Annotations were not added from annotation file '"
-                            + param + "'");
-          }
+    /**
+     * Load features file and view settings as specified by parameters. Returns
+     * true if features were loaded, else false.
+     * 
+     * @param alignFrame
+     * @return
+     */
+    protected boolean loadFeatures(AlignFrame alignFrame)
+    {
+      boolean result = false;
+      // ///////////////////////////
+      // modify display of features
+      // we do this before any features have been loaded, ensuring any hidden
+      // groups are hidden when features first displayed
+      //
+      // hide specific groups
+      //
+      String param = applet.getParameter("hidefeaturegroups");
+      if (param != null)
+      {
+        alignFrame.setFeatureGroupState(separatorListToArray(param), false);
+        // applet.setFeatureGroupStateOn(newAlignFrame, param, false);
+      }
+      // show specific groups
+      param = applet.getParameter("showfeaturegroups");
+      if (param != null)
+      {
+        alignFrame.setFeatureGroupState(separatorListToArray(param), true);
+        // applet.setFeatureGroupStateOn(newAlignFrame, param, true);
+      }
+      // and now load features
+      param = applet.getParameter("features");
+      if (param != null)
+      {
+        param = setProtocolState(param);
 
-        }
+        result = alignFrame.parseFeaturesFile(param, protocol);
+      }
 
-        param = applet.getParameter("jnetfile");
-        if (param != null)
+      param = applet.getParameter("showFeatureSettings");
+      if (param != null && param.equalsIgnoreCase(TRUE))
+      {
+        alignFrame.viewport.setShowSequenceFeatures(true);
+        new FeatureSettings(alignFrame.alignPanel);
+      }
+      return result;
+    }
+
+    /**
+     * Load a score file if specified by parameter. Returns true if file was
+     * loaded, else false.
+     * 
+     * @param alignFrame
+     */
+    protected boolean loadScoreFile(AlignFrame alignFrame)
+    {
+      boolean result = false;
+      String sScoreFile = applet.getParameter("scoreFile");
+      if (sScoreFile != null && !"".equals(sScoreFile))
+      {
+        try
         {
-          try
+          if (debug)
           {
-            param = setProtocolState(param);
-            jalview.io.JPredFile predictions = new jalview.io.JPredFile(
-                    param, protocol);
-            JnetAnnotationMaker.add_annotation(predictions,
-                    newAlignFrame.viewport.getAlignment(), 0, false); // false==do
-            SequenceI repseq = newAlignFrame.viewport.getAlignment()
-                    .getSequenceAt(0);
-            newAlignFrame.viewport.getAlignment().setSeqrep(repseq);
-            ColumnSelection cs = new ColumnSelection();
-            cs.hideInsertionsFor(repseq);
-            newAlignFrame.viewport.setColumnSelection(cs);
-            // not
-            // add
-            // sequence
-            // profile
-            // from
-            // concise
-            // output
-            newAlignFrame.alignPanel.fontChanged();
-            newAlignFrame.alignPanel.setScrollValues(0, 0);
-          } catch (Exception ex)
+            System.err
+                    .println("Attempting to load T-COFFEE score file from the scoreFile parameter");
+          }
+          result = alignFrame.loadScoreFile(sScoreFile);
+          if (!result)
           {
-            ex.printStackTrace();
+            System.err
+                    .println("Failed to parse T-COFFEE parameter as a valid score file ('"
+                            + sScoreFile + "')");
           }
+        } catch (Exception e)
+        {
+          System.err.printf("Cannot read score file: '%s'. Cause: %s \n",
+                  sScoreFile, e.getMessage());
         }
-        /*
-         * <param name="alignpdbfiles" value="false/true"/> Undocumented for 2.6
-         * - related to JAL-434
-         */
-        applet.setAlignPdbStructures(getDefaultParameter("alignpdbfiles",
-                false));
-        /*
-         * <param name="PDBfile" value="1gaq.txt PDB|1GAQ|1GAQ|A PDB|1GAQ|1GAQ|B
-         * PDB|1GAQ|1GAQ|C">
-         * 
-         * <param name="PDBfile2" value="1gaq.txt A=SEQA B=SEQB C=SEQB">
-         * 
-         * <param name="PDBfile3" value="1q0o Q45135_9MICO">
-         */
+      }
+      return result;
+    }
 
-        int pdbFileCount = 0;
-        // Accumulate pdbs here if they are heading for the same view (if
-        // alignPdbStructures is true)
-        Vector pdbs = new Vector();
-        // create a lazy matcher if we're asked to
-        jalview.analysis.SequenceIdMatcher matcher = (applet
-                .getDefaultParameter("relaxedidmatch", false)) ? new jalview.analysis.SequenceIdMatcher(
-                newAlignFrame.getAlignViewport().getAlignment()
-                        .getSequencesArray()) : null;
+    /**
+     * Load a tree for the alignment if specified by parameter. Returns true if
+     * a tree was loaded, else false.
+     * 
+     * @param alignFrame
+     * @return
+     */
+    protected boolean loadTree(AlignFrame alignFrame)
+    {
+      boolean result = false;
+      String treeFile = applet.getParameter("tree");
+      if (treeFile == null)
+      {
+        treeFile = applet.getParameter("treeFile");
+      }
 
-        do
+      if (treeFile != null)
+      {
+        try
         {
-          if (pdbFileCount > 0)
+          treeFile = setProtocolState(treeFile);
+          NewickFile fin = new NewickFile(treeFile, protocol);
+          fin.parse();
+
+          if (fin.getTree() != null)
           {
-            param = applet.getParameter("PDBFILE" + pdbFileCount);
+            alignFrame.loadTree(fin, treeFile);
+            result = true;
+            dbgMsg("Successfully imported tree.");
           }
           else
           {
-            param = applet.getParameter("PDBFILE");
-          }
-
-          if (param != null)
-          {
-            PDBEntry pdb = new PDBEntry();
-
-            String seqstring;
-            SequenceI[] seqs = null;
-            String[] chains = null;
-
-            StringTokenizer st = new StringTokenizer(param, " ");
-
-            if (st.countTokens() < 2)
-            {
-              String sequence = applet.getParameter("PDBSEQ");
-              if (sequence != null)
-              {
-                seqs = new SequenceI[]
-                { matcher == null ? (Sequence) newAlignFrame
-                        .getAlignViewport().getAlignment()
-                        .findName(sequence) : matcher.findIdMatch(sequence) };
-              }
-
-            }
-            else
-            {
-              param = st.nextToken();
-              Vector tmp = new Vector();
-              Vector tmp2 = new Vector();
-
-              while (st.hasMoreTokens())
-              {
-                seqstring = st.nextToken();
-                StringTokenizer st2 = new StringTokenizer(seqstring, "=");
-                if (st2.countTokens() > 1)
-                {
-                  // This is the chain
-                  tmp2.addElement(st2.nextToken());
-                  seqstring = st2.nextToken();
-                }
-                tmp.addElement(matcher == null ? (Sequence) newAlignFrame
-                        .getAlignViewport().getAlignment()
-                        .findName(seqstring) : matcher
-                        .findIdMatch(seqstring));
-              }
-
-              seqs = new SequenceI[tmp.size()];
-              tmp.copyInto(seqs);
-              if (tmp2.size() == tmp.size())
-              {
-                chains = new String[tmp2.size()];
-                tmp2.copyInto(chains);
-              }
-            }
-            param = setProtocolState(param);
-
-            if (// !jmolAvailable
-            // &&
-            protocol == AppletFormatAdapter.CLASSLOADER
-                    && !useXtrnalSviewer)
-            {
-              // Re: JAL-357 : the bug isn't a problem if we are using an
-              // external viewer!
-              // TODO: verify this Re:
-              // https://mantis.lifesci.dundee.ac.uk/view.php?id=36605
-              // This exception preserves the current behaviour where, even if
-              // the local pdb file was identified in the class loader
-              protocol = AppletFormatAdapter.URL; // this is probably NOT
-              // CORRECT!
-              param = addProtocol(param); //
-            }
-
-            pdb.setFile(param);
-
-            if (seqs != null)
-            {
-              for (int i = 0; i < seqs.length; i++)
-              {
-                if (seqs[i] != null)
-                {
-                  ((Sequence) seqs[i]).addPDBId(pdb);
-                  StructureSelectionManager.getStructureSelectionManager(
-                          applet).registerPDBEntry(pdb);
-                }
-                else
-                {
-                  if (JalviewLite.debug)
-                  {
-                    // this may not really be a problem but we give a warning
-                    // anyway
-                    System.err
-                            .println("Warning: Possible input parsing error: Null sequence for attachment of PDB (sequence "
-                                    + i + ")");
-                  }
-                }
-              }
-
-              if (!alignPdbStructures)
-              {
-                newAlignFrame.newStructureView(applet, pdb, seqs, chains,
-                        protocol);
-              }
-              else
-              {
-                pdbs.addElement(new Object[]
-                { pdb, seqs, chains, new String(protocol) });
-              }
-            }
+            dbgMsg("Tree parameter did not resolve to a valid tree.");
           }
-
-          pdbFileCount++;
-        } while (param != null || pdbFileCount < 10);
-        if (pdbs.size() > 0)
+        } catch (Exception ex)
         {
-          SequenceI[][] seqs = new SequenceI[pdbs.size()][];
-          PDBEntry[] pdb = new PDBEntry[pdbs.size()];
-          String[][] chains = new String[pdbs.size()][];
-          String[] protocols = new String[pdbs.size()];
-          for (int pdbsi = 0, pdbsiSize = pdbs.size(); pdbsi < pdbsiSize; pdbsi++)
-          {
-            Object[] o = (Object[]) pdbs.elementAt(pdbsi);
-            pdb[pdbsi] = (PDBEntry) o[0];
-            seqs[pdbsi] = (SequenceI[]) o[1];
-            chains[pdbsi] = (String[]) o[2];
-            protocols[pdbsi] = (String) o[3];
-          }
-          newAlignFrame.alignedStructureView(applet, pdb, seqs, chains,
-                  protocols);
-
+          ex.printStackTrace();
         }
       }
-      else
-      {
-        fileFound = false;
-        applet.remove(launcher);
-        applet.repaint();
-      }
-      callInitCallback();
+      return result;
     }
 
     /**
@@ -2246,48 +2366,88 @@ public class JalviewLite extends Applet implements
       }
     }
 
-    String addProtocol(String file)
+    /**
+     * If the file is not already in URL format, tries to locate it by resolving
+     * as a URL.
+     * 
+     * @param file
+     * @return
+     */
+    String addProtocol(final String file)
     {
       if (file.indexOf("://") == -1)
       {
-        String fl = applet.resolveUrlForLocalOrAbsolute(file,
+        /*
+         * Try relative to document base
+         */
+        String url = applet.resolveUrlForLocalOrAbsolute(file,
                 getDocumentBase());
-        try
+        if (urlExists(url))
         {
-          if (new java.net.URL(fl).openStream() != null)
+          if (debug)
           {
-            if (debug)
-            {
-              System.err.println("Prepended document base for resource: '"
-                      + file + "'");
-            }
-            return fl;
+            System.err.println("Prepended document base for resource: '"
+                    + file + "'");
           }
-        } catch (Exception x)
-        {
+          return url;
         }
-        ;
-        fl = applet.resolveUrlForLocalOrAbsolute(file, getCodeBase());
-        try
+
+        /*
+         * Try relative to codebase
+         */
+        url = applet.resolveUrlForLocalOrAbsolute(file, getCodeBase());
+        if (urlExists(url))
         {
-          if (new java.net.URL(fl).openStream() != null)
+          if (debug)
           {
-            if (debug)
-            {
-              System.err.println("Prepended codebase for resource: '"
-                      + file + "'");
-            }
-            return fl;
+            System.err.println("Prepended codebase for resource: '" + file
+                    + "'");
           }
-        } catch (Exception x)
-        {
+          return url;
         }
-        ;
-
       }
 
+      /*
+       * Not resolved, leave unchanged
+       */
       return file;
     }
+
+    /**
+     * Returns true if an input stream can be opened on the specified URL, else
+     * false.
+     * 
+     * @param url
+     * @return
+     */
+    private boolean urlExists(String url)
+    {
+      InputStream is = null;
+      try
+      {
+        is = new URL(url).openStream();
+        if (is != null)
+        {
+          return true;
+        }
+      } catch (Exception x)
+      {
+        // ignore
+      } finally
+      {
+        if (is != null)
+        {
+          try
+          {
+            is.close();
+          } catch (IOException e)
+          {
+            // ignore
+          }
+        }
+      }
+      return false;
+    }
   }
 
   /**
@@ -2566,7 +2726,7 @@ public class JalviewLite extends Applet implements
     {
       return def;
     }
-    if (stn.toLowerCase().equals("true"))
+    if (stn.toLowerCase().equals(TRUE))
     {
       return true;
     }
index dedff72..30749a5 100644 (file)
@@ -2987,7 +2987,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   public void hideSelSequences_actionPerformed(ActionEvent e)
   {
     viewport.hideAllSelectedSeqs();
-    alignPanel.paintAlignment(true);
+//    alignPanel.paintAlignment(true);
   }
 
   /**
index 486db47..791e04f 100644 (file)
@@ -22,6 +22,18 @@ import javax.swing.KeyStroke;
 import javax.swing.event.InternalFrameAdapter;
 import javax.swing.event.InternalFrameEvent;
 
+/**
+ * An internal frame on the desktop that hosts a horizontally split view of
+ * linked DNA and Protein alignments. Additional views can be created in linked
+ * pairs, expanded to separate split frames, or regathered into a single frame.
+ * <p>
+ * (Some) operations on each alignment are automatically mirrored on the other.
+ * These include mouseover (highlighting), sequence and column selection,
+ * sequence ordering and sorting, and grouping, colouring and sorting by tree.
+ * 
+ * @author gmcarstairs
+ *
+ */
 public class SplitFrame extends GSplitFrame
 {
   private static final long serialVersionUID = 1L;