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.viewmodel.AlignmentViewport;
import java.awt.Color;
+import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
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 javax.swing.event.InternalFrameAdapter;
import javax.swing.event.InternalFrameEvent;
-import org.forester.archaeopteryx.MainFrame;
-import org.forester.phylogeny.Phylogeny;
-import org.forester.phylogeny.PhylogenyMethods;
-import org.forester.phylogeny.PhylogenyNode;
-import org.forester.phylogeny.data.BranchColor;
-
/**
* Class for binding the Archaeopteryx tree viewer to the Jalview alignment that
* it originates from, meaning that selecting sequences in the tree viewer also
*
*/
public final class JalviewBinding
- implements ExternalTreeViewerBindingI<PhylogenyNode>
+ 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 AlignmentPanel[] associatedPanels;
- private Map<SequenceI, PhylogenyNode> sequencesBoundToNodes;
+ private Map<SequenceI, TreeNodeI> sequencesBoundToNodes;
- private Map<PhylogenyNode, SequenceI> nodesBoundToSequences;
+ private Map<TreeNodeI, SequenceI> nodesBoundToSequences;
private float rootX;
* 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<SequenceI, PhylogenyNode> alignMappedToNodes,
- final Map<PhylogenyNode, SequenceI> nodesMappedToAlign)
+ final Map<SequenceI, TreeNodeI> alignMappedToNodes,
+ final Map<TreeNodeI, SequenceI> 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());
- archaeopteryx.addInternalFrameListener(new InternalFrameAdapter()
+ aptxFrame.addFrameListener(new InternalFrameAdapter()
{
@Override
public void internalFrameClosed(InternalFrameEvent e)
{
- AptxInit.getAllAptxFrames().remove(archaeopteryx);
+ TreeViewerUtils.getActiveTreeViews().remove(aptxFrame);
+ ssm.removeSelectionListener(JalviewBinding.this);
}
});
- treeTabs.addChangeListener(new ChangeListener()
+ // 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);
- @Override
- public void stateChanged(ChangeEvent e)
- {
- SwingUtilities.invokeLater(new Runnable()
- {
+ for (SequenceI seq : parentAvport.getAlignment().getSequencesArray())
+ {
+ if (!sequencesBoundToNodes.containsKey(seq))
+ {
+ parentAvport.hideSequence(new SequenceI[] { seq });
+ }
+ }
+ }
- @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());
+ 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
- public void actionPerformed(ActionEvent e)
- {
}
@Override
*/
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
partitionTree(e.getX());
}
- PaintRefresher.Refresh(treeView, parentAvport.getSequenceSetId());
+ treeView.notifyPaintRefresher(parentAvport.getSequenceSetId(),
+ false, false);
treeView.repaint();
if (source == parentAvport) // check if source is alignment from where the
// tree originates
{
- treeView.setFoundNodes0(
+ treeView.setMatchingNodes(
new HashSet<Long>(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));
-
- }
+ // if (!matchingNode.getBranchData().isHasBranchColor())
+ // {
+ // // Color foundNodesColour = treeView.getTreeColorSet()
+ // // .getFoundColor0();
+ // // matchingNode.getBranchData()
+ // // .setBranchColor(new BranchColor(foundNodesColour));
+ //
+ // }
}
*/
public void partitionTree(final int x)
{
- Phylogeny tree = treeView.getPhylogeny();
+ TreeI tree = treeView.getTree();
if (!tree.isEmpty())
{
// should be calculated on each partition as the tree can theoretically
// change in the meantime
- PhylogenyNode furthestNode = PhylogenyMethods
- .calculateNodeWithMaxDistanceToRoot(tree);
+ TreeNodeI furthestNode = tree.getFurthestNode();
furthestNodeX = furthestNode.getXcoord();
rootX = tree.getRoot().getXcoord();
- if (furthestNodeX != rootX && !(x < rootX || x > furthestNodeX)) // don't
- // bother
- // if 0
- // distance tree or
- // clicked x lies outside
- // of tree
+ // don't bother if 0 distance tree or clicked x lies outside of tree
+ if (furthestNodeX != rootX && !(x > furthestNodeX))
{
-
float threshold = (x - rootX) / (furthestNodeX - rootX);
- List<PhylogenyNode> foundNodes = getNodesAboveThreshold(threshold,
+ List<TreeNodeI> foundNodes = getNodesAboveThreshold(
+ threshold,
tree.getRoot());
}
}
- public List<PhylogenyNode> getNodesAboveThreshold(double threshold,
- PhylogenyNode node)
+ public List<TreeNodeI> getNodesAboveThreshold(double threshold,
+ TreeNodeI node)
{
- List<PhylogenyNode> nodesAboveThreshold = new ArrayList<>();
+ List<TreeNodeI> nodesAboveThreshold = new ArrayList<>();
parentAvport.setSelectionGroup(null);
parentAvport.getAlignment().deleteAllGroups();
* @param node
* @return
*/
- private List<PhylogenyNode> colourNodesAboveThreshold(
- List<PhylogenyNode> nodeList, double threshold,
- PhylogenyNode node)
+ private List<TreeNodeI> colourNodesAboveThreshold(
+ List<TreeNodeI> nodeList, double threshold,
+ TreeNodeI node)
{
- for (PhylogenyNode childNode : node.getDescendants())
+ for (TreeNodeI childNode : node.getDirectChildren())
{
- childNode.getBranchData()
- .setBranchColor(new BranchColor(Color.black));
+ childNode.setBranchColor(Color.black);
float nodeCutoff = (childNode.getXcoord() - rootX)
/ (furthestNodeX - rootX);
Color randomColour = new Color((int) (Math.random() * 255),
(int) (Math.random() * 255), (int) (Math.random() * 255));
- childNode.getBranchData()
- .setBranchColor(new BranchColor(randomColour));
+ childNode.setBranchColor(randomColour);
List<SequenceI> groupSeqs = new ArrayList<>();
SequenceI seq = nodesBoundToSequences.get(childNode);
parentAvport.setSequenceColour(seq, randomColour);
}
- List<PhylogenyNode> descendantNodes = PhylogenyMethods
- .getAllDescendants(childNode);
+ List<TreeNodeI> descendantNodes = childNode
+ .getAllDescendants();
// .forEach instead?
- for (PhylogenyNode descNode : descendantNodes)
+ for (TreeNodeI descNode : descendantNodes)
{
seq = nodesBoundToSequences.get(descNode);
if (seq != null)
parentAvport.setSequenceColour(seq, randomColour);
}
- descNode.getBranchData()
- .setBranchColor(new BranchColor(randomColour));
+ descNode.setBranchColor(randomColour);
}
if (groupSeqs != null)
* does)
*/
@Override
- public void showNodeSelectionOnAlign(final PhylogenyNode node)
+ public void showNodeSelectionOnAlign(final TreeNodeI node)
{
if (node.isInternal())
@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();
}
@Override
- public void showMatchingChildSequences(final PhylogenyNode parentNode)
+ public void showMatchingChildSequences(final TreeNodeI parentNode)
{
- List<PhylogenyNode> childNodes = PhylogenyMethods
- .getAllDescendants(parentNode);
+ // redundancy here, Forester already iterates through tree to get all
+ // descendants
+ List<TreeNodeI> childNodes = parentNode.getAllDescendants();
- for (PhylogenyNode childNode : childNodes)
+ for (TreeNodeI childNode : childNodes)
{
// childNode.getBranchData().setBranchColor(new BranchColor(Color.BLUE));
if (matchingSequence != null)
{
long nodeId = childNode.getId();
- addOrRemoveInSet(treeView.getFoundNodes0(), nodeId);
+ addOrRemoveInSet(treeView.getMatchingNodes(), nodeId);
treeSelectionChanged(matchingSequence);
@Override
public void sortByTree_actionPerformed()// modify for Aptx
{
- //
+
// if (treeCanvas.applyToAllViews)
// {
// final ArrayList<CommandI> commands = new ArrayList<>();
// for (AlignmentPanel ap : PaintRefresher
- // .getAssociatedPanels(av.getSequenceSetId()))
+ // .getAssociatedPanels(parentAvport.getSequenceSetId()))
// {
// commands.add(sortAlignmentIn(ap.av.getAlignPanel()));
// }
- // av.getAlignPanel().alignFrame.addHistoryItem(new CommandI()
+ // parentAvport.getAlignPanel().alignFrame.addHistoryItem(new CommandI()
// {
//
// @Override
}
+ @Override
public CommandI sortAlignmentIn(AlignmentPanel ap)
{
- // // TODO: move to alignment view controller
- // AlignmentViewport viewport = ap.av;
- // SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
- // AlignmentSorter.sortByTree(viewport.getAlignment(), tree);
- // CommandI undo;
- // undo = new OrderCommand("Tree Sort", oldOrder, viewport.getAlignment());
- //
- // ap.paintAlignment(true, false);
- // return undo;
+ // 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;
+
}