1 package jalview.ext.archaeopteryx;
3 import jalview.datamodel.ColumnSelection;
4 import jalview.datamodel.HiddenColumns;
5 import jalview.datamodel.SequenceGroup;
6 import jalview.datamodel.SequenceI;
7 import jalview.gui.PaintRefresher;
8 import jalview.structure.SelectionSource;
9 import jalview.structure.StructureSelectionManager;
10 import jalview.viewmodel.AlignmentViewport;
12 import java.awt.event.ActionEvent;
13 import java.awt.event.InputEvent;
14 import java.awt.event.MouseEvent;
15 import java.util.HashSet;
16 import java.util.List;
19 import org.forester.archaeopteryx.MainFrame;
20 import org.forester.phylogeny.PhylogenyMethods;
21 import org.forester.phylogeny.PhylogenyNode;
24 * Class for binding the Archaeopteryx tree viewer to the Jalview alignment that
25 * it originates from, meaning that selecting sequences in the tree viewer also
26 * selects them in the alignment view and vice versa.
28 * @author kjvanderheide
31 public final class AptxBinding
32 implements ExternalTreeViewerBindingI<PhylogenyNode>
34 private org.forester.archaeopteryx.TreePanel treeView;
36 private AlignmentViewport parentAvport;
38 private final StructureSelectionManager ssm;
40 private Map<SequenceI, PhylogenyNode> sequencesBoundToNodes;
42 private Map<PhylogenyNode, SequenceI> nodesBoundToSequences;
46 * @param archaeopteryx
48 * @param jalviewAlignmentViewport
49 * alignment viewport from which the tree was calculated.
51 * @param alignMappedToNodes
52 * map with sequences used to calculate the tree and matching tree
53 * nodes as key, value pair respectively.
55 * @param nodesMappedToAlign
56 * map with tree nodes and matching sequences used to calculate the
57 * tree as key, value pair respectively.
59 public AptxBinding(final MainFrame archaeopteryx,
60 final AlignmentViewport jalviewAlignmentViewport,
61 final Map<SequenceI, PhylogenyNode> alignMappedToNodes,
62 final Map<PhylogenyNode, SequenceI> nodesMappedToAlign)
64 // deal with/prohibit null values here as that will cause problems
65 parentAvport = jalviewAlignmentViewport;
66 sequencesBoundToNodes = alignMappedToNodes;
67 nodesBoundToSequences = nodesMappedToAlign;
68 treeView = archaeopteryx.getMainPanel().getCurrentTreePanel();
69 ssm = parentAvport.getStructureSelectionManager();
70 ssm.addSelectionListener(this);
71 treeView.addMouseListener(this);
72 PaintRefresher.Register(treeView, parentAvport.getSequenceSetId());
77 public void actionPerformed(ActionEvent e)
82 public void mouseClicked(MouseEvent e)
87 public void mousePressed(final MouseEvent e)
89 showNodeSelectionOnAlign(e);
93 public void mouseReleased(MouseEvent e)
98 public void mouseEntered(MouseEvent e)
103 public void mouseExited(MouseEvent e)
109 public void selection(final SequenceGroup seqsel,
110 final ColumnSelection colsel, final HiddenColumns hidden,
111 final SelectionSource source)
113 if (source == parentAvport) // check if source is alignment from where the
116 treeView.setFoundNodes0(
117 new HashSet<Long>(seqsel.getSequences().size()));
119 for (SequenceI selectedSequence : seqsel.getSequences())
121 PhylogenyNode matchingNode = sequencesBoundToNodes.get(selectedSequence);
122 if (matchingNode != null)
124 treeView.getFoundNodes0().add(matchingNode.getId());
128 PaintRefresher.Refresh(treeView, parentAvport.getSequenceSetId());
136 * If a node is selected in the tree panel this method highlights the
137 * corresponding sequence in the Jalview alignment view. If an internal node
138 * is selected all child sequences get highlighted as well.
141 public void showNodeSelectionOnAlign(final MouseEvent e)
143 final PhylogenyNode node = treeView.findNode(e.getX(), e.getY());
146 if ((e.getModifiers() & InputEvent.SHIFT_MASK) == 0) // clear previous
147 // selection if shift
150 parentAvport.setSelectionGroup(null);
153 if (node.isInternal())
155 showMatchingChildSequences(node);
160 showMatchingSequence(node);
171 public void showMatchingSequence(final PhylogenyNode nodeToMatch)
173 SequenceI matchingSequence = nodesBoundToSequences.get(nodeToMatch);
174 if (matchingSequence != null)
176 treeSelectionChanged(matchingSequence);
177 parentAvport.sendSelection();
178 PaintRefresher.Refresh(treeView, parentAvport.getSequenceSetId());
183 public void showMatchingChildSequences(final PhylogenyNode parentNode)
185 final List<PhylogenyNode> childNodes = PhylogenyMethods
186 .getAllDescendants(parentNode);
188 for (PhylogenyNode childNode : childNodes)
190 SequenceI matchingSequence = nodesBoundToSequences.get(childNode);
191 if (matchingSequence != null)
193 treeSelectionChanged(matchingSequence);
197 parentAvport.sendSelection();
198 PaintRefresher.Refresh(treeView, parentAvport.getSequenceSetId());
202 * Refactored from TreeCanvas.
205 * of the node selected in the tree viewer.
208 public void treeSelectionChanged(final SequenceI sequence)
210 SequenceGroup selected = parentAvport.getSelectionGroup();
212 if (selected == null)
214 selected = new SequenceGroup();
215 parentAvport.setSelectionGroup(selected);
218 selected.setEndRes(parentAvport.getAlignment().getWidth() - 1);
219 selected.addOrRemove(sequence, true);
223 public AlignmentViewport getParentAvport()
228 public void setParentAvport(final AlignmentViewport parentAvport)
230 this.parentAvport = parentAvport;