From 733974a24ce2eb5755c46bbb2a41674493d04740 Mon Sep 17 00:00:00 2001 From: kjvdheide Date: Thu, 14 Dec 2017 17:00:12 +0000 Subject: [PATCH] JAL-1953 more progress on interfaces, jalview binding still problematic --- forester | 2 +- src/jalview/ext/archaeopteryx/AptxConfig.java | 14 - .../ext/archaeopteryx/AptxControlPanel.java | 2 +- src/jalview/ext/archaeopteryx/AptxFrame.java | 170 ++++++++++- src/jalview/ext/archaeopteryx/AptxInit.java | 18 +- src/jalview/ext/archaeopteryx/AptxTreeBuilder.java | 5 +- src/jalview/ext/archaeopteryx/AptxTreePanel.java | 107 ++++++- .../DataConversions.java | 34 +-- src/jalview/ext/archaeopteryx/JalviewBinding.java | 9 +- src/jalview/ext/archaeopteryx/Tree.java | 29 +- src/jalview/ext/archaeopteryx/TreeIterator.java | 2 +- src/jalview/ext/archaeopteryx/TreeNode.java | 124 +++++++- src/jalview/ext/archaeopteryx/TreeParser.java | 47 +++ src/jalview/ext/forester/ForesterMatrix.java | 1 + src/jalview/ext/forester/UtilityMethods.java | 25 ++ src/jalview/ext/forester/io/TreeParser.java | 23 +- src/jalview/ext/treeviewer/ExternalTreeFrame.java | 38 ++- src/jalview/ext/treeviewer/ExternalTreeI.java | 1 + .../ext/treeviewer/ExternalTreeIteratorI.java | 6 - src/jalview/ext/treeviewer/ExternalTreePanel.java | 23 +- .../ext/treeviewer/ExternalTreeParserI.java | 31 +- .../LoadedTreeSequenceAssociation.java | 14 +- .../ext/archaeopteryx/AptxPhylogenyTreeTest.java | 308 ++++++++++---------- test/jalview/ext/archaeopteryx/TreeViewTest.java | 5 +- 24 files changed, 742 insertions(+), 296 deletions(-) delete mode 100644 src/jalview/ext/archaeopteryx/AptxConfig.java rename src/jalview/ext/{forester => archaeopteryx}/DataConversions.java (62%) create mode 100644 src/jalview/ext/archaeopteryx/TreeParser.java create mode 100644 src/jalview/ext/forester/UtilityMethods.java delete mode 100644 src/jalview/ext/treeviewer/ExternalTreeIteratorI.java rename src/jalview/ext/{archaeopteryx => treeviewer}/LoadedTreeSequenceAssociation.java (89%) diff --git a/forester b/forester index 835739d..20ce936 160000 --- a/forester +++ b/forester @@ -1 +1 @@ -Subproject commit 835739d782b7099677aadf653ecc682cf74fc87f +Subproject commit 20ce9361380c461b8a7053100207034314e56e23 diff --git a/src/jalview/ext/archaeopteryx/AptxConfig.java b/src/jalview/ext/archaeopteryx/AptxConfig.java deleted file mode 100644 index 9563a0a..0000000 --- a/src/jalview/ext/archaeopteryx/AptxConfig.java +++ /dev/null @@ -1,14 +0,0 @@ -package jalview.ext.archaeopteryx; - -import org.forester.archaeopteryx.Configuration; - -public class AptxConfig -{ - private final Configuration config; - - public AptxConfig(Configuration aptxConfig) - { - config = aptxConfig; - } - -} diff --git a/src/jalview/ext/archaeopteryx/AptxControlPanel.java b/src/jalview/ext/archaeopteryx/AptxControlPanel.java index 6c1bfb4..facbe01 100644 --- a/src/jalview/ext/archaeopteryx/AptxControlPanel.java +++ b/src/jalview/ext/archaeopteryx/AptxControlPanel.java @@ -8,7 +8,7 @@ public class AptxControlPanel implements ExternalTreeControlsI { ControlPanel aptxCp; - public AptxControlPanel(ControlPanel aptxControlPanel) + protected AptxControlPanel(ControlPanel aptxControlPanel) { aptxCp = aptxControlPanel; diff --git a/src/jalview/ext/archaeopteryx/AptxFrame.java b/src/jalview/ext/archaeopteryx/AptxFrame.java index 4223147..b00b24d 100644 --- a/src/jalview/ext/archaeopteryx/AptxFrame.java +++ b/src/jalview/ext/archaeopteryx/AptxFrame.java @@ -4,23 +4,42 @@ import jalview.ext.treeviewer.ExternalTreeControlsI; import jalview.ext.treeviewer.ExternalTreeFrame; import jalview.ext.treeviewer.ExternalTreeI; import jalview.ext.treeviewer.ExternalTreePanel; +import jalview.gui.Desktop; import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Event; +import java.awt.Font; +import java.awt.Image; +import java.awt.MenuComponent; +import javax.accessibility.AccessibleContext; +import javax.swing.JLayeredPane; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; +import javax.swing.JRootPane; import javax.swing.JSeparator; +import javax.swing.event.InternalFrameListener; import org.forester.archaeopteryx.MainFrame; -public class AptxFrame extends ExternalTreeFrame +public class AptxFrame implements ExternalTreeFrame { private final MainFrame aptxFrame; + private ExternalTreePanel aptxPanel; + + private ExternalTreeControlsI aptxControls; + public AptxFrame(MainFrame aptx) { aptxFrame = aptx; + aptxPanel = new AptxTreePanel( + aptxFrame.getMainPanel().getCurrentTreePanel()); + aptxControls = new AptxControlPanel( + aptxFrame.getMainPanel().getControlPanel()); adaptAptxGui(aptxFrame); } @@ -83,23 +102,13 @@ public class AptxFrame extends ExternalTreeFrame @Override public ExternalTreePanel getTreePanel() { - ExternalTreePanel aptxPanel = new AptxTreePanel( - aptxFrame.getMainPanel().getCurrentTreePanel()); return aptxPanel; } @Override - public void switchTreePanel(int panelIndex) - { - aptxFrame.getMainPanel().getTabbedPane().getTabComponentAt(panelIndex); - - } - - @Override public ExternalTreeI getTree() { - return new Tree( - aptxFrame.getMainPanel().getCurrentTreePanel().getPhylogeny()); + return aptxPanel.getTree(); } @Override @@ -118,6 +127,141 @@ public class AptxFrame extends ExternalTreeFrame @Override public ExternalTreeControlsI getTreeControls() { - return new AptxControlPanel(aptxFrame.getMainPanel().getControlPanel()); + return aptxControls; + } + + @Override + public AccessibleContext getAccessibleContext() + { + return aptxFrame.getAccessibleContext(); + } + + @Override + public JRootPane getRootPane() + { + return aptxFrame.getRootPane(); + } + + @Override + public void setContentPane(Container contentPane) + { + aptxFrame.setContentPane(contentPane); + + } + + @Override + public Container getContentPane() + { + return aptxFrame.getContentPane(); + } + + @Override + public void setLayeredPane(JLayeredPane layeredPane) + { + aptxFrame.setLayeredPane(layeredPane); + + } + + @Override + public JLayeredPane getLayeredPane() + { + return aptxFrame.getLayeredPane(); + } + + @Override + public void setGlassPane(Component glassPane) + { + aptxFrame.setGlassPane(glassPane); + + } + + @Override + public Component getGlassPane() + { + return aptxFrame.getGlassPane(); + } + + @Override + public boolean imageUpdate(Image img, int infoflags, int x, int y, + int width, int height) + { + return aptxFrame.imageUpdate(img, infoflags, x, y, width, height); + } + + @Override + public Font getFont() + { + return aptxFrame.getFont(); + } + + @Override + public void remove(MenuComponent comp) + { + aptxFrame.remove(comp); + + } + + @Deprecated + @Override + public boolean postEvent(Event evt) + { + return aptxFrame.postEvent(evt); + } + + @Override + public void addFrameListener(InternalFrameListener listener) + { + aptxFrame.addInternalFrameListener(listener); + + } + + @Override + public void removeFrameListener(InternalFrameListener listener) + { + aptxFrame.removeInternalFrameListener(listener); + + } + + @Override + public InternalFrameListener[] getFrameListeners() + { + return aptxFrame.getInternalFrameListeners(); + } + + @Override + public void repaint() + { + aptxFrame.repaint(); + + } + + @Override + public void setMinimumSize(Dimension dimension) + { + aptxFrame.setMinimumSize(dimension); + + } + + @Override + public boolean isShowing() + { + return aptxFrame.isShowing(); + } + + @Override + public Container getTopLevelAncestor() + { + return aptxFrame.getTopLevelAncestor(); + } + + @Override + public void addFrameToJalview(String title, boolean makeVisible, + int width, int height, boolean resizable, boolean ignoreMinSize) + { + Desktop.addInternalFrame(aptxFrame, title, makeVisible, width, height, + resizable, ignoreMinSize); + + } + } \ No newline at end of file diff --git a/src/jalview/ext/archaeopteryx/AptxInit.java b/src/jalview/ext/archaeopteryx/AptxInit.java index e8fa7d0..d0fb9fe 100644 --- a/src/jalview/ext/archaeopteryx/AptxInit.java +++ b/src/jalview/ext/archaeopteryx/AptxInit.java @@ -2,12 +2,14 @@ package jalview.ext.archaeopteryx; import jalview.analysis.TreeBuilder; import jalview.datamodel.SequenceI; +import jalview.ext.forester.UtilityMethods; import jalview.ext.treeviewer.ExternalLoadedTreeAssociationI; import jalview.ext.treeviewer.ExternalTreeBuilderI; import jalview.ext.treeviewer.ExternalTreeFrame; import jalview.ext.treeviewer.ExternalTreeI; import jalview.ext.treeviewer.ExternalTreeNodeI; import jalview.ext.treeviewer.ExternalTreeViewerBindingI; +import jalview.ext.treeviewer.LoadedTreeSequenceAssociation; import jalview.gui.Desktop; import jalview.gui.JvOptionPane; import jalview.util.MessageManager; @@ -70,6 +72,7 @@ public final class AptxInit + public static ExternalTreeFrame createInstanceFromCalculation( final TreeBuilder calculatedTree) { @@ -99,13 +102,9 @@ public final class AptxInit throws FileNotFoundException, IOException { File treeFile = new File(filePath); - final String err = ForesterUtil.isReadableFile(treeFile); - if (!ForesterUtil.isEmpty(err)) + ExternalTreeFrame[] aptxFrames = null; + if (UtilityMethods.canForesterReadFile(treeFile)) { - JvOptionPane.showMessageDialog(Desktop.desktop, err, - MessageManager.getString("label.problem_reading_tree_file"), - JvOptionPane.WARNING_MESSAGE); - } if (Desktop.instance != null) { @@ -142,7 +141,7 @@ public final class AptxInit } Phylogeny[] trees = PhylogenyMethods.readPhylogenies(parser, treeFile); - ExternalTreeFrame[] aptxFrames = new ExternalTreeFrame[trees.length]; + aptxFrames = new ExternalTreeFrame[trees.length]; for (int i = 0; i < trees.length; i++) @@ -163,6 +162,7 @@ public final class AptxInit if (Desktop.instance != null) { Desktop.instance.stopLoading(); + } } return aptxFrames; } @@ -520,7 +520,7 @@ public final class AptxInit final Map alignMappedToNodes, final Map nodesMappedToAlign) { - JalviewBinding treeBinding = new JalviewBinding(aptxApp, + ExternalTreeViewerBindingI treeBinding = new JalviewBinding(aptxApp, jalviewAlignViewport, alignMappedToNodes, nodesMappedToAlign); activeAptx.put(aptxApp, treeBinding); @@ -544,7 +544,7 @@ public final class AptxInit new String[] { treeFile.getAbsolutePath() }); } - Desktop.addInternalFrame(aptxApp, frameTitle, true, width, height, true, + aptxApp.addFrameToJalview(frameTitle, true, width, height, true, true); return aptxApp; diff --git a/src/jalview/ext/archaeopteryx/AptxTreeBuilder.java b/src/jalview/ext/archaeopteryx/AptxTreeBuilder.java index 54bcff1..c6f7898 100644 --- a/src/jalview/ext/archaeopteryx/AptxTreeBuilder.java +++ b/src/jalview/ext/archaeopteryx/AptxTreeBuilder.java @@ -53,7 +53,7 @@ public class AptxTreeBuilder jalviewTree.getDistances(), sequences); aptxTree = new Tree(new Phylogeny()); - rootNode = new TreeNode(new PhylogenyNode()); + rootNode = TreeNode.getUniqueWrapper(new PhylogenyNode()); int amountOfSequences = distances.getSize(); alignmentWithNodes = new HashMap<>(amountOfSequences); @@ -85,7 +85,8 @@ public class AptxTreeBuilder for (SequenceI sequence : sequences) { - ExternalTreeNodeI sequenceNode = new TreeNode( + ExternalTreeNodeI sequenceNode = TreeNode + .getUniqueWrapper( new PhylogenyNode(sequence.getName())); sequenceNode.setSequence(sequence); diff --git a/src/jalview/ext/archaeopteryx/AptxTreePanel.java b/src/jalview/ext/archaeopteryx/AptxTreePanel.java index 94e0f91..d8a57d0 100644 --- a/src/jalview/ext/archaeopteryx/AptxTreePanel.java +++ b/src/jalview/ext/archaeopteryx/AptxTreePanel.java @@ -3,18 +3,30 @@ package jalview.ext.archaeopteryx; import jalview.ext.treeviewer.ExternalTreeI; import jalview.ext.treeviewer.ExternalTreeNodeI; import jalview.ext.treeviewer.ExternalTreePanel; +import jalview.gui.PaintRefresher; +import java.awt.Event; +import java.awt.Font; +import java.awt.MenuComponent; +import java.awt.event.MouseListener; import java.io.File; import java.util.Set; -public class AptxTreePanel extends ExternalTreePanel +import javax.accessibility.AccessibleContext; + +public class AptxTreePanel implements ExternalTreePanel { private final org.forester.archaeopteryx.TreePanel treeView; - public AptxTreePanel(org.forester.archaeopteryx.TreePanel aptxTreePanel) + private final Tree tree; + + private String sequenceSetId; + + protected AptxTreePanel( + org.forester.archaeopteryx.TreePanel aptxTreePanel) { treeView = aptxTreePanel; - + tree = new Tree(treeView.getPhylogeny()); } @Override @@ -26,7 +38,7 @@ public class AptxTreePanel extends ExternalTreePanel @Override public ExternalTreeI getTree() { - return new Tree(treeView.getPhylogeny()); + return tree; } @Override @@ -38,7 +50,7 @@ public class AptxTreePanel extends ExternalTreePanel @Override public ExternalTreeNodeI findNode(int x, int y) { - return new TreeNode(treeView.findNode(x, y)); + return TreeNode.getUniqueWrapper(treeView.findNode(x, y)); } @Override @@ -53,4 +65,89 @@ public class AptxTreePanel extends ExternalTreePanel { return treeView.getFoundNodes0(); } + + @Override + public AccessibleContext getAccessibleContext() + { + return treeView.getAccessibleContext(); + } + + @Override + public Font getFont() + { + return treeView.getFont(); + } + + @Override + public void remove(MenuComponent comp) + { + treeView.remove(comp); + + } + + @Deprecated + @Override + public boolean postEvent(Event evt) + { + return treeView.postEvent(evt); + } + + @Override + public void addMouseListener(MouseListener listener) + { + treeView.addMouseListener(listener); + } + + @Override + public void removeMouseListener(MouseListener listener) + { + treeView.removeMouseListener(listener); + + } + + @Override + public MouseListener[] getMouseListeners() + { + return treeView.getMouseListeners(); + } + + @Override + public void repaint() + { + treeView.repaint(); + + } + + @Override + public void registerWithPaintRefresher(String sequenceSetIdentifier) + { + sequenceSetId = sequenceSetIdentifier; + PaintRefresher.Register(treeView, sequenceSetIdentifier); + + } + + @Override + public void notifyPaintRefresher(String sequenceSetIdentifier, + boolean alignmentChanged, boolean validateSequences) + { + PaintRefresher.Refresh(treeView, sequenceSetIdentifier, + alignmentChanged, validateSequences); + + } + + @Override + public void notifyPaintRefresher(boolean alignmentChanged, + boolean validateSequences) + { + if (sequenceSetId != null) + { + PaintRefresher.Refresh(treeView, sequenceSetId, alignmentChanged, + validateSequences); + } + else + { + // throw some kind of exception + } + + } } diff --git a/src/jalview/ext/forester/DataConversions.java b/src/jalview/ext/archaeopteryx/DataConversions.java similarity index 62% rename from src/jalview/ext/forester/DataConversions.java rename to src/jalview/ext/archaeopteryx/DataConversions.java index 22c4df0..e7fb2de 100644 --- a/src/jalview/ext/forester/DataConversions.java +++ b/src/jalview/ext/archaeopteryx/DataConversions.java @@ -1,16 +1,11 @@ -package jalview.ext.forester; +package jalview.ext.archaeopteryx; import jalview.datamodel.SequenceI; -import jalview.ext.archaeopteryx.TreeNode; -import jalview.ext.treeviewer.ExternalTreeNodeI; +import jalview.ext.forester.ForesterMatrix; import jalview.math.MatrixI; -import java.util.ArrayList; -import java.util.List; - import org.forester.evoinference.matrix.distance.DistanceMatrix; import org.forester.io.parsers.phyloxml.PhyloXmlDataFormatException; -import org.forester.phylogeny.PhylogenyNode; public final class DataConversions { @@ -23,14 +18,14 @@ public final class DataConversions { foresterSeq.setName(jalviewSequence.getDescription()); } - foresterSeq.setMolecularSequenceAligned(sequenceIsAligned); // all tree - // sequences - // should - // be aligned - // already + + // all tree sequences should be aligned already + foresterSeq.setMolecularSequenceAligned(sequenceIsAligned); + foresterSeq.setMolecularSequence(jalviewSequence.getSequenceAsString()); - if (jalviewSequence.isProtein()) // add checks for DNA or RNA (infer from - // forester itself?) + + // add checks for DNA or RNA (infer from forester itself?) + if (jalviewSequence.isProtein()) { try { @@ -80,14 +75,5 @@ public final class DataConversions } - public static List getConvertedTreeNodes( - List aptxNodes) - { - List jalviewNodes = new ArrayList<>(); - for (PhylogenyNode aptxNode : aptxNodes) - { - jalviewNodes.add(new TreeNode(aptxNode)); - } - return jalviewNodes; - } + } diff --git a/src/jalview/ext/archaeopteryx/JalviewBinding.java b/src/jalview/ext/archaeopteryx/JalviewBinding.java index 510becf..810a711 100644 --- a/src/jalview/ext/archaeopteryx/JalviewBinding.java +++ b/src/jalview/ext/archaeopteryx/JalviewBinding.java @@ -116,12 +116,12 @@ public final class JalviewBinding ssm.addSelectionListener(this); treeView.addMouseListener(this); - - PaintRefresher.Register(treeView, parentAvport.getSequenceSetId()); + treeView.registerWithPaintRefresher( + parentAvport.getSequenceSetId()); associatedPanels = PaintRefresher .getAssociatedPanels(parentAvport.getSequenceSetId()); - aptxFrame.addInternalFrameListener(new InternalFrameAdapter() + aptxFrame.addFrameListener(new InternalFrameAdapter() { @Override @@ -202,7 +202,8 @@ public final class JalviewBinding partitionTree(e.getX()); } - PaintRefresher.Refresh(treeView, parentAvport.getSequenceSetId()); + treeView.notifyPaintRefresher(parentAvport.getSequenceSetId(), + false, false); treeView.repaint(); diff --git a/src/jalview/ext/archaeopteryx/Tree.java b/src/jalview/ext/archaeopteryx/Tree.java index d06339e..e9bfb9b 100644 --- a/src/jalview/ext/archaeopteryx/Tree.java +++ b/src/jalview/ext/archaeopteryx/Tree.java @@ -15,16 +15,33 @@ public class Tree implements ExternalTreeI { private final Phylogeny tree; + public Tree() + { + tree = new Phylogeny(); + } public Tree(Phylogeny aptxTree) { tree = aptxTree; + wrapAllTreeNodes(); + } + private void wrapAllTreeNodes() + { + for (Iterator iterator = tree + .iteratorPostorder(); iterator.hasNext();) + { + PhylogenyNode foresterNode = iterator.next(); + ExternalTreeNodeI treeNode = TreeNode + .getUniqueWrapper(foresterNode); + + } + } @Override public ExternalTreeNodeI getRoot() { - ExternalTreeNodeI root = new TreeNode(tree.getRoot()); + ExternalTreeNodeI root = TreeNode.getUniqueWrapper(tree.getRoot()); return root; } @@ -38,7 +55,7 @@ public class Tree implements ExternalTreeI @Override public ExternalTreeNodeI getNodeWithName(String name) { - return new TreeNode(tree.getNode(name)); + return TreeNode.getUniqueWrapper(tree.getNode(name)); } @@ -77,9 +94,9 @@ public class Tree implements ExternalTreeI @Override public void setRoot(ExternalTreeNodeI rootNode) { - PhylogenyNode treeRoot = new PhylogenyNode(rootNode.getNodeName()); - // expand this + PhylogenyNode treeRoot = TreeNode.unwrapNode(rootNode); tree.setRoot(treeRoot); + wrapAllTreeNodes(); } @@ -118,7 +135,7 @@ public class Tree implements ExternalTreeI { PhylogenyNode furthestNode = PhylogenyMethods .calculateNodeWithMaxDistanceToRoot(tree); - return new TreeNode(furthestNode); + return TreeNode.getUniqueWrapper(furthestNode); } @Override @@ -128,4 +145,6 @@ public class Tree implements ExternalTreeI AptxInit.APTX_CONFIG, instanceTitle)); } + + } diff --git a/src/jalview/ext/archaeopteryx/TreeIterator.java b/src/jalview/ext/archaeopteryx/TreeIterator.java index 79e8e49..2d82db2 100644 --- a/src/jalview/ext/archaeopteryx/TreeIterator.java +++ b/src/jalview/ext/archaeopteryx/TreeIterator.java @@ -24,7 +24,7 @@ public class TreeIterator implements Iterator @Override public ExternalTreeNodeI next() { - ExternalTreeNodeI node = new TreeNode(iter.next()); + ExternalTreeNodeI node = TreeNode.getUniqueWrapper(iter.next()); return node; } diff --git a/src/jalview/ext/archaeopteryx/TreeNode.java b/src/jalview/ext/archaeopteryx/TreeNode.java index 78b3981..914cdd2 100644 --- a/src/jalview/ext/archaeopteryx/TreeNode.java +++ b/src/jalview/ext/archaeopteryx/TreeNode.java @@ -1,11 +1,13 @@ package jalview.ext.archaeopteryx; import jalview.datamodel.SequenceI; -import jalview.ext.forester.DataConversions; import jalview.ext.treeviewer.ExternalTreeNodeI; import java.awt.Color; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.forester.phylogeny.PhylogenyMethods; import org.forester.phylogeny.PhylogenyNode; @@ -17,9 +19,17 @@ public class TreeNode implements ExternalTreeNodeI private SequenceI nodeSeq; - public TreeNode(PhylogenyNode aptxNode) + private static Map originalNodes = new HashMap<>( + 500); // prolly make this size dynamic + + private static Map wrappedNodes = new HashMap<>( + 500); + + private TreeNode(PhylogenyNode aptxNode) { node = aptxNode; + originalNodes.put(aptxNode, this); + wrappedNodes.put(this, aptxNode); } @@ -30,12 +40,15 @@ public class TreeNode implements ExternalTreeNodeI return node.getName(); } + @Override public List getAllDescendants() { + List descNodes = PhylogenyMethods .getAllDescendants(node); - return DataConversions.getConvertedTreeNodes(descNodes); + return getUniqueWrappers(descNodes); + } @@ -43,7 +56,7 @@ public class TreeNode implements ExternalTreeNodeI public List getExternalDescendants() { List extDescNodes = node.getAllExternalDescendants(); - return DataConversions.getConvertedTreeNodes(extDescNodes); + return getUniqueWrappers(extDescNodes); } @@ -51,7 +64,9 @@ public class TreeNode implements ExternalTreeNodeI public List getDirectChildren() { List childNodes = node.getDescendants(); - return DataConversions.getConvertedTreeNodes(childNodes); + return getUniqueWrappers(childNodes); + + } @@ -76,9 +91,8 @@ public class TreeNode implements ExternalTreeNodeI @Override public void addAsChild(ExternalTreeNodeI childNode) { - PhylogenyNode aptxNode = new PhylogenyNode(childNode.getNodeName()); + PhylogenyNode aptxNode = unwrapNode(childNode); - // expand on this node.addAsChild(aptxNode); } @@ -108,4 +122,100 @@ public class TreeNode implements ExternalTreeNodeI return node.isInternal(); } + public static List getUniqueWrappers( + List aptxNodes) + { + List wrappedNodes = new ArrayList<>( + aptxNodes.size()); + + for (PhylogenyNode aptxNode : aptxNodes) + { + wrappedNodes.add(getUniqueWrapper(aptxNode)); + } + return wrappedNodes; + } + + /** + * This method should be used to create new wrappers as there is a possibility + * the Archaeopteryx node was already introduced to Jalview previously so this + * avoids giving one node duplicate wrappers + * + * @param aptxNode + * @return + */ + public static ExternalTreeNodeI getUniqueWrapper( + PhylogenyNode aptxNode) + { + ExternalTreeNodeI wrappedNode = originalNodes.get(aptxNode); + if (wrappedNode == null) + { + wrappedNode = new TreeNode(aptxNode); + } + + return wrappedNode; + } + + /** + * Attempts to unwrap the given node, if the unwrapped node already exists it + * is simply returned as is. If it is not however, the wrapper will be used to + * create a new Archaeopteryx node. This way it becomes possible to construct + * new Archaeopteryx nodes from different tree viewers, as long as they + * implement the interface. + * + * @param wrappedNode + * @return + */ + protected static PhylogenyNode unwrapNode(ExternalTreeNodeI wrappedNode) + { + PhylogenyNode aptxNode = wrappedNodes.get(wrappedNode); + if (aptxNode == null) + { + // expand this + aptxNode = new PhylogenyNode(wrappedNode.getNodeName()); + } + return aptxNode; + + } + + + @Override + public int hashCode() + { + final int prime = 31; + int result = 1; + result = prime * result + ((node == null) ? 0 : node.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) + { + return true; + } + if (obj == null) + { + return false; + } + if (getClass() != obj.getClass()) + { + return false; + } + TreeNode other = (TreeNode) obj; + if (node == null) + { + if (other.node != null) + { + return false; + } + } + else if (!node.equals(other.node)) + { + return false; + } + return true; + } + + } diff --git a/src/jalview/ext/archaeopteryx/TreeParser.java b/src/jalview/ext/archaeopteryx/TreeParser.java new file mode 100644 index 0000000..79853ed --- /dev/null +++ b/src/jalview/ext/archaeopteryx/TreeParser.java @@ -0,0 +1,47 @@ +package jalview.ext.archaeopteryx; + +import jalview.ext.treeviewer.ExternalTreeI; +import jalview.ext.treeviewer.ExternalTreeParserI; + +import java.io.IOException; + +import org.forester.io.parsers.PhylogenyParser; +import org.forester.phylogeny.Phylogeny; + +public class TreeParser implements ExternalTreeParserI +{ + private final PhylogenyParser parser; + + public TreeParser(PhylogenyParser foresterParser) + { + parser = foresterParser; + } + + @Override + public ExternalTreeI[] parse() throws IOException + { + Phylogeny[] foresterTrees = parser.parse(); + ExternalTreeI[] jalviewTrees = new ExternalTreeI[foresterTrees.length]; + + for (int i = 0; i < foresterTrees.length; i++) + { + jalviewTrees[i] = new Tree(foresterTrees[i]); + } + return jalviewTrees; + + } + + @Override + public void setSource(Object source) throws IOException + { + parser.setSource(source); + + } + + @Override + public String getName() + { + return parser.getName(); + } + +} diff --git a/src/jalview/ext/forester/ForesterMatrix.java b/src/jalview/ext/forester/ForesterMatrix.java index a12dc1d..3fedaa5 100644 --- a/src/jalview/ext/forester/ForesterMatrix.java +++ b/src/jalview/ext/forester/ForesterMatrix.java @@ -1,6 +1,7 @@ package jalview.ext.forester; import jalview.datamodel.SequenceI; +import jalview.ext.archaeopteryx.DataConversions; import jalview.math.MatrixI; import jalview.util.MessageManager; diff --git a/src/jalview/ext/forester/UtilityMethods.java b/src/jalview/ext/forester/UtilityMethods.java new file mode 100644 index 0000000..d242e11 --- /dev/null +++ b/src/jalview/ext/forester/UtilityMethods.java @@ -0,0 +1,25 @@ +package jalview.ext.forester; + +import jalview.gui.Desktop; +import jalview.gui.JvOptionPane; +import jalview.util.MessageManager; + +import java.io.File; + +import org.forester.util.ForesterUtil; + +public class UtilityMethods +{ + public static boolean canForesterReadFile(File treeFile) + { + final String err = ForesterUtil.isReadableFile(treeFile); + if (!ForesterUtil.isEmpty(err)) + { + JvOptionPane.showInternalMessageDialog(Desktop.desktop, err, + MessageManager.getString("label.problem_reading_tree_file"), + JvOptionPane.WARNING_MESSAGE); + return false; + } + return true; + } +} diff --git a/src/jalview/ext/forester/io/TreeParser.java b/src/jalview/ext/forester/io/TreeParser.java index e11591d..cbdc3e8 100644 --- a/src/jalview/ext/forester/io/TreeParser.java +++ b/src/jalview/ext/forester/io/TreeParser.java @@ -5,7 +5,6 @@ import jalview.gui.AlignViewport; //import jalview.ext.treeviewer.ExternalTreeParserI; import jalview.gui.Desktop; import jalview.gui.JvOptionPane; -import jalview.io.DataSourceType; import jalview.io.NewickFile; import jalview.util.MessageManager; @@ -40,9 +39,9 @@ public class TreeParser // implements ExternalTreeParserI { AptxInit.createInstancesFromFile(filePath, viewport); - fin = new NewickFile(filePath, DataSourceType.FILE); - viewport.setCurrentTree(viewport.getAlignPanel().alignFrame - .showNewickTree(fin, filePath).getTree()); + // fin = new NewickFile(filePath, DataSourceType.FILE); + // viewport.setCurrentTree(viewport.getAlignPanel().alignFrame + // .showNewickTree(fin, filePath).getTree()); } catch (Exception ex) { @@ -51,14 +50,14 @@ public class TreeParser // implements ExternalTreeParserI JvOptionPane.WARNING_MESSAGE); ex.printStackTrace(); } - if (fin != null && fin.hasWarningMessage()) - { - JvOptionPane.showMessageDialog(Desktop.desktop, - fin.getWarningMessage(), - MessageManager - .getString("label.possible_problem_with_tree_file"), - JvOptionPane.WARNING_MESSAGE); - } + // if (fin != null && fin.hasWarningMessage()) + // { + // JvOptionPane.showMessageDialog(Desktop.desktop, + // fin.getWarningMessage(), + // MessageManager + // .getString("label.possible_problem_with_tree_file"), + // JvOptionPane.WARNING_MESSAGE); + // } } } diff --git a/src/jalview/ext/treeviewer/ExternalTreeFrame.java b/src/jalview/ext/treeviewer/ExternalTreeFrame.java index 32c8e51..48b150e 100644 --- a/src/jalview/ext/treeviewer/ExternalTreeFrame.java +++ b/src/jalview/ext/treeviewer/ExternalTreeFrame.java @@ -1,19 +1,45 @@ package jalview.ext.treeviewer; -import javax.swing.JInternalFrame; - -public abstract class ExternalTreeFrame extends JInternalFrame +import java.awt.Container; +import java.awt.Dimension; +import java.awt.MenuContainer; +import java.awt.image.ImageObserver; + +import javax.accessibility.Accessible; +import javax.swing.RootPaneContainer; +import javax.swing.WindowConstants; +import javax.swing.event.InternalFrameListener; + +public interface ExternalTreeFrame + extends Accessible, WindowConstants, RootPaneContainer, + ImageObserver, MenuContainer { public abstract ExternalTreePanel getTreePanel(); - public abstract void switchTreePanel(int panelIndex); - public abstract ExternalTreeI getTree(); public abstract void checkMultipleTrees(); public abstract int getNumberOfTrees(); - public abstract ExternalTreeControlsI getTreeControls(); + public ExternalTreeControlsI getTreeControls(); + + public void addFrameListener(InternalFrameListener listener); + + public void removeFrameListener(InternalFrameListener listener); + + public InternalFrameListener[] getFrameListeners(); + + public void repaint(); + + public void setMinimumSize(Dimension dimension); + + public boolean isShowing(); + + public Container getTopLevelAncestor(); + + public void addFrameToJalview(String title, boolean makeVisible, + int width, int height, boolean resizable, boolean ignoreMinSize); + } diff --git a/src/jalview/ext/treeviewer/ExternalTreeI.java b/src/jalview/ext/treeviewer/ExternalTreeI.java index 68e5ff8..3f28043 100644 --- a/src/jalview/ext/treeviewer/ExternalTreeI.java +++ b/src/jalview/ext/treeviewer/ExternalTreeI.java @@ -34,4 +34,5 @@ public interface ExternalTreeI public ExternalTreeFrame createInstanceFromTree(String instanceTitle); + } diff --git a/src/jalview/ext/treeviewer/ExternalTreeIteratorI.java b/src/jalview/ext/treeviewer/ExternalTreeIteratorI.java deleted file mode 100644 index e5a39f6..0000000 --- a/src/jalview/ext/treeviewer/ExternalTreeIteratorI.java +++ /dev/null @@ -1,6 +0,0 @@ -package jalview.ext.treeviewer; - -public interface ExternalTreeIteratorI -{ - -} diff --git a/src/jalview/ext/treeviewer/ExternalTreePanel.java b/src/jalview/ext/treeviewer/ExternalTreePanel.java index 705117d..ceb0e10 100644 --- a/src/jalview/ext/treeviewer/ExternalTreePanel.java +++ b/src/jalview/ext/treeviewer/ExternalTreePanel.java @@ -1,11 +1,13 @@ package jalview.ext.treeviewer; +import java.awt.MenuContainer; +import java.awt.event.MouseListener; import java.io.File; import java.util.Set; -import javax.swing.JPanel; +import javax.accessibility.Accessible; -public abstract class ExternalTreePanel extends JPanel +public interface ExternalTreePanel extends Accessible, MenuContainer { public abstract void setTreeFile(File file); @@ -19,4 +21,21 @@ public abstract class ExternalTreePanel extends JPanel public abstract void setMatchingNodes(Set matchingNodes); public abstract Set getMatchingNodes(); + + public void addMouseListener(MouseListener listener); + + public void removeMouseListener(MouseListener listener); + + public MouseListener[] getMouseListeners(); + + public void repaint(); + + public void registerWithPaintRefresher(String sequenceSetIdentifier); + + public void notifyPaintRefresher(boolean alignmentChanged, + boolean validateSequences); + + public void notifyPaintRefresher(String newSeqSetIdentifier, + boolean alignmentChanged, boolean validateSequences); + } diff --git a/src/jalview/ext/treeviewer/ExternalTreeParserI.java b/src/jalview/ext/treeviewer/ExternalTreeParserI.java index 47960f9..65ff63c 100644 --- a/src/jalview/ext/treeviewer/ExternalTreeParserI.java +++ b/src/jalview/ext/treeviewer/ExternalTreeParserI.java @@ -1,18 +1,13 @@ -// package jalview.ext.treeviewer; -// -// import jalview.viewmodel.AlignmentViewport; -// -/// ** -// * -// * Interface for loading in existing trees to an external tree viewer. -// * -// * @author kjvanderheide -// * -// */ -// public interface ExternalTreeParserI -// { -// public ExternalTreeI loadTreeFile(AlignmentViewport viewport); -// -// public ExternalTreeI loadTreeUrl(AlignmentViewport viewport); -// -// } +package jalview.ext.treeviewer; + +import java.io.IOException; + +public interface ExternalTreeParserI + { + public ExternalTreeI[] parse() throws IOException; + + public void setSource(Object source) throws IOException; + + public String getName(); + + } diff --git a/src/jalview/ext/archaeopteryx/LoadedTreeSequenceAssociation.java b/src/jalview/ext/treeviewer/LoadedTreeSequenceAssociation.java similarity index 89% rename from src/jalview/ext/archaeopteryx/LoadedTreeSequenceAssociation.java rename to src/jalview/ext/treeviewer/LoadedTreeSequenceAssociation.java index f05ba45..05d13e9 100644 --- a/src/jalview/ext/archaeopteryx/LoadedTreeSequenceAssociation.java +++ b/src/jalview/ext/treeviewer/LoadedTreeSequenceAssociation.java @@ -1,17 +1,13 @@ -package jalview.ext.archaeopteryx; +package jalview.ext.treeviewer; import jalview.analysis.SequenceIdMatcher; import jalview.datamodel.SequenceI; -import jalview.ext.treeviewer.ExternalLoadedTreeAssociationI; -import jalview.ext.treeviewer.ExternalTreeI; -import jalview.ext.treeviewer.ExternalTreeNodeI; import jalview.util.MappingUtils; import java.util.HashMap; import java.util.Iterator; import java.util.Map; - public class LoadedTreeSequenceAssociation implements ExternalLoadedTreeAssociationI { @@ -24,17 +20,15 @@ public class LoadedTreeSequenceAssociation Map nodesWithAlignment; public LoadedTreeSequenceAssociation(SequenceI[] alignmentSequences, - ExternalTreeI aptxTree) + ExternalTreeI extTree) { alignSequences = alignmentSequences; - tree = aptxTree; + tree = extTree; alignmentWithNodes = new HashMap<>(alignSequences.length); nodesWithAlignment = new HashMap<>(alignSequences.length); } - - /** * Tries to match sequences from Jalview with tree nodes in Archaeopteryx and * fills in the tree node with sequence data if a match is found. @@ -83,11 +77,13 @@ public class LoadedTreeSequenceAssociation + @Override public Map getAlignmentWithNodes() { return alignmentWithNodes; } + @Override public Map getNodesWithAlignment() { return nodesWithAlignment; diff --git a/test/jalview/ext/archaeopteryx/AptxPhylogenyTreeTest.java b/test/jalview/ext/archaeopteryx/AptxPhylogenyTreeTest.java index 8975d83..4163e3d 100644 --- a/test/jalview/ext/archaeopteryx/AptxPhylogenyTreeTest.java +++ b/test/jalview/ext/archaeopteryx/AptxPhylogenyTreeTest.java @@ -1,154 +1,154 @@ -package jalview.ext.archaeopteryx; - -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertTrue; - -import jalview.gui.Desktop; - -import org.forester.archaeopteryx.Archaeopteryx; -import org.forester.archaeopteryx.MainFrame; -import org.forester.archaeopteryx.TreePanel; -import org.forester.phylogeny.Phylogeny; -import org.forester.phylogeny.PhylogenyNode; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - -public class AptxPhylogenyTreeTest extends TreeViewTest -{ - final Phylogeny inputTree = new Phylogeny(); - - final PhylogenyNode rootNode = new PhylogenyNode("root"); - - final PhylogenyNode ancestor1Node = new PhylogenyNode("ancestor 1"); - - final PhylogenyNode ancestor2Node = new PhylogenyNode("leaf 2"); - - final PhylogenyNode leaf1aNode = new PhylogenyNode("leaf 1a"); - - final PhylogenyNode leaf1bNode = new PhylogenyNode("leaf 1b"); - - final PhylogenyNode leaf1cNode = new PhylogenyNode("leaf 1c"); - - Phylogeny tree; - - TreePanel treePanel; - - MainFrame aptx; - - - @Override - @BeforeClass(alwaysRun = true) - public void setUpTree() - { - ancestor1Node.addAsChild(leaf1aNode); - ancestor1Node.addAsChild(leaf1bNode); - ancestor1Node.addAsChild(leaf1cNode); - - rootNode.addAsChild(ancestor1Node); - rootNode.addAsChild(ancestor2Node); - - leaf1aNode.setDistanceToParent(2); - leaf1bNode.setDistanceToParent(3); - leaf1cNode.setDistanceToParent(4); - - ancestor1Node.setDistanceToParent(36); - ancestor2Node.setDistanceToParent(42); - - inputTree.setName("test"); - inputTree.setRoot(rootNode); - inputTree.setRooted(true); - - } - - @Override - @BeforeClass(dependsOnMethods = { "setUpJalview", "setUpTree" }) - public void createTreeView() - { - treeView = Archaeopteryx.createApplication(inputTree); - aptx = (MainFrame) treeView; // pretty ugly - treePanel = aptx.getMainPanel().getCurrentTreePanel(); - tree = treePanel.getPhylogeny(); - - Desktop.addInternalFrame(aptx, "Archaeopteryx", 500, 500); - - } - - - - @Test(groups = "Functional") - public void testMainPanelExists() - { - assertTrue(aptx.getMainPanel() != null); - } - - @Test(groups = "Functional") - public void testTreePanelExists() - { - assertTrue(treePanel != null); - } - - @Override - public void testTreeTitle() - { - assertTrue(tree.getName().equals("test")); - - } - - @Test( - groups = "Functional", - expectedExceptions = IllegalArgumentException.class) - public void testInvalidBranchName() - { - tree.getNode("I shouldn't exist"); - - } - - @Override - public void testExistingBranchName() - { - tree.getNode("leaf 2"); - - } - - @Override - public void testTreeLoaded() - { - assertTrue(tree != null); - } - - @Override - public void testChildNodesCount() - { - assertEquals(tree.getNode("ancestor 1").getNumberOfExternalNodes(), 3); - - } - - @Override - public void testChildToParentBranchLength() - { - assertEquals(tree.getNode("leaf 1a").getDistanceToParent(), 2.0); - - } - - @Override - public void testNodeToRootBranchLength() - { - assertEquals(tree.getNode("leaf 2").getDistanceToParent(), 42.0); - - } - - @Override - public void testDistantNodeToRootBranchLength() - { - assertEquals(tree.getNode("leaf 1c").calculateDistanceToRoot(), - 4.0 + 36.0); - - } - - - - - - - -} +// package jalview.ext.archaeopteryx; +// +// import static org.testng.Assert.assertEquals; +// import static org.testng.Assert.assertTrue; +// +// import jalview.gui.Desktop; +// +// import org.forester.archaeopteryx.Archaeopteryx; +// import org.forester.archaeopteryx.MainFrame; +// import org.forester.archaeopteryx.TreePanel; +// import org.forester.phylogeny.Phylogeny; +// import org.forester.phylogeny.PhylogenyNode; +// import org.testng.annotations.BeforeClass; +// import org.testng.annotations.Test; +// +// public class AptxPhylogenyTreeTest extends TreeViewTest +// { +// final Phylogeny inputTree = new Phylogeny(); +// +// final PhylogenyNode rootNode = new PhylogenyNode("root"); +// +// final PhylogenyNode ancestor1Node = new PhylogenyNode("ancestor 1"); +// +// final PhylogenyNode ancestor2Node = new PhylogenyNode("leaf 2"); +// +// final PhylogenyNode leaf1aNode = new PhylogenyNode("leaf 1a"); +// +// final PhylogenyNode leaf1bNode = new PhylogenyNode("leaf 1b"); +// +// final PhylogenyNode leaf1cNode = new PhylogenyNode("leaf 1c"); +// +// Phylogeny tree; +// +// TreePanel treePanel; +// +// MainFrame aptx; +// +// +// @Override +// @BeforeClass(alwaysRun = true) +// public void setUpTree() +// { +// ancestor1Node.addAsChild(leaf1aNode); +// ancestor1Node.addAsChild(leaf1bNode); +// ancestor1Node.addAsChild(leaf1cNode); +// +// rootNode.addAsChild(ancestor1Node); +// rootNode.addAsChild(ancestor2Node); +// +// leaf1aNode.setDistanceToParent(2); +// leaf1bNode.setDistanceToParent(3); +// leaf1cNode.setDistanceToParent(4); +// +// ancestor1Node.setDistanceToParent(36); +// ancestor2Node.setDistanceToParent(42); +// +// inputTree.setName("test"); +// inputTree.setRoot(rootNode); +// inputTree.setRooted(true); +// +// } +// +// @Override +// @BeforeClass(dependsOnMethods = { "setUpJalview", "setUpTree" }) +// public void createTreeView() +// { +// treeView = Archaeopteryx.createApplication(inputTree); +// aptx = (MainFrame) treeView; // pretty ugly +// treePanel = aptx.getMainPanel().getCurrentTreePanel(); +// tree = treePanel.getPhylogeny(); +// +// Desktop.addInternalFrame(aptx, "Archaeopteryx", 500, 500); +// +// } +// +// +// +// @Test(groups = "Functional") +// public void testMainPanelExists() +// { +// assertTrue(aptx.getMainPanel() != null); +// } +// +// @Test(groups = "Functional") +// public void testTreePanelExists() +// { +// assertTrue(treePanel != null); +// } +// +// @Override +// public void testTreeTitle() +// { +// assertTrue(tree.getName().equals("test")); +// +// } +// +// @Test( +// groups = "Functional", +// expectedExceptions = IllegalArgumentException.class) +// public void testInvalidBranchName() +// { +// tree.getNode("I shouldn't exist"); +// +// } +// +// @Override +// public void testExistingBranchName() +// { +// tree.getNode("leaf 2"); +// +// } +// +// @Override +// public void testTreeLoaded() +// { +// assertTrue(tree != null); +// } +// +// @Override +// public void testChildNodesCount() +// { +// assertEquals(tree.getNode("ancestor 1").getNumberOfExternalNodes(), 3); +// +// } +// +// @Override +// public void testChildToParentBranchLength() +// { +// assertEquals(tree.getNode("leaf 1a").getDistanceToParent(), 2.0); +// +// } +// +// @Override +// public void testNodeToRootBranchLength() +// { +// assertEquals(tree.getNode("leaf 2").getDistanceToParent(), 42.0); +// +// } +// +// @Override +// public void testDistantNodeToRootBranchLength() +// { +// assertEquals(tree.getNode("leaf 1c").calculateDistanceToRoot(), +// 4.0 + 36.0); +// +// } +// +// +// +// +// +// +// +// } diff --git a/test/jalview/ext/archaeopteryx/TreeViewTest.java b/test/jalview/ext/archaeopteryx/TreeViewTest.java index 4bbe140..f0595f2 100644 --- a/test/jalview/ext/archaeopteryx/TreeViewTest.java +++ b/test/jalview/ext/archaeopteryx/TreeViewTest.java @@ -3,11 +3,10 @@ package jalview.ext.archaeopteryx; import static org.testng.Assert.assertTrue; import jalview.bin.Jalview; +import jalview.ext.treeviewer.ExternalTreeFrame; import jalview.gui.Desktop; import jalview.gui.JvOptionPane; -import javax.swing.JInternalFrame; - import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -15,7 +14,7 @@ public abstract class TreeViewTest { Jalview jalview; - JInternalFrame treeView; + ExternalTreeFrame treeView; @BeforeClass(alwaysRun = true) public void setUpJvOptionPane() -- 1.7.10.2