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.ext.treeviewer.ExternalTreeViewerBindingI;
8 import jalview.gui.PaintRefresher;
9 import jalview.structure.SelectionSource;
10 import jalview.structure.StructureSelectionManager;
11 import jalview.viewmodel.AlignmentViewport;
13 import java.awt.event.ActionEvent;
14 import java.awt.event.InputEvent;
15 import java.awt.event.MouseEvent;
16 import java.util.HashSet;
17 import java.util.List;
20 import javax.swing.JTabbedPane;
21 import javax.swing.SwingUtilities;
22 import javax.swing.event.ChangeEvent;
23 import javax.swing.event.ChangeListener;
25 import org.forester.archaeopteryx.MainFrame;
26 import org.forester.phylogeny.PhylogenyMethods;
27 import org.forester.phylogeny.PhylogenyNode;
30 * Class for binding the Archaeopteryx tree viewer to the Jalview alignment that
31 * it originates from, meaning that selecting sequences in the tree viewer also
32 * selects them in the alignment view and vice versa.
34 * @author kjvanderheide
37 public final class JalviewBinding
38 implements ExternalTreeViewerBindingI<PhylogenyNode>
40 private org.forester.archaeopteryx.TreePanel treeView;
42 private AlignmentViewport parentAvport;
44 private JTabbedPane treeTabs;
46 private final StructureSelectionManager ssm;
48 private Map<SequenceI, PhylogenyNode> sequencesBoundToNodes;
50 private Map<PhylogenyNode, SequenceI> nodesBoundToSequences;
54 * @param archaeopteryx
56 * @param jalviewAlignmentViewport
57 * alignment viewport from which the tree was calculated.
59 * @param alignMappedToNodes
60 * map with sequences used to calculate the tree and matching tree
61 * nodes as key, value pair respectively.
63 * @param nodesMappedToAlign
64 * map with tree nodes and matching sequences used to calculate the
65 * tree as key, value pair respectively.
67 public JalviewBinding(final MainFrame archaeopteryx,
68 final AlignmentViewport jalviewAlignmentViewport,
69 final Map<SequenceI, PhylogenyNode> alignMappedToNodes,
70 final Map<PhylogenyNode, SequenceI> nodesMappedToAlign)
72 // deal with/prohibit null values here as that will cause problems
73 parentAvport = jalviewAlignmentViewport;
74 sequencesBoundToNodes = alignMappedToNodes;
75 nodesBoundToSequences = nodesMappedToAlign;
77 treeView = archaeopteryx.getMainPanel().getCurrentTreePanel();
78 treeTabs = archaeopteryx.getMainPanel().getTabbedPane();
79 ssm = parentAvport.getStructureSelectionManager();
81 // archaeopteryx.getMainPanel().getControlPanel().setColorBranches(true);
83 ssm.addSelectionListener(this);
84 treeView.addMouseListener(this);
85 PaintRefresher.Register(treeView, parentAvport.getSequenceSetId());
88 treeTabs.addChangeListener(new ChangeListener()
92 public void stateChanged(ChangeEvent e)
95 SwingUtilities.invokeLater(new Runnable()
100 * Resend the selection to the tree view when tabs get switched, this
101 * has to be buried in invokeLater as Forester first resets the tree
102 * view on switching tabs, without invokeLater this would get called
103 * before Forester resets which would nullify the selection.
107 parentAvport.sendSelection();
108 // PaintRefresher.Refresh(treeView,
109 // parentAvport.getSequenceSetId());
121 public void actionPerformed(ActionEvent e)
126 public void mouseClicked(MouseEvent e)
131 public void mousePressed(final MouseEvent e)
133 final PhylogenyNode node = treeView.findNode(e.getX(), e.getY());
136 if ((e.getModifiers() & InputEvent.SHIFT_MASK) == 0) // clear previous
137 // selection if shift
140 parentAvport.setSelectionGroup(null);
143 showNodeSelectionOnAlign(node);
151 public void mouseReleased(MouseEvent e)
156 public void mouseEntered(MouseEvent e)
161 public void mouseExited(MouseEvent e)
167 public void selection(final SequenceGroup seqsel,
168 final ColumnSelection colsel, final HiddenColumns hidden,
169 final SelectionSource source)
171 if (source == parentAvport) // check if source is alignment from where the
174 treeView.setFoundNodes0(
175 new HashSet<Long>(seqsel.getSequences().size()));
177 for (SequenceI selectedSequence : seqsel.getSequences())
179 PhylogenyNode matchingNode = sequencesBoundToNodes.get(selectedSequence);
180 if (matchingNode != null)
182 treeView.getFoundNodes0().add(matchingNode.getId());
186 PaintRefresher.Refresh(treeView, parentAvport.getSequenceSetId());
193 public void partitionTree()
200 public void showNodeSelectionOnAlign(final PhylogenyNode node)
202 if (node.isInternal())
204 showMatchingChildSequences(node);
209 showMatchingSequence(node);
219 public void showMatchingSequence(final PhylogenyNode nodeToMatch)
221 SequenceI matchingSequence = nodesBoundToSequences.get(nodeToMatch);
222 if (matchingSequence != null)
224 treeSelectionChanged(matchingSequence);
225 parentAvport.sendSelection();
226 PaintRefresher.Refresh(treeView, parentAvport.getSequenceSetId()); // redundant?
231 public void showMatchingChildSequences(final PhylogenyNode parentNode)
233 List<PhylogenyNode> childNodes = PhylogenyMethods
234 .getAllDescendants(parentNode);
236 for (PhylogenyNode childNode : childNodes)
238 // childNode.getBranchData().setBranchColor(new BranchColor(Color.BLUE));
240 SequenceI matchingSequence = nodesBoundToSequences.get(childNode);
241 if (matchingSequence != null)
243 treeSelectionChanged(matchingSequence);
247 parentAvport.sendSelection();
248 PaintRefresher.Refresh(treeView, parentAvport.getSequenceSetId()); // redundant?
252 * Refactored from TreeCanvas.
255 * of the node selected in the tree viewer.
258 public void treeSelectionChanged(final SequenceI sequence)
260 SequenceGroup selected = parentAvport.getSelectionGroup();
262 if (selected == null)
264 selected = new SequenceGroup();
265 parentAvport.setSelectionGroup(selected);
268 selected.setEndRes(parentAvport.getAlignment().getWidth() - 1);
269 selected.addOrRemove(sequence, true);
273 public AlignmentViewport getParentAvport()
278 public void setParentAvport(final AlignmentViewport parentAvport)
280 this.parentAvport = parentAvport;