From 23635fe385da9ea48690349c0530739121600a00 Mon Sep 17 00:00:00 2001 From: gmungoc Date: Fri, 13 Feb 2015 17:10:22 +0000 Subject: [PATCH] JAL-845 first rough applet SplitFrame (add parameter file2) --- help/html/features/multipleViews.html | 4 +- resources/lang/Messages.properties | 3 +- src/jalview/appletgui/AlignFrame.java | 136 +++-- src/jalview/appletgui/AlignmentPanel.java | 3 +- src/jalview/appletgui/EmbmenuFrame.java | 65 +-- src/jalview/appletgui/SplitFrame.java | 107 ++++ src/jalview/bin/JalviewLite.java | 902 +++++++++++++++++------------ src/jalview/gui/AlignFrame.java | 2 +- src/jalview/gui/SplitFrame.java | 12 + 9 files changed, 771 insertions(+), 463 deletions(-) create mode 100644 src/jalview/appletgui/SplitFrame.java diff --git a/help/html/features/multipleViews.html b/help/html/features/multipleViews.html index b1ccf4b..725f9d0 100644 --- a/help/html/features/multipleViews.html +++ b/help/html/features/multipleViews.html @@ -47,8 +47,8 @@ something more meaningful.

as tabs within a single alignment window. They can be viewed simultanously by pressing X (or via "View→Expand") to expand each view into its own linked alignment window. Expanded views -are gathered back into into a single tabbed alignment window by pressing -G, or by selecting "View→Gather"). +are gathered back into a single tabbed alignment window by pressing +G, or by selecting "View→Gather".

Hidden Sequence Representatives and Multiple Views

diff --git a/resources/lang/Messages.properties b/resources/lang/Messages.properties index 0319c9d..801d7a0 100644 --- a/resources/lang/Messages.properties +++ b/resources/lang/Messages.properties @@ -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 diff --git a/src/jalview/appletgui/AlignFrame.java b/src/jalview/appletgui/AlignFrame.java index 5599695..aa7aed3 100644 --- a/src/jalview/appletgui/AlignFrame.java +++ b/src/jalview/appletgui/AlignFrame.java @@ -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 diff --git a/src/jalview/appletgui/AlignmentPanel.java b/src/jalview/appletgui/AlignmentPanel.java index 61e8f12..6f843d0 100644 --- a/src/jalview/appletgui/AlignmentPanel.java +++ b/src/jalview/appletgui/AlignmentPanel.java @@ -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); diff --git a/src/jalview/appletgui/EmbmenuFrame.java b/src/jalview/appletgui/EmbmenuFrame.java index c527308..4eb3086 100644 --- a/src/jalview/appletgui/EmbmenuFrame.java +++ b/src/jalview/appletgui/EmbmenuFrame.java @@ -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 index 0000000..d77f331 --- /dev/null +++ b/src/jalview/appletgui/SplitFrame.java @@ -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); + } + } +} diff --git a/src/jalview/bin/JalviewLite.java b/src/jalview/bin/JalviewLite.java index ada49cc..ca3de8b 100644 --- a/src/jalview/bin/JalviewLite.java +++ b/src/jalview/bin/JalviewLite.java @@ -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; + /* + * Undocumented for 2.6 - + * related to JAL-434 + */ + + applet.setAlignPdbStructures(getDefaultParameter("alignpdbfiles", + false)); + /* + * + * + * + * + * + */ + + 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()); } - /* - * Undocumented for 2.6 - * - related to JAL-434 - */ - applet.setAlignPdbStructures(getDefaultParameter("alignpdbfiles", - false)); - /* - * - * - * - * - * - */ + } + 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; } diff --git a/src/jalview/gui/AlignFrame.java b/src/jalview/gui/AlignFrame.java index dedff72..30749a5 100644 --- a/src/jalview/gui/AlignFrame.java +++ b/src/jalview/gui/AlignFrame.java @@ -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); } /** diff --git a/src/jalview/gui/SplitFrame.java b/src/jalview/gui/SplitFrame.java index 486db47..791e04f 100644 --- a/src/jalview/gui/SplitFrame.java +++ b/src/jalview/gui/SplitFrame.java @@ -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. + *

+ * (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; -- 1.7.10.2