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 JalviewAptxBinding implements JalviewTreeViewerBindingI
33 private org.forester.archaeopteryx.TreePanel treeView;
35 private AlignmentViewport parentAvport;
37 private final StructureSelectionManager ssm;
39 private Map<SequenceI, PhylogenyNode> sequencesBoundToNodes;
41 private Map<PhylogenyNode, SequenceI> nodesBoundToSequences;
45 * @param archaeopteryx
47 * @param jalviewAlignmentViewport
48 * alignment viewport from which the tree was calculated.
50 * @param alignMappedToNodes
51 * map with sequences used to calculate the tree and matching tree
52 * nodes as key, value pair respectively.
54 * @param nodesMappedToAlign
55 * map with tree nodes and matching sequences used to calculate the
56 * tree as key, value pair respectively.
58 public JalviewAptxBinding(final MainFrame archaeopteryx,
59 final AlignmentViewport jalviewAlignmentViewport,
60 final Map<SequenceI, PhylogenyNode> alignMappedToNodes,
61 final Map<PhylogenyNode, SequenceI> nodesMappedToAlign)
63 // deal with/prohibit null values here as that will cause problems
64 parentAvport = jalviewAlignmentViewport;
65 sequencesBoundToNodes = alignMappedToNodes;
66 nodesBoundToSequences = nodesMappedToAlign;
67 treeView = archaeopteryx.getMainPanel().getCurrentTreePanel();
68 ssm = parentAvport.getStructureSelectionManager();
69 ssm.addSelectionListener(this);
70 treeView.addMouseListener(this);
71 PaintRefresher.Register(treeView, parentAvport.getSequenceSetId());
76 public void actionPerformed(ActionEvent e)
81 public void mouseClicked(MouseEvent e)
86 public void mousePressed(final MouseEvent e)
88 showNodeSelectionOnAlign(e);
92 public void mouseReleased(MouseEvent e)
97 public void mouseEntered(MouseEvent e)
102 public void mouseExited(MouseEvent e)
108 public void selection(final SequenceGroup seqsel,
109 final ColumnSelection colsel, final HiddenColumns hidden,
110 final SelectionSource source)
112 if (source == parentAvport) // check if source is alignment from where the
115 treeView.setFoundNodes0(
116 new HashSet<Long>(seqsel.getSequences().size()));
118 for (SequenceI selectedSequence : seqsel.getSequences())
120 PhylogenyNode matchingNode = sequencesBoundToNodes.get(selectedSequence);
121 if (matchingNode != null)
123 treeView.getFoundNodes0().add(matchingNode.getId());
127 PaintRefresher.Refresh(treeView, parentAvport.getSequenceSetId());
135 * If a node is selected in the tree panel this method highlights the
136 * corresponding sequence in the Jalview alignment view. If an internal node
137 * is selected all child sequences get highlighted as well.
140 public void showNodeSelectionOnAlign(final MouseEvent e)
142 final PhylogenyNode node = treeView.findNode(e.getX(), e.getY());
145 if ((e.getModifiers() & InputEvent.SHIFT_MASK) == 0) // clear previous
146 // selection if shift
149 parentAvport.setSelectionGroup(null);
152 if (node.isInternal())
154 showMatchingChildSequences(node);
159 showMatchingSequence(node);
169 public void showMatchingSequence(final PhylogenyNode nodeToMatch)
171 SequenceI matchingSequence = nodesBoundToSequences.get(nodeToMatch);
172 if (matchingSequence != null)
174 treeSelectionChanged(matchingSequence);
175 parentAvport.sendSelection();
176 PaintRefresher.Refresh(treeView, parentAvport.getSequenceSetId());
180 public void showMatchingChildSequences(final PhylogenyNode parentNode)
182 final List<PhylogenyNode> childNodes = PhylogenyMethods
183 .getAllDescendants(parentNode);
185 for (PhylogenyNode childNode : childNodes)
187 SequenceI matchingSequence = nodesBoundToSequences.get(childNode);
188 if (matchingSequence != null)
190 treeSelectionChanged(matchingSequence);
194 parentAvport.sendSelection();
195 PaintRefresher.Refresh(treeView, parentAvport.getSequenceSetId());
199 * Refactored from TreeCanvas.
202 * of the node selected in the tree viewer.
205 public void treeSelectionChanged(final SequenceI sequence)
207 SequenceGroup selected = parentAvport.getSelectionGroup();
209 if (selected == null)
211 selected = new SequenceGroup();
212 parentAvport.setSelectionGroup(selected);
215 selected.setEndRes(parentAvport.getAlignment().getWidth() - 1);
216 selected.addOrRemove(sequence, true);
220 public AlignmentViewport getParentAvport()
225 public void setParentAvport(final AlignmentViewport parentAvport)
227 this.parentAvport = parentAvport;