From ecfc49bc5a7e416c0f967677651923993f105dd8 Mon Sep 17 00:00:00 2001 From: Jim Procter Date: Wed, 2 Jul 2014 15:49:47 -0700 Subject: [PATCH] JAL-1333 JAL-1527 refactors to create core structure viewer binding architecture and StructureViewer factory for creating structure views with the currently preferred viewer --- src/jalview/api/SequenceStructureBinding.java | 21 +++- .../api/structures/JalviewStructureDisplayI.java | 39 +++++++ src/jalview/appletgui/AppletJmol.java | 2 +- src/jalview/ext/jmol/JalviewJmolBinding.java | 44 +------- src/jalview/ext/varna/JalviewVarnaBinding.java | 3 +- src/jalview/gui/AppJmol.java | 12 +- src/jalview/gui/Jalview2XML.java | 18 +-- src/jalview/gui/PopupMenu.java | 13 ++- src/jalview/gui/StructureViewer.java | 117 ++++++++++++++++++++ .../models/SequenceStructureBindingModel.java | 72 ++++++++++++ 10 files changed, 281 insertions(+), 60 deletions(-) create mode 100644 src/jalview/api/structures/JalviewStructureDisplayI.java create mode 100644 src/jalview/gui/StructureViewer.java create mode 100644 src/jalview/structures/models/SequenceStructureBindingModel.java diff --git a/src/jalview/api/SequenceStructureBinding.java b/src/jalview/api/SequenceStructureBinding.java index 5047699..32c5bca 100644 --- a/src/jalview/api/SequenceStructureBinding.java +++ b/src/jalview/api/SequenceStructureBinding.java @@ -29,6 +29,23 @@ package jalview.api; public interface SequenceStructureBinding { - // todo: decide what this really means - we could return a reference to the - // alignment/jmol binding, or some other binding. + /** + * + * @return true if Jalview or the Viewer is still restoring state or loading + * is still going on (see setFinsihedLoadingFromArchive) + */ + void setLoadingFromArchive(boolean loadingFromArchive); + + boolean isLoadingFromArchive(); + + /** + * modify flag which controls if sequence colouring events are honoured by the + * binding. Should be true for normal operation + * + * @param finishedLoading + */ + void setFinishedLoadingFromArchive(boolean finishedLoading); + + boolean isLoadingFinished(); + } diff --git a/src/jalview/api/structures/JalviewStructureDisplayI.java b/src/jalview/api/structures/JalviewStructureDisplayI.java new file mode 100644 index 0000000..e37f467 --- /dev/null +++ b/src/jalview/api/structures/JalviewStructureDisplayI.java @@ -0,0 +1,39 @@ +package jalview.api.structures; + +import jalview.api.FeatureRenderer; +import jalview.api.SequenceRenderer; +import jalview.api.SequenceStructureBinding; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.SequenceI; +import jalview.ext.jmol.JalviewJmolBinding; +import jalview.structure.StructureMappingcommandSet; +import jalview.structure.StructureSelectionManager; + +public interface JalviewStructureDisplayI +{ + + SequenceStructureBinding getBinding(); + + /** + * @return true if there is an active GUI handling a structure display + */ + boolean isVisible(); + + /** + * enable or disable the structure display - note this might just hide or show a GUI element, but not actually reset the display + * @param b + */ + void setVisible(boolean b); + + /** + * free up any external resources that were used by this display and collect garbage + */ + void dispose(); + + /** + * shutdown any structure viewing processes started by this display + */ + void closeViewer(); + + +} diff --git a/src/jalview/appletgui/AppletJmol.java b/src/jalview/appletgui/AppletJmol.java index 3d1d0fb..bf82bca 100644 --- a/src/jalview/appletgui/AppletJmol.java +++ b/src/jalview/appletgui/AppletJmol.java @@ -34,7 +34,7 @@ import jalview.util.MessageManager; public class AppletJmol extends EmbmenuFrame implements // StructureListener, - KeyListener, ActionListener, ItemListener, SequenceStructureBinding + KeyListener, ActionListener, ItemListener { Menu fileMenu = new Menu(MessageManager.getString("action.file")); diff --git a/src/jalview/ext/jmol/JalviewJmolBinding.java b/src/jalview/ext/jmol/JalviewJmolBinding.java index c075bf5..cadb205 100644 --- a/src/jalview/ext/jmol/JalviewJmolBinding.java +++ b/src/jalview/ext/jmol/JalviewJmolBinding.java @@ -35,6 +35,7 @@ import jalview.schemes.ResidueProperties; import jalview.structure.StructureListener; import jalview.structure.StructureMapping; import jalview.structure.StructureSelectionManager; +import jalview.structures.models.SequenceStructureBindingModel; import java.awt.Color; import java.awt.Container; @@ -56,26 +57,13 @@ import org.jmol.api.JmolViewer; import org.jmol.constant.EnumCallback; import org.jmol.popup.JmolPopup; -public abstract class JalviewJmolBinding implements StructureListener, +public abstract class JalviewJmolBinding extends SequenceStructureBindingModel implements StructureListener, JmolStatusListener, SequenceStructureBinding, JmolSelectionListener, ComponentListener, StructureSelectionManagerProvider { /** - * set if Jmol state is being restored from some source - instructs binding - * not to apply default display style when structure set is updated for first - * time. - */ - private boolean loadingFromArchive = false; - - /** - * second flag to indicate if the jmol viewer should ignore sequence colouring - * events from the structure manager because the GUI is still setting up - */ - private boolean loadingFinished = true; - - /** * state flag used to check if the Jmol viewer's paint method can be called */ private boolean finishedInit = false; @@ -641,7 +629,7 @@ public abstract class JalviewJmolBinding implements StructureListener, public void colourBySequence(boolean showFeatures, jalview.api.AlignmentViewPanel alignmentv) { - if (!colourBySequence || !loadingFinished) + if (!colourBySequence || !isLoadingFinished()) return; if (ssm == null) { @@ -1509,32 +1497,6 @@ public abstract class JalviewJmolBinding implements StructureListener, showConsole(false); } - public void setLoadingFromArchive(boolean loadingFromArchive) - { - this.loadingFromArchive = loadingFromArchive; - } - - /** - * - * @return true if Jmol is still restoring state or loading is still going on - * (see setFinsihedLoadingFromArchive) - */ - public boolean isLoadingFromArchive() - { - return loadingFromArchive && !loadingFinished; - } - - /** - * modify flag which controls if sequence colouring events are honoured by the - * binding. Should be true for normal operation - * - * @param finishedLoading - */ - public void setFinishedLoadingFromArchive(boolean finishedLoading) - { - loadingFinished = finishedLoading; - } - public void setBackgroundColour(java.awt.Color col) { jmolHistory(false); diff --git a/src/jalview/ext/varna/JalviewVarnaBinding.java b/src/jalview/ext/varna/JalviewVarnaBinding.java index 9e9434c..6a32f30 100644 --- a/src/jalview/ext/varna/JalviewVarnaBinding.java +++ b/src/jalview/ext/varna/JalviewVarnaBinding.java @@ -25,8 +25,9 @@ import java.awt.event.*; import jalview.api.SequenceStructureBinding; import jalview.api.StructureSelectionManagerProvider; import jalview.structure.*; +import jalview.structures.models.SequenceStructureBindingModel; -public abstract class JalviewVarnaBinding implements StructureListener, +public abstract class JalviewVarnaBinding extends SequenceStructureBindingModel implements StructureListener, SequenceStructureBinding, ComponentListener, StructureSelectionManagerProvider diff --git a/src/jalview/gui/AppJmol.java b/src/jalview/gui/AppJmol.java index 6eb6ac3..bcdc2de 100644 --- a/src/jalview/gui/AppJmol.java +++ b/src/jalview/gui/AppJmol.java @@ -22,6 +22,7 @@ package jalview.gui; import java.util.*; import java.awt.*; + import javax.swing.*; import javax.swing.event.*; @@ -30,17 +31,19 @@ import java.io.*; import jalview.jbgui.GStructureViewer; import jalview.api.SequenceStructureBinding; +import jalview.api.structures.JalviewStructureDisplayI; import jalview.bin.Cache; import jalview.datamodel.*; import jalview.gui.ViewSelectionMenu.ViewSetProvider; import jalview.datamodel.PDBEntry; +import jalview.ext.jmol.JalviewJmolBinding; import jalview.io.*; import jalview.schemes.*; import jalview.util.MessageManager; import jalview.util.Platform; public class AppJmol extends GStructureViewer implements Runnable, - SequenceStructureBinding, ViewSetProvider + ViewSetProvider, JalviewStructureDisplayI { AppJmolBinding jmb; @@ -688,7 +691,7 @@ public class AppJmol extends GStructureViewer implements Runnable, jmb.centerViewer(toshow); } - void closeViewer() + public void closeViewer() { jmb.closeViewer(); ap = null; @@ -1356,4 +1359,9 @@ public class AppJmol extends GStructureViewer implements Runnable, return !jmb.isColourBySequence(); } + public JalviewJmolBinding getBinding() + { + return jmb; + } + } diff --git a/src/jalview/gui/Jalview2XML.java b/src/jalview/gui/Jalview2XML.java index 8cad9ca..f3bc42e 100644 --- a/src/jalview/gui/Jalview2XML.java +++ b/src/jalview/gui/Jalview2XML.java @@ -32,6 +32,7 @@ import javax.swing.*; import org.exolab.castor.xml.*; +import jalview.api.structures.JalviewStructureDisplayI; import jalview.bin.Cache; import jalview.datamodel.Alignment; import jalview.datamodel.AlignmentAnnotation; @@ -1795,7 +1796,7 @@ public class Jalview2XML try { // create list to store references for any new Jmol viewers created - newStructureViewers = new Vector(); + newStructureViewers = new Vector(); // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING // Workaround is to make sure caller implements the JarInputStreamProvider // interface @@ -3132,10 +3133,11 @@ public class Jalview2XML @Override public void run() { - AppJmol sview = null; + JalviewStructureDisplayI sview = null; try { - sview = new AppJmol(pdbf, id, sq, alf.alignPanel, + // JAL-1333 note - we probably can't migrate Jmol views to UCSF Chimera! + sview = new StructureViewer(alf.alignPanel.getStructureSelectionManager()).createView(StructureViewer.Viewer.JMOL, pdbf, id, sq, alf.alignPanel, useinJmolsuperpos, usetoColourbyseq, jmolColouring, fileloc, rect, vid); addNewStructureViewer(sview); @@ -3265,13 +3267,13 @@ public class Jalview2XML return true; } - Vector newStructureViewers = null; + Vector newStructureViewers = null; - protected void addNewStructureViewer(AppJmol sview) + protected void addNewStructureViewer(JalviewStructureDisplayI sview) { if (newStructureViewers != null) { - sview.jmb.setFinishedLoadingFromArchive(false); + sview.getBinding().setFinishedLoadingFromArchive(false); newStructureViewers.add(sview); } } @@ -3280,9 +3282,9 @@ public class Jalview2XML { if (newStructureViewers != null) { - for (AppJmol sview : newStructureViewers) + for (JalviewStructureDisplayI sview : newStructureViewers) { - sview.jmb.setFinishedLoadingFromArchive(true); + sview.getBinding().setFinishedLoadingFromArchive(true); } newStructureViewers.clear(); newStructureViewers = null; diff --git a/src/jalview/gui/PopupMenu.java b/src/jalview/gui/PopupMenu.java index 3cf4fe0..e256b33 100644 --- a/src/jalview/gui/PopupMenu.java +++ b/src/jalview/gui/PopupMenu.java @@ -256,9 +256,12 @@ public class PopupMenu extends JPopupMenu { // TODO re JAL-860: optionally open dialog or provide a menu entry // allowing user to open just one structure per sequence - new AppJmol(pdb, ap.av.collateForPDB(new PDBEntry[] - { pdb })[0], null, ap); - // new PDBViewer(pdb, seqs2, null, ap, AppletFormatAdapter.FILE); + //new AppJmol(pdb, ap.av.collateForPDB(new PDBEntry[] + //{ pdb })[0], null, ap); + new StructureViewer(ap.getStructureSelectionManager()) + .viewStructures(pdb, + ap.av.collateForPDB(new PDBEntry[] + { pdb })[0], null, ap); } }); @@ -558,7 +561,7 @@ public class PopupMenu extends JPopupMenu @Override public void actionPerformed(ActionEvent e) { - new AppJmol(ap, pe, ap.av.collateForPDB(pe)); + new StructureViewer(ap.getStructureSelectionManager()).viewStructures(ap, pe, ap.av.collateForPDB(pe)); } }); if (reppdb.size() > 1 && reppdb.size() < pdbe.size()) @@ -576,7 +579,7 @@ public class PopupMenu extends JPopupMenu @Override public void actionPerformed(ActionEvent e) { - new AppJmol(ap, pr, ap.av.collateForPDB(pr)); + new StructureViewer(ap.getStructureSelectionManager()).viewStructures(ap, pr, ap.av.collateForPDB(pr)); } }); } diff --git a/src/jalview/gui/StructureViewer.java b/src/jalview/gui/StructureViewer.java new file mode 100644 index 0000000..ce22d84 --- /dev/null +++ b/src/jalview/gui/StructureViewer.java @@ -0,0 +1,117 @@ +/* + * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2) + * Copyright (C) 2014 The Jalview Authors + * + * This file is part of Jalview. + * + * Jalview is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * Jalview is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Jalview. If not, see . + * The Jalview Authors are detailed in the 'AUTHORS' file. + */ +package jalview.gui; + +import java.awt.Rectangle; + +import jalview.api.structures.JalviewStructureDisplayI; +import jalview.bin.Cache; +import jalview.datamodel.PDBEntry; +import jalview.datamodel.SequenceI; +import jalview.gui.StructureViewer.Viewer; +import jalview.structure.StructureSelectionManager; + +/** + * proxy for handling structure viewers. + * + * this allows new views to be created with the currently configured viewer, the + * preferred viewer to be set/read and existing views created previously with a + * particular viewer to be recovered + * + * @author jprocter + */ +public class StructureViewer +{ + StructureSelectionManager ssm; + + public enum Viewer + { + JMOL, CHIMERA + }; + + public Viewer getViewerType() + { + String viewType = Cache.getDefault("STRUCTURE_DISPLAY", "JMOL"); + return Viewer.valueOf(viewType); + } + + public void setViewerType(Viewer type) + { + Cache.setProperty("STRUCTURE_DISPLAY", type.toString()); + } + + public StructureViewer(StructureSelectionManager structureSelectionManager) + { + ssm = structureSelectionManager; + } + + public JalviewStructureDisplayI viewStructures(AlignmentPanel ap, + PDBEntry[] pr, SequenceI[][] collateForPDB) + { + JalviewStructureDisplayI sview = null; + switch (getViewerType()) + { + case JMOL: + + sview = new AppJmol(ap, pr, ap.av.collateForPDB(pr)); + + break; + case CHIMERA: + break; + default: + Cache.log.error("Unknown structure viewer type " + + getViewerType().toString()); + } + return sview; + } + + public JalviewStructureDisplayI viewStructures(PDBEntry pdb, + SequenceI[] sequenceIs, Object object, AlignmentPanel ap) + { + return viewStructures(ap, new PDBEntry[] + { pdb }, new SequenceI[][] + { sequenceIs }); + } + + public JalviewStructureDisplayI createView(Viewer jmol, String[] pdbf, + String[] id, SequenceI[][] sq, AlignmentPanel alignPanel, + boolean useinJmolsuperpos, boolean usetoColourbyseq, + boolean jmolColouring, String fileloc, Rectangle rect, String vid) + { + JalviewStructureDisplayI sview = null; + switch (getViewerType()) + { + case JMOL: + + sview = new AppJmol(pdbf, id, sq, alignPanel, useinJmolsuperpos, + usetoColourbyseq, jmolColouring, fileloc, rect, vid); + + break; + case CHIMERA: + break; + default: + Cache.log.error("Unknown structure viewer type " + + getViewerType().toString()); + } + return sview; + } + +} diff --git a/src/jalview/structures/models/SequenceStructureBindingModel.java b/src/jalview/structures/models/SequenceStructureBindingModel.java new file mode 100644 index 0000000..7d023a8 --- /dev/null +++ b/src/jalview/structures/models/SequenceStructureBindingModel.java @@ -0,0 +1,72 @@ +/* + * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2) + * Copyright (C) 2014 The Jalview Authors + * + * This file is part of Jalview. + * + * Jalview is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * Jalview is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Jalview. If not, see . + * The Jalview Authors are detailed in the 'AUTHORS' file. + */ +package jalview.structures.models; + +import jalview.api.SequenceStructureBinding; + +public class SequenceStructureBindingModel implements + SequenceStructureBinding +{ + + /** + * set if Structure Viewer state is being restored from some source - + * instructs binding not to apply default display style when structure set is + * updated for first time. + */ + private boolean loadingFromArchive = false; + + /** + * second flag to indicate if the Structure viewer should ignore sequence + * colouring events from the structure manager because the GUI is still + * setting up + */ + private boolean loadingFinished = true; + + @Override + public void setLoadingFromArchive(boolean loadingFromArchive) + { + this.loadingFromArchive = loadingFromArchive; + } + + /** + * + * @return true if Jmol is still restoring state or loading is still going on + * (see setFinsihedLoadingFromArchive) + */ + @Override + public boolean isLoadingFromArchive() + { + return loadingFromArchive && !loadingFinished; + } + + @Override + public boolean isLoadingFinished() + { + return loadingFinished; + } + + @Override + public void setFinishedLoadingFromArchive(boolean finishedLoading) + { + loadingFinished = finishedLoading; + } + +} -- 1.7.10.2