X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fext%2Farchaeopteryx%2FJalviewBinding.java;h=54b92252e18e33fa1676046d827afe37ef804c9d;hb=f7c1fd8a0f220e1e896414b1aa905bd30138c26a;hp=2bacfd503d6361bed9aea015816d48cfd783fe1f;hpb=0002d6c015a12da3ba7ce22934e6a311a3f90682;p=jalview.git diff --git a/src/jalview/ext/archaeopteryx/JalviewBinding.java b/src/jalview/ext/archaeopteryx/JalviewBinding.java index 2bacfd5..54b9225 100644 --- a/src/jalview/ext/archaeopteryx/JalviewBinding.java +++ b/src/jalview/ext/archaeopteryx/JalviewBinding.java @@ -1,13 +1,23 @@ package jalview.ext.archaeopteryx; +import jalview.analysis.AlignmentSorter; import jalview.analysis.Conservation; import jalview.api.AlignViewportI; +import jalview.commands.CommandI; +import jalview.commands.OrderCommand; import jalview.datamodel.ColumnSelection; import jalview.datamodel.HiddenColumns; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; -import jalview.ext.treeviewer.ExternalTreeViewerBindingI; +import jalview.ext.treeviewer.TreeFrameI; +import jalview.ext.treeviewer.TreeI; +import jalview.ext.treeviewer.TreeNodeI; +import jalview.ext.treeviewer.TreePanelI; +import jalview.ext.treeviewer.TreeViewerBindingI; +import jalview.ext.treeviewer.TreeViewerUtils; +import jalview.ext.treeviewer.LoadedTreeSequenceAssociation; import jalview.gui.AlignViewport; +import jalview.gui.AlignmentPanel; import jalview.gui.Desktop; import jalview.gui.JvOptionPane; import jalview.gui.PaintRefresher; @@ -21,7 +31,7 @@ import jalview.util.MessageManager; import jalview.viewmodel.AlignmentViewport; import java.awt.Color; -import java.awt.Graphics; +import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.InputEvent; import java.awt.event.MouseEvent; @@ -31,17 +41,9 @@ import java.util.List; import java.util.Map; import java.util.Set; -import javax.swing.JTabbedPane; import javax.swing.SwingUtilities; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; - -import org.forester.archaeopteryx.MainFrame; -import org.forester.archaeopteryx.TreePanelUtil; -import org.forester.phylogeny.Phylogeny; -import org.forester.phylogeny.PhylogenyMethods; -import org.forester.phylogeny.PhylogenyNode; -import org.forester.phylogeny.data.BranchColor; +import javax.swing.event.InternalFrameAdapter; +import javax.swing.event.InternalFrameEvent; /** * Class for binding the Archaeopteryx tree viewer to the Jalview alignment that @@ -52,19 +54,29 @@ import org.forester.phylogeny.data.BranchColor; * */ public final class JalviewBinding - implements ExternalTreeViewerBindingI + implements TreeViewerBindingI { - private org.forester.archaeopteryx.TreePanel treeView; + private final TreeFrameI aptxFrame; - private AlignmentViewport parentAvport; + private TreePanelI treeView; - private final JTabbedPane treeTabs; + private AlignmentViewport parentAvport; private final StructureSelectionManager ssm; - private Map sequencesBoundToNodes; + private AlignmentPanel[] associatedPanels; + + private Map sequencesBoundToNodes; + + private Map nodesBoundToSequences; + + private float rootX; + + private float furthestNodeX; + + private int nrTreeGroups = 0; - private Map nodesBoundToSequences; + private boolean applyToAllViews = false; /** * @@ -81,71 +93,132 @@ public final class JalviewBinding * map with tree nodes and matching sequences used to calculate the * tree as key, value pair respectively. */ - public JalviewBinding(final MainFrame archaeopteryx, + public JalviewBinding(final TreeFrameI archaeopteryx, final AlignmentViewport jalviewAlignmentViewport, - final Map alignMappedToNodes, - final Map nodesMappedToAlign) + final Map alignMappedToNodes, + final Map nodesMappedToAlign) { - if (archaeopteryx.getMainPanel().getTabbedPane().getTabCount() > 1) + if (archaeopteryx.getNumberOfTrees() > 1) { JvOptionPane.showMessageDialog(Desktop.desktop, MessageManager.getString("label.tabs_detected_archaeopteryx"), MessageManager.getString("label.problem_reading_tree_file"), JvOptionPane.WARNING_MESSAGE); - ; + } // deal with/prohibit null values here as that will cause problems + aptxFrame = archaeopteryx; parentAvport = jalviewAlignmentViewport; sequencesBoundToNodes = alignMappedToNodes; nodesBoundToSequences = nodesMappedToAlign; - treeView = archaeopteryx.getMainPanel().getCurrentTreePanel(); - treeTabs = archaeopteryx.getMainPanel().getTabbedPane(); + treeView = archaeopteryx.getTreePanel(); ssm = parentAvport.getStructureSelectionManager(); ssm.addSelectionListener(this); treeView.addMouseListener(this); - PaintRefresher.Register(treeView, parentAvport.getSequenceSetId()); - + treeView.registerWithPaintRefresher( + parentAvport.getSequenceSetId()); + associatedPanels = PaintRefresher + .getAssociatedPanels(parentAvport.getSequenceSetId()); - treeTabs.addChangeListener(new ChangeListener() + aptxFrame.addFrameListener(new InternalFrameAdapter() { @Override - public void stateChanged(ChangeEvent e) + public void internalFrameClosed(InternalFrameEvent e) { - - SwingUtilities.invokeLater(new Runnable() - { - - @Override - /** - * Resend the selection to the tree view when tabs get switched, this - * has to be buried in invokeLater as Forester first resets the tree - * view on switching tabs, without invokeLater this would get called - * before Forester resets which would nullify the selection. - */ - public void run() - { - treeView = archaeopteryx.getMainPanel().getCurrentTreePanel(); - parentAvport.sendSelection(); - // PaintRefresher.Refresh(treeView, - // parentAvport.getSequenceSetId()); - - } - }); - + TreeViewerUtils.getActiveTreeViews().remove(aptxFrame); + ssm.removeSelectionListener(JalviewBinding.this); } }); + // treeTabs.addChangeListener(new ChangeListener() + // { + // + // @Override + // public void stateChanged(ChangeEvent e) + // { + // + // SwingUtilities.invokeLater(new Runnable() + // { + // + // @Override + // /** + // * Resend the selection to the tree view when tabs get switched, this + // * has to be buried in invokeLater as Forester first resets the tree + // * view on switching tabs, without invokeLater this would get called + // * before Forester resets which would nullify the selection. + // */ + // public void run() + // { + // treeView = archaeopteryx.getMainPanel().getCurrentTreePanel(); + // parentAvport.sendSelection(); + // // PaintRefresher.Refresh(treeView, + // // parentAvport.getSequenceSetId()); + // + // } + // }); + // + // } + // + // }); + } @Override public void actionPerformed(ActionEvent e) { + // reset hidden sequences first + parentAvport.showAllHiddenSeqs(); + + if (treeView.showingSubTree()) + { + LoadedTreeSequenceAssociation bindAptxNodes = new LoadedTreeSequenceAssociation( + parentAvport.getAlignment().getSequencesArray(), + treeView.getTree()); + bindAptxNodes.associateLeavesToSequences(); + sequencesBoundToNodes = bindAptxNodes.getAlignmentWithNodes(); + nodesBoundToSequences = bindAptxNodes.getNodesWithAlignment(); + TreeViewerUtils.associateNodesWithJalviewSequences(aptxFrame, parentAvport, + sequencesBoundToNodes, nodesBoundToSequences); + + + for (SequenceI seq : parentAvport.getAlignment().getSequencesArray()) + { + if (!sequencesBoundToNodes.containsKey(seq)) + { + parentAvport.hideSequence(new SequenceI[] { seq }); + } + } + } + + else + { + + Rectangle visibleView = treeView.getVisibleArea(); + + for (TreeNodeI node : treeView.getTree().getRoot() + .getAllDescendants()) + { + if (!(node.getXcoord() > visibleView.getMinX() + && node.getXcoord() < visibleView.getMaxX() + && node.getYcoord() > visibleView.getMinY() + && node.getYcoord() < visibleView.getMaxY())) + { + parentAvport + .hideSequence(new SequenceI[] + { nodesBoundToSequences.get(node) }); + } + } + + } + + + } @Override @@ -159,7 +232,8 @@ public final class JalviewBinding */ public void run() { - final PhylogenyNode node = treeView.findNode(e.getX(), e.getY()); + final TreeNodeI node = treeView.findNode(e.getX(), + e.getY()); if (node != null) { if ((e.getModifiers() & InputEvent.SHIFT_MASK) == 0) // clear previous @@ -176,7 +250,9 @@ public final class JalviewBinding partitionTree(e.getX()); } - PaintRefresher.Refresh(treeView, parentAvport.getSequenceSetId()); + treeView.notifyPaintRefresher(parentAvport.getSequenceSetId(), + false, false); + treeView.repaint(); @@ -215,20 +291,32 @@ public final class JalviewBinding if (source == parentAvport) // check if source is alignment from where the // tree originates { - treeView.setFoundNodes0( + treeView.setMatchingNodes( new HashSet(seqsel.getSequences().size())); + for (SequenceI selectedSequence : seqsel.getSequences()) { - PhylogenyNode matchingNode = sequencesBoundToNodes.get(selectedSequence); + TreeNodeI matchingNode = sequencesBoundToNodes + .get(selectedSequence); if (matchingNode != null) { - treeView.getFoundNodes0().add(matchingNode.getId()); + treeView.getMatchingNodes().add(matchingNode.getId()); + + + // if (!matchingNode.getBranchData().isHasBranchColor()) + // { + // // Color foundNodesColour = treeView.getTreeColorSet() + // // .getFoundColor0(); + // // matchingNode.getBranchData() + // // .setBranchColor(new BranchColor(foundNodesColour)); + // + // } + } } - treeView.repaint(); } @@ -240,24 +328,23 @@ public final class JalviewBinding */ public void partitionTree(final int x) { - Phylogeny tree = treeView.getPhylogeny(); + TreeI tree = treeView.getTree(); if (!tree.isEmpty()) { - double longestBranch = tree.calculateHeight(true); - if (longestBranch != 0) + // should be calculated on each partition as the tree can theoretically + // change in the meantime + TreeNodeI furthestNode = tree.getFurthestNode(); + furthestNodeX = furthestNode.getXcoord(); + rootX = tree.getRoot().getXcoord(); + + // don't bother if 0 distance tree or clicked x lies outside of tree + if (furthestNodeX != rootX && !(x > furthestNodeX)) { - - // double relativeTreeWidth = longestBranch / viewWidth; - // MOVE - Graphics g = treeView.getGraphics(); - int panelHeight = treeView.getHeight(); - g.drawLine(x, 0, x, panelHeight); - - float rootX = tree.getRoot().getXcoord(); - double threshold = ((double) x - rootX) / longestBranch; - List foundNodes = getNodesAboveThreshold(threshold, - longestBranch, tree.getRoot()); + float threshold = (x - rootX) / (furthestNodeX - rootX); + List foundNodes = getNodesAboveThreshold( + threshold, + tree.getRoot()); } } @@ -265,11 +352,11 @@ public final class JalviewBinding } - public List getNodesAboveThreshold(double threshold, - double treeLength, PhylogenyNode node) + public List getNodesAboveThreshold(double threshold, + TreeNodeI node) { - List nodesAboveThreshold = new ArrayList<>(); + List nodesAboveThreshold = new ArrayList<>(); parentAvport.setSelectionGroup(null); parentAvport.getAlignment().deleteAllGroups(); @@ -282,7 +369,7 @@ public final class JalviewBinding } - colourNodesAboveThreshold(nodesAboveThreshold, threshold, treeLength, + colourNodesAboveThreshold(nodesAboveThreshold, threshold, node); return nodesAboveThreshold; @@ -297,157 +384,156 @@ public final class JalviewBinding * @param node * @return */ - private List colourNodesAboveThreshold( - List nodeList, double threshold, - double treeLength, PhylogenyNode node) + private List colourNodesAboveThreshold( + List nodeList, double threshold, + TreeNodeI node) { - // could also use PhylogenyMethods.getAllDescendants - for (PhylogenyNode childNode : node.getDescendants()) + + for (TreeNodeI childNode : node.getDirectChildren()) { - childNode.getBranchData() - .setBranchColor(new BranchColor(Color.black)); - double nodeCutoff = childNode.calculateDistanceToRoot() / treeLength; + childNode.setBranchColor(Color.black); + float nodeCutoff = (childNode.getXcoord() - rootX) + / (furthestNodeX - rootX); if (nodeCutoff > threshold) { nodeList.add(childNode); - Color randomColor = new Color((int) (Math.random() * 255), + Color randomColour = new Color((int) (Math.random() * 255), (int) (Math.random() * 255), (int) (Math.random() * 255)); - TreePanelUtil.colorizeSubtree(childNode, - new BranchColor(randomColor)); + childNode.setBranchColor(randomColour); - List descendantNodes = childNode - .getAllExternalDescendants(); - List descendantSeqs = new ArrayList<>(); - for (PhylogenyNode descNode : descendantNodes) + List groupSeqs = new ArrayList<>(); + SequenceI seq = nodesBoundToSequences.get(childNode); + if (seq != null) { - descendantSeqs.add(nodesBoundToSequences.get(descNode)); + groupSeqs.add(seq); + parentAvport.setSequenceColour(seq, randomColour); } - - SequenceGroup sg = new SequenceGroup(descendantSeqs, null, null, - true, true, false, 0, - parentAvport.getAlignment().getWidth() - 1); - - ColourSchemeI cs = null; - if (parentAvport.getGlobalColourScheme() != null) + List descendantNodes = childNode + .getAllDescendants(); + // .forEach instead? + for (TreeNodeI descNode : descendantNodes) { - if (parentAvport.getGlobalColourScheme() instanceof UserColourScheme) - { - cs = new UserColourScheme( - ((UserColourScheme) parentAvport.getGlobalColourScheme()) - .getColours()); - - } - else + seq = nodesBoundToSequences.get(descNode); + if (seq != null) { - cs = ColourSchemeProperty.getColourScheme(sg, ColourSchemeProperty - .getColourName(parentAvport.getGlobalColourScheme())); + groupSeqs.add(seq); + parentAvport.setSequenceColour(seq, randomColour); } + + descNode.setBranchColor(randomColour); } - sg.setColourScheme(cs); - sg.getGroupColourScheme().setThreshold( - parentAvport.getResidueShading().getThreshold(), - parentAvport.isIgnoreGapsConsensus()); - // sg.recalcConservation(); - sg.setName("Tree Group:" + sg.hashCode()); - sg.setIdColour(randomColor); - - if (parentAvport.getGlobalColourScheme() != null - && parentAvport.getResidueShading().conservationApplied()) + + if (groupSeqs != null) { - Conservation c = new Conservation("Group", sg.getSequences(null), - sg.getStartRes(), sg.getEndRes()); - c.calculate(); - c.verdict(false, parentAvport.getConsPercGaps()); - sg.cs.setConservation(c); - } + nrTreeGroups++; + groupThresholdSequences(groupSeqs, randomColour); + }} + + else + { + colourNodesAboveThreshold(nodeList, threshold, childNode); + } + } + - parentAvport.getAlignment().addGroup(new SequenceGroup(sg)); - // TODO can we push all of the below into AlignViewportI? - final AlignViewportI codingComplement = parentAvport + for (AlignmentPanel associatedPanel : associatedPanels) { + + associatedPanel.updateAnnotation(); + + final AlignViewportI codingComplement = associatedPanel.getAlignViewport() .getCodingComplement(); if (codingComplement != null) { - SequenceGroup mappedGroup = MappingUtils.mapSequenceGroup(sg, - parentAvport, - codingComplement); - if (mappedGroup.getSequences().size() > 0) - { - codingComplement.getAlignment().addGroup(mappedGroup); - for (SequenceI seq : mappedGroup.getSequences()) - { - codingComplement.setSequenceColour(seq, - randomColor.brighter()); - } - } + // GROSS + ((AlignViewport) codingComplement).getAlignPanel() + .updateAnnotation(); } + } + + return nodeList; + } + public void groupThresholdSequences(List groupedSeqs, + Color groupColour) + { + SequenceGroup treeGroup = new SequenceGroup(groupedSeqs, null, null, + true, true, false, 0, + parentAvport.getAlignment().getWidth() - 1); + + ColourSchemeI cs = null; + if (parentAvport.getGlobalColourScheme() != null) + { + if (parentAvport.getGlobalColourScheme() instanceof UserColourScheme) + { + cs = new UserColourScheme( + ((UserColourScheme) parentAvport.getGlobalColourScheme()) + .getColours()); } else { - colourNodesAboveThreshold(nodeList, threshold, treeLength, - childNode); + cs = ColourSchemeProperty.getColourScheme(treeGroup, + ColourSchemeProperty.getColourName( + parentAvport.getGlobalColourScheme())); } } - // GROSS - ((AlignViewport) parentAvport).getAlignPanel().updateAnnotation(); - - final AlignViewportI codingComplement = parentAvport - .getCodingComplement(); - if (codingComplement != null) - { - ((AlignViewport) codingComplement).getAlignPanel().updateAnnotation(); - } + treeGroup.setColourScheme(cs); + treeGroup.getGroupColourScheme().setThreshold( + parentAvport.getResidueShading().getThreshold(), + parentAvport.isIgnoreGapsConsensus()); + treeGroup.setName("Tree Group " + nrTreeGroups); + treeGroup.setIdColour(groupColour); - return nodeList; - } - + for (AlignmentPanel associatedPanel : associatedPanels) + { + AlignViewportI altViewport = associatedPanel + .getAlignViewport(); + if (altViewport.getGlobalColourScheme() != null + && altViewport.getResidueShading() + .conservationApplied()) + { + Conservation conserv = new Conservation(treeGroup.getName(), + treeGroup.getSequences(null), treeGroup.getStartRes(), + treeGroup.getEndRes()); + conserv.calculate(); + conserv.verdict(false, altViewport.getConsPercGaps()); + treeGroup.getGroupColourScheme().setConservation(conserv); + } + altViewport.getAlignment().addGroup(treeGroup); + // TODO can we push all of the below into AlignViewportI? + final AlignViewportI codingComplement = altViewport + .getCodingComplement(); + if (codingComplement != null) + { + SequenceGroup mappedGroup = MappingUtils.mapSequenceGroup(treeGroup, + parentAvport, codingComplement); + if (mappedGroup.getSequences().size() > 0) + { + codingComplement.getAlignment().addGroup(mappedGroup); + for (SequenceI seq : mappedGroup.getSequences()) + { + codingComplement.setSequenceColour(seq, groupColour.brighter()); + } + } + } - // public List groupNodes(float threshold, PhylogenyNode root, - // double treeHeight) - // { - // List groups = new ArrayList<>(); - // _groupNodes(groups, root, threshold, treeHeight); - // System.out.println(groups); - // return groups; - // } - // - // protected void _groupNodes(List groups, PhylogenyNode nd, - // float threshold, double treeHeight) - // { - // if (nd == null) - // { - // return; - // } - // - // if ((nd.calculateDistanceToRoot() / treeHeight) > threshold) - // { - // groups.add(nd); - // } - // else - // { - // for (PhylogenyNode childNode : nd.getDescendants()) - // { - // _groupNodes(groups, childNode, threshold, treeHeight); - // } - // } - // } - // + } + } /** * may or may not need an extra repaint on the alignment view (check what kira * does) */ @Override - public void showNodeSelectionOnAlign(final PhylogenyNode node) + public void showNodeSelectionOnAlign(final TreeNodeI node) { if (node.isInternal()) @@ -468,13 +554,13 @@ public final class JalviewBinding @Override - public void showMatchingSequence(final PhylogenyNode nodeToMatch) + public void showMatchingSequence(final TreeNodeI nodeToMatch) { SequenceI matchingSequence = nodesBoundToSequences.get(nodeToMatch); if (matchingSequence != null) { long nodeId = nodeToMatch.getId(); - addOrRemoveInSet(treeView.getFoundNodes0(), nodeId); + addOrRemoveInSet(treeView.getMatchingNodes(), nodeId); treeSelectionChanged(matchingSequence); parentAvport.sendSelection(); @@ -482,13 +568,14 @@ public final class JalviewBinding } @Override - public void showMatchingChildSequences(final PhylogenyNode parentNode) + public void showMatchingChildSequences(final TreeNodeI parentNode) { - List childNodes = PhylogenyMethods - .getAllDescendants(parentNode); + // redundancy here, Forester already iterates through tree to get all + // descendants + List childNodes = parentNode.getAllDescendants(); - for (PhylogenyNode childNode : childNodes) + for (TreeNodeI childNode : childNodes) { // childNode.getBranchData().setBranchColor(new BranchColor(Color.BLUE)); @@ -496,7 +583,7 @@ public final class JalviewBinding if (matchingSequence != null) { long nodeId = childNode.getId(); - addOrRemoveInSet(treeView.getFoundNodes0(), nodeId); + addOrRemoveInSet(treeView.getMatchingNodes(), nodeId); treeSelectionChanged(matchingSequence); @@ -532,79 +619,95 @@ public final class JalviewBinding } } - public void sortByTree_actionPerformed() { - // parentAvport.mirrorCommand(command, undo, ssm, source); - // alignFrame + @Override + public void sortByTree_actionPerformed()// modify for Aptx + { + + // if (treeCanvas.applyToAllViews) + // { + // final ArrayList commands = new ArrayList<>(); + // for (AlignmentPanel ap : PaintRefresher + // .getAssociatedPanels(parentAvport.getSequenceSetId())) + // { + // commands.add(sortAlignmentIn(ap.av.getAlignPanel())); + // } + // parentAvport.getAlignPanel().alignFrame.addHistoryItem(new CommandI() + // { + // + // @Override + // public void undoCommand(AlignmentI[] views) + // { + // for (CommandI tsort : commands) + // { + // tsort.undoCommand(views); + // } + // } + // + // @Override + // public int getSize() + // { + // return commands.size(); + // } + // + // @Override + // public String getDescription() + // { + // return "Tree Sort (many views)"; + // } + // + // @Override + // public void doCommand(AlignmentI[] views) + // { + // + // for (CommandI tsort : commands) + // { + // tsort.doCommand(views); + // } + // } + // }); + // for (AlignmentPanel ap : PaintRefresher + // .getAssociatedPanels(av.getSequenceSetId())) + // { + // // ensure all the alignFrames refresh their GI after adding an undo item + // ap.alignFrame.updateEditMenuBar(); + // } + // } + // else + // { + // treeCanvas.ap.alignFrame // .addHistoryItem(sortAlignmentIn(treeCanvas.ap)); - + // } + } - - /** - * sort the associated alignment view by the current tree. - * - * @param e - */ - // @Override - // public void sortByTree_actionPerformed()// modify for Aptx - // { - // - // // if (treeCanvas.applyToAllViews) - // - // final ArrayList commands = new ArrayList<>(); - // for (AlignmentPanel ap : PaintRefresher - // .getAssociatedPanels(parentAvport.getSequenceSetId())) - // { - // commands.add(sortAlignmentIn(ap.parentAvport.getAlignPanel())); - // } - // parentAvport.getAlignPanel().alignFrame.addHistoryItem(new CommandI() - // { - // - // @Override - // public void undoCommand(AlignmentI[] views) - // { - // for (CommandI tsort : commands) - // { - // tsort.undoCommand(views); - // } - // } - // - // @Override - // public int getSize() - // { - // return commands.size(); - // } - // - // @Override - // public String getDescription() - // { - // return "Tree Sort (many views)"; - // } - // - // @Override - // public void doCommand(AlignmentI[] views) - // { - // - // for (CommandI tsort : commands) - // { - // tsort.doCommand(views); - // } - // } - // }); - // for (AlignmentPanel ap : PaintRefresher - // .getAssociatedPanels(parentAvport.getSequenceSetId())) - // { - // // ensure all the alignFrames refresh their GI after adding an undo item - // ap.alignFrame.updateEditMenuBar(); - // } - // } - // else - // { - // treeCanvas.ap.alignFrame - // .addHistoryItem(sortAlignmentIn(treeCanvas.ap)); - // } + @Override + public CommandI sortAlignmentIn(AlignmentPanel ap) + { + // TODO: move to alignment view controller + AlignmentViewport viewport = ap.av; + SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray(); + try + { + AlignmentSorter.sortByTree(viewport.getAlignment(), + nodesBoundToSequences, + treeView.getTree()); + CommandI undo; + undo = new OrderCommand("Tree Sort", oldOrder, + viewport.getAlignment()); + + ap.paintAlignment(true, false); + return undo; + + } catch (Exception e) + { + System.err.println(e.getMessage()); + } + return null; + + } + /** @@ -635,6 +738,17 @@ public final class JalviewBinding { this.parentAvport = parentAvport; } + + public AlignmentPanel[] getAssociatedPanels() + { + return associatedPanels; + } + + public void setAssociatedPanels(AlignmentPanel[] associatedPanels) + { + this.associatedPanels = associatedPanels; + } + }