Clover icon

Coverage Report

  1. Project Clover database Tue Mar 10 2026 14:58:44 GMT
  2. Package jalview.gui

File SeqPanelTest.java

 

Code metrics

8
519
16
1
1,077
716
22
0.04
32.44
16
1.38

Classes

Class Line # Actions
SeqPanelTest 59 519 22
0.00%
 

Contributing tests

No tests hitting this source file were found.

Source view

1    /*
2    * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3    * Copyright (C) $$Year-Rel$$ The Jalview Authors
4    *
5    * This file is part of Jalview.
6    *
7    * Jalview is free software: you can redistribute it and/or
8    * modify it under the terms of the GNU General Public License
9    * as published by the Free Software Foundation, either version 3
10    * of the License, or (at your option) any later version.
11    *
12    * Jalview is distributed in the hope that it will be useful, but
13    * WITHOUT ANY WARRANTY; without even the implied warranty
14    * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15    * PURPOSE. See the GNU General Public License for more details.
16    *
17    * You should have received a copy of the GNU General Public License
18    * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19    * The Jalview Authors are detailed in the 'AUTHORS' file.
20    */
21    package jalview.gui;
22   
23    import static org.testng.Assert.assertEquals;
24    import static org.testng.Assert.assertNull;
25    import static org.testng.Assert.assertTrue;
26   
27    import java.awt.EventQueue;
28    import java.awt.FontMetrics;
29    import java.awt.event.MouseEvent;
30    import java.lang.reflect.InvocationTargetException;
31   
32    import javax.swing.JLabel;
33   
34    import org.testng.annotations.AfterMethod;
35    import org.testng.annotations.BeforeClass;
36    import org.testng.annotations.Test;
37    import jalview.api.AlignViewportI;
38    import jalview.bin.Cache;
39    import jalview.bin.Jalview;
40    import jalview.commands.EditCommand;
41    import jalview.commands.EditCommand.Action;
42    import jalview.commands.EditCommand.Edit;
43    import jalview.datamodel.Alignment;
44    import jalview.datamodel.AlignmentAnnotation;
45    import jalview.datamodel.AlignmentI;
46    import jalview.datamodel.SearchResults;
47    import jalview.datamodel.SearchResultsI;
48    import jalview.datamodel.Sequence;
49    import jalview.datamodel.SequenceI;
50    import jalview.gui.SeqPanel.MousePos;
51    import jalview.io.DataSourceType;
52    import jalview.io.FileLoader;
53    import jalview.util.MessageManager;
54    import jalview.viewmodel.ViewportRanges;
55   
56   
57    import junit.extensions.PA;
58   
 
59    public class SeqPanelTest
60    {
61    AlignFrame af;
62   
 
63  0 toggle @BeforeClass(alwaysRun = true)
64    public void setUpJvOptionPane()
65    {
66  0 JvOptionPane.setInteractiveMode(false);
67  0 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
68    }
69   
 
70  0 toggle @Test(groups = "Functional")
71    public void testSetStatusReturnsNearestResiduePosition()
72    {
73  0 SequenceI seq1 = new Sequence("Seq1", "AACDE");
74  0 SequenceI seq2 = new Sequence("Seq2", "AA--E");
75  0 AlignmentI al = new Alignment(new SequenceI[] { seq1, seq2 });
76  0 AlignFrame alignFrame = new AlignFrame(al, al.getWidth(),
77    al.getHeight());
78  0 AlignmentI visAl = alignFrame.getViewport().getAlignment();
79   
80    // Test either side of gap
81  0 assertEquals(alignFrame.alignPanel.getSeqPanel()
82    .setStatusMessage(visAl.getSequenceAt(1), 1, 1), 2);
83  0 assertEquals(((JLabel) PA.getValue(alignFrame, "statusBar")).getText(),
84    "Sequence 2 ID: Seq2 Residue: ALA (2)");
85  0 assertEquals(alignFrame.alignPanel.getSeqPanel()
86    .setStatusMessage(visAl.getSequenceAt(1), 4, 1), 3);
87  0 assertEquals(((JLabel) PA.getValue(alignFrame, "statusBar")).getText(),
88    "Sequence 2 ID: Seq2 Residue: GLU (3)");
89    // no status message at a gap, returns next residue position to the right
90  0 assertEquals(alignFrame.alignPanel.getSeqPanel()
91    .setStatusMessage(visAl.getSequenceAt(1), 2, 1), 3);
92  0 assertEquals(((JLabel) PA.getValue(alignFrame, "statusBar")).getText(),
93    "Sequence 2 ID: Seq2");
94  0 assertEquals(alignFrame.alignPanel.getSeqPanel()
95    .setStatusMessage(visAl.getSequenceAt(1), 3, 1), 3);
96  0 assertEquals(((JLabel) PA.getValue(alignFrame, "statusBar")).getText(),
97    "Sequence 2 ID: Seq2");
98    }
99   
 
100  0 toggle @Test(groups = "Functional")
101    public void testAmbiguousAminoAcidGetsStatusMessage()
102    {
103  0 SequenceI seq1 = new Sequence("Seq1", "ABCDE");
104  0 SequenceI seq2 = new Sequence("Seq2", "AB--E");
105  0 AlignmentI al = new Alignment(new SequenceI[] { seq1, seq2 });
106  0 AlignFrame alignFrame = new AlignFrame(al, al.getWidth(),
107    al.getHeight());
108  0 AlignmentI visAl = alignFrame.getViewport().getAlignment();
109   
110  0 assertEquals(alignFrame.alignPanel.getSeqPanel()
111    .setStatusMessage(visAl.getSequenceAt(1), 1, 1), 2);
112  0 assertEquals(((JLabel) PA.getValue(alignFrame, "statusBar")).getText(),
113    "Sequence 2 ID: Seq2 Residue: B (2)");
114    }
115   
 
116  0 toggle @Test(groups = "Functional")
117    public void testGetEditStatusMessage()
118    {
119  0 assertNull(SeqPanel.getEditStatusMessage(null));
120   
121  0 EditCommand edit = new EditCommand(); // empty
122  0 assertNull(SeqPanel.getEditStatusMessage(edit));
123   
124  0 SequenceI[] seqs = new SequenceI[] { new Sequence("a", "b") };
125   
126    // 1 gap
127  0 edit.addEdit(edit.new Edit(Action.INSERT_GAP, seqs, 1, 1, '-'));
128  0 String expected = MessageManager.formatMessage("label.insert_gap", "1");
129  0 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
130   
131    // 3 more gaps makes +4
132  0 edit.addEdit(edit.new Edit(Action.INSERT_GAP, seqs, 1, 3, '-'));
133  0 expected = MessageManager.formatMessage("label.insert_gaps", "4");
134  0 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
135   
136    // 2 deletes makes + 2
137  0 edit.addEdit(edit.new Edit(Action.DELETE_GAP, seqs, 1, 2, '-'));
138  0 expected = MessageManager.formatMessage("label.insert_gaps", "2");
139  0 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
140   
141    // 2 more deletes makes 0 - no text
142  0 edit.addEdit(edit.new Edit(Action.DELETE_GAP, seqs, 1, 2, '-'));
143  0 assertNull(SeqPanel.getEditStatusMessage(edit));
144   
145    // 1 more delete makes 1 delete
146  0 edit.addEdit(edit.new Edit(Action.DELETE_GAP, seqs, 1, 1, '-'));
147  0 expected = MessageManager.formatMessage("label.delete_gap", "1");
148  0 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
149   
150    // 1 more delete makes 2 deletes
151  0 edit.addEdit(edit.new Edit(Action.DELETE_GAP, seqs, 1, 1, '-'));
152  0 expected = MessageManager.formatMessage("label.delete_gaps", "2");
153  0 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
154    }
155   
156    /**
157    * Tests that simulate 'locked editing', where an inserted gap is balanced by
158    * a gap deletion in the selection group, and vice versa
159    */
 
160  0 toggle @Test(groups = "Functional")
161    public void testGetEditStatusMessage_lockedEditing()
162    {
163  0 EditCommand edit = new EditCommand(); // empty
164  0 SequenceI[] seqs = new SequenceI[] { new Sequence("a", "b") };
165   
166    // 1 gap inserted, balanced by 1 delete
167  0 Edit e1 = edit.new Edit(Action.INSERT_GAP, seqs, 1, 1, '-');
168  0 edit.addEdit(e1);
169  0 Edit e2 = edit.new Edit(Action.DELETE_GAP, seqs, 5, 1, '-');
170  0 e2.setSystemGenerated(true);
171  0 edit.addEdit(e2);
172  0 String expected = MessageManager.formatMessage("label.insert_gap", "1");
173  0 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
174   
175    // 2 more gaps makes +3
176  0 Edit e3 = edit.new Edit(Action.INSERT_GAP, seqs, 1, 2, '-');
177  0 edit.addEdit(e3);
178  0 Edit e4 = edit.new Edit(Action.DELETE_GAP, seqs, 5, 2, '-');
179  0 e4.setSystemGenerated(true);
180  0 edit.addEdit(e4);
181  0 expected = MessageManager.formatMessage("label.insert_gaps", "3");
182  0 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
183   
184    // 2 deletes makes + 1
185  0 Edit e5 = edit.new Edit(Action.DELETE_GAP, seqs, 1, 2, '-');
186  0 edit.addEdit(e5);
187  0 Edit e6 = edit.new Edit(Action.INSERT_GAP, seqs, 5, 2, '-');
188  0 e6.setSystemGenerated(true);
189  0 edit.addEdit(e6);
190  0 expected = MessageManager.formatMessage("label.insert_gap", "1");
191  0 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
192   
193    // 1 more delete makes 0 - no text
194  0 Edit e7 = edit.new Edit(Action.DELETE_GAP, seqs, 1, 1, '-');
195  0 edit.addEdit(e7);
196  0 Edit e8 = edit.new Edit(Action.INSERT_GAP, seqs, 5, 1, '-');
197  0 e8.setSystemGenerated(true);
198  0 edit.addEdit(e8);
199  0 expected = MessageManager.formatMessage("label.insert_gaps", "2");
200  0 assertNull(SeqPanel.getEditStatusMessage(edit));
201   
202    // 1 more delete makes 1 delete
203  0 Edit e9 = edit.new Edit(Action.DELETE_GAP, seqs, 1, 1, '-');
204  0 edit.addEdit(e9);
205  0 Edit e10 = edit.new Edit(Action.INSERT_GAP, seqs, 5, 1, '-');
206  0 e10.setSystemGenerated(true);
207  0 edit.addEdit(e10);
208  0 expected = MessageManager.formatMessage("label.delete_gap", "1");
209  0 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
210   
211    // 2 more deletes makes 3 deletes
212  0 Edit e11 = edit.new Edit(Action.DELETE_GAP, seqs, 1, 2, '-');
213  0 edit.addEdit(e11);
214  0 Edit e12 = edit.new Edit(Action.INSERT_GAP, seqs, 5, 2, '-');
215  0 e12.setSystemGenerated(true);
216  0 edit.addEdit(e12);
217  0 expected = MessageManager.formatMessage("label.delete_gaps", "3");
218  0 assertEquals(SeqPanel.getEditStatusMessage(edit), expected);
219    }
220   
 
221  0 toggle public void testFindMousePosition_unwrapped()
222    {
223  0 String seqData = ">Seq1\nAACDE\n>Seq2\nAA--E\n";
224  0 AlignFrame alignFrame = new FileLoader().LoadFileWaitTillLoaded(seqData,
225    DataSourceType.PASTE);
226  0 AlignViewportI av = alignFrame.getViewport();
227  0 av.setShowAnnotation(true);
228  0 av.setWrapAlignment(false);
229  0 final int charHeight = av.getCharHeight();
230  0 final int charWidth = av.getCharWidth();
231    // sanity checks:
232  0 assertTrue(charHeight > 0);
233  0 assertTrue(charWidth > 0);
234  0 assertTrue(alignFrame.alignPanel.getSeqPanel().getWidth() > 0);
235   
236  0 SeqPanel testee = alignFrame.alignPanel.getSeqPanel();
237  0 int x = 0;
238  0 int y = 0;
239   
240    /*
241    * mouse at top left of unwrapped panel
242    */
243  0 MouseEvent evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0,
244    x, y, 0, 0, 0, false, 0);
245  0 MousePos pos = testee.findMousePosition(evt);
246  0 assertEquals(pos.column, 0);
247  0 assertEquals(pos.seqIndex, 0);
248  0 assertEquals(pos.annotationIndex, -1);
249    }
250   
 
251  0 toggle @AfterMethod(alwaysRun = true)
252    public void tearDown()
253    {
254  0 if (Desktop.getInstance() != null)
255  0 Desktop.getInstance().closeAll_actionPerformed(null);
256    }
257   
 
258  0 toggle @Test(groups = "Functional")
259    public void testFindMousePosition_wrapped_annotations()
260    {
261  0 Cache.setPropertyNoSave("SHOW_ANNOTATIONS", "true");
262  0 Cache.setPropertyNoSave("WRAP_ALIGNMENT", "true");
263  0 AlignFrame alignFrame = new FileLoader().LoadFileWaitTillLoaded(
264    "examples/uniref50.fa", DataSourceType.FILE);
265  0 AlignViewportI av = alignFrame.getViewport();
266  0 av.setScaleAboveWrapped(false);
267  0 av.setScaleLeftWrapped(false);
268  0 av.setScaleRightWrapped(false);
269   
270  0 alignFrame.alignPanel.updateLayout();
271   
272  0 final int charHeight = av.getCharHeight();
273  0 final int charWidth = av.getCharWidth();
274  0 final int alignmentHeight = av.getAlignment().getHeight();
275   
276    // sanity checks:
277  0 assertTrue(charHeight > 0);
278  0 assertTrue(charWidth > 0);
279  0 assertTrue(alignFrame.alignPanel.getSeqPanel().getWidth() > 0);
280   
281  0 SeqPanel testee = alignFrame.alignPanel.getSeqPanel();
282  0 int x = 0;
283  0 int y = 0;
284   
285    /*
286    * mouse at top left of wrapped panel; there is a gap of charHeight
287    * above the alignment
288    */
289  0 MouseEvent evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0,
290    x, y, 0, 0, 0, false, 0);
291  0 MousePos pos = testee.findMousePosition(evt);
292  0 assertEquals(pos.column, 0);
293  0 assertEquals(pos.seqIndex, -1); // above sequences
294  0 assertEquals(pos.annotationIndex, -1);
295   
296    /*
297    * cursor at bottom of gap above
298    */
299  0 y = charHeight - 1;
300  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0,
301    0, false, 0);
302  0 pos = testee.findMousePosition(evt);
303  0 assertEquals(pos.seqIndex, -1);
304  0 assertEquals(pos.annotationIndex, -1);
305   
306    /*
307    * cursor over top of first sequence
308    */
309  0 y = charHeight;
310  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0,
311    0, false, 0);
312  0 pos = testee.findMousePosition(evt);
313  0 assertEquals(pos.seqIndex, 0);
314  0 assertEquals(pos.annotationIndex, -1);
315   
316    /*
317    * cursor at bottom of first sequence
318    */
319  0 y = 2 * charHeight - 1;
320  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0,
321    0, false, 0);
322  0 pos = testee.findMousePosition(evt);
323  0 assertEquals(pos.seqIndex, 0);
324  0 assertEquals(pos.annotationIndex, -1);
325   
326    /*
327    * cursor at top of second sequence
328    */
329  0 y = 2 * charHeight;
330  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0,
331    0, false, 0);
332  0 pos = testee.findMousePosition(evt);
333  0 assertEquals(pos.seqIndex, 1);
334  0 assertEquals(pos.annotationIndex, -1);
335   
336    /*
337    * cursor at bottom of second sequence
338    */
339  0 y = 3 * charHeight - 1;
340  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0,
341    0, false, 0);
342  0 pos = testee.findMousePosition(evt);
343  0 assertEquals(pos.seqIndex, 1);
344  0 assertEquals(pos.annotationIndex, -1);
345   
346    /*
347    * cursor at bottom of last sequence
348    */
349  0 y = charHeight * (1 + alignmentHeight) - 1;
350  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0,
351    0, false, 0);
352  0 pos = testee.findMousePosition(evt);
353  0 assertEquals(pos.seqIndex, alignmentHeight - 1);
354  0 assertEquals(pos.annotationIndex, -1);
355   
356    /*
357    * cursor below sequences, in 3-pixel gap above annotations
358    * method reports index of nearest sequence above
359    */
360  0 y += 1;
361  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0,
362    0, false, 0);
363  0 pos = testee.findMousePosition(evt);
364  0 assertEquals(pos.seqIndex, alignmentHeight - 1);
365  0 assertEquals(pos.annotationIndex, -1);
366   
367    /*
368    * cursor still in the gap above annotations, now at the bottom of it
369    */
370  0 y += SeqCanvas.SEQS_ANNOTATION_GAP - 1; // 3-1 = 2
371  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0,
372    0, false, 0);
373  0 pos = testee.findMousePosition(evt);
374  0 assertEquals(pos.seqIndex, alignmentHeight - 1);
375  0 assertEquals(pos.annotationIndex, -1);
376   
377  0 AlignmentAnnotation[] annotationRows = av.getAlignment()
378    .getAlignmentAnnotation();
379  0 for (int n = 0; n < annotationRows.length; n++)
380    {
381    /*
382    * cursor at the top of the n'th annotation
383    */
384  0 y += 1;
385  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0,
386    0, 0, false, 0);
387  0 pos = testee.findMousePosition(evt);
388  0 assertEquals(pos.seqIndex, alignmentHeight - 1);
389  0 assertEquals(pos.annotationIndex, n); // over n'th annotation
390   
391    /*
392    * cursor at the bottom of the n'th annotation
393    */
394  0 y += annotationRows[n].height - 1;
395  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0,
396    0, 0, false, 0);
397  0 pos = testee.findMousePosition(evt);
398  0 assertEquals(pos.seqIndex, alignmentHeight - 1);
399  0 assertEquals(pos.annotationIndex, n);
400    }
401   
402    /*
403    * cursor in gap between wrapped widths
404    */
405  0 y += 1;
406  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0,
407    0, false, 0);
408  0 pos = testee.findMousePosition(evt);
409  0 assertEquals(pos.seqIndex, -1);
410  0 assertEquals(pos.annotationIndex, -1);
411   
412    /*
413    * cursor at bottom of gap between wrapped widths
414    */
415  0 y += charHeight - 1;
416  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0,
417    0, false, 0);
418  0 pos = testee.findMousePosition(evt);
419  0 assertEquals(pos.seqIndex, -1);
420  0 assertEquals(pos.annotationIndex, -1);
421   
422    /*
423    * cursor at top of first sequence, second wrapped width
424    */
425  0 y += 1;
426  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0,
427    0, false, 0);
428  0 pos = testee.findMousePosition(evt);
429  0 assertEquals(pos.seqIndex, 0);
430  0 assertEquals(pos.annotationIndex, -1);
431    }
432   
 
433  0 toggle @Test(groups = "Functional")
434    public void testFindMousePosition_wrapped_scaleAbove()
435    {
436  0 Cache.setPropertyNoSave("SHOW_ANNOTATIONS", "true");
437  0 Cache.setPropertyNoSave("WRAP_ALIGNMENT", "true");
438  0 AlignFrame alignFrame = new FileLoader().LoadFileWaitTillLoaded(
439    "examples/uniref50.fa", DataSourceType.FILE);
440  0 AlignViewportI av = alignFrame.getViewport();
441  0 av.setScaleAboveWrapped(true);
442  0 av.setScaleLeftWrapped(false);
443  0 av.setScaleRightWrapped(false);
444  0 alignFrame.alignPanel.updateLayout();
445   
446  0 final int charHeight = av.getCharHeight();
447  0 final int charWidth = av.getCharWidth();
448  0 final int alignmentHeight = av.getAlignment().getHeight();
449   
450    // sanity checks:
451  0 assertTrue(charHeight > 0);
452  0 assertTrue(charWidth > 0);
453  0 assertTrue(alignFrame.alignPanel.getSeqPanel().getWidth() > 0);
454   
455  0 SeqPanel testee = alignFrame.alignPanel.getSeqPanel();
456  0 int x = 0;
457  0 int y = 0;
458   
459    /*
460    * mouse at top left of wrapped panel; there is a gap of charHeight
461    * above the alignment
462    */
463  0 MouseEvent evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0,
464    x, y, 0, 0, 0, false, 0);
465  0 MousePos pos = testee.findMousePosition(evt);
466  0 assertEquals(pos.column, 0);
467  0 assertEquals(pos.seqIndex, -1); // above sequences
468  0 assertEquals(pos.annotationIndex, -1);
469   
470    /*
471    * cursor at bottom of gap above
472    * two charHeights including scale panel
473    */
474  0 y = 2 * charHeight - 1;
475  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0,
476    0, false, 0);
477  0 pos = testee.findMousePosition(evt);
478  0 assertEquals(pos.seqIndex, -1);
479  0 assertEquals(pos.annotationIndex, -1);
480   
481    /*
482    * cursor over top of first sequence
483    */
484  0 y += 1;
485  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0,
486    0, false, 0);
487  0 pos = testee.findMousePosition(evt);
488  0 assertEquals(pos.seqIndex, 0);
489  0 assertEquals(pos.annotationIndex, -1);
490   
491    /*
492    * cursor at bottom of first sequence
493    */
494  0 y += charHeight - 1;
495  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0,
496    0, false, 0);
497  0 pos = testee.findMousePosition(evt);
498  0 assertEquals(pos.seqIndex, 0);
499  0 assertEquals(pos.annotationIndex, -1);
500   
501    /*
502    * cursor at top of second sequence
503    */
504  0 y += 1;
505  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0,
506    0, false, 0);
507  0 pos = testee.findMousePosition(evt);
508  0 assertEquals(pos.seqIndex, 1);
509  0 assertEquals(pos.annotationIndex, -1);
510   
511    /*
512    * cursor at bottom of second sequence
513    */
514  0 y += charHeight - 1;
515  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0,
516    0, false, 0);
517  0 pos = testee.findMousePosition(evt);
518  0 assertEquals(pos.seqIndex, 1);
519  0 assertEquals(pos.annotationIndex, -1);
520   
521    /*
522    * cursor at bottom of last sequence
523    * (scale + gap + sequences)
524    */
525  0 y = charHeight * (2 + alignmentHeight) - 1;
526  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0,
527    0, false, 0);
528  0 pos = testee.findMousePosition(evt);
529  0 assertEquals(pos.seqIndex, alignmentHeight - 1);
530  0 assertEquals(pos.annotationIndex, -1);
531   
532    /*
533    * cursor below sequences, in 3-pixel gap above annotations
534    */
535  0 y += 1;
536  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0,
537    0, false, 0);
538  0 pos = testee.findMousePosition(evt);
539  0 assertEquals(pos.seqIndex, alignmentHeight - 1);
540  0 assertEquals(pos.annotationIndex, -1);
541   
542    /*
543    * cursor still in the gap above annotations, now at the bottom of it
544    * method reports index of nearest sequence above
545    */
546  0 y += SeqCanvas.SEQS_ANNOTATION_GAP - 1; // 3-1 = 2
547  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0,
548    0, false, 0);
549  0 pos = testee.findMousePosition(evt);
550  0 assertEquals(pos.seqIndex, alignmentHeight - 1);
551  0 assertEquals(pos.annotationIndex, -1);
552   
553  0 AlignmentAnnotation[] annotationRows = av.getAlignment()
554    .getAlignmentAnnotation();
555  0 for (int n = 0; n < annotationRows.length; n++)
556    {
557    /*
558    * cursor at the top of the n'th annotation
559    */
560  0 y += 1;
561  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0,
562    0, 0, false, 0);
563  0 pos = testee.findMousePosition(evt);
564  0 assertEquals(pos.seqIndex, alignmentHeight - 1);
565  0 assertEquals(pos.annotationIndex, n); // over n'th annotation
566   
567    /*
568    * cursor at the bottom of the n'th annotation
569    */
570  0 y += annotationRows[n].height - 1;
571  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0,
572    0, 0, false, 0);
573  0 pos = testee.findMousePosition(evt);
574  0 SeqCanvas sc = testee.seqCanvas;
575  0 assertEquals(pos.seqIndex, alignmentHeight - 1,
576    String.format("%s n=%d y=%d %d, %d, %d, %d",
577    annotationRows[n].label, n, y, sc.getWidth(),
578    sc.getHeight(), sc.wrappedRepeatHeightPx,
579    sc.wrappedSpaceAboveAlignment));
580  0 assertEquals(pos.annotationIndex, n);
581    }
582   
583    /*
584    * cursor in gap between wrapped widths
585    */
586  0 y += 1;
587  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0,
588    0, false, 0);
589  0 pos = testee.findMousePosition(evt);
590  0 assertEquals(pos.seqIndex, -1);
591  0 assertEquals(pos.annotationIndex, -1);
592   
593    /*
594    * cursor at bottom of gap between wrapped widths
595    */
596  0 y += charHeight - 1;
597  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0,
598    0, false, 0);
599  0 pos = testee.findMousePosition(evt);
600  0 assertEquals(pos.seqIndex, -1);
601  0 assertEquals(pos.annotationIndex, -1);
602   
603    /*
604    * cursor at top of scale, second wrapped width
605    */
606  0 y += 1;
607  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0,
608    0, false, 0);
609  0 pos = testee.findMousePosition(evt);
610  0 assertEquals(pos.seqIndex, -1);
611  0 assertEquals(pos.annotationIndex, -1);
612   
613    /*
614    * cursor at bottom of scale, second wrapped width
615    */
616  0 y += charHeight - 1;
617  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0,
618    0, false, 0);
619  0 pos = testee.findMousePosition(evt);
620  0 assertEquals(pos.seqIndex, -1);
621  0 assertEquals(pos.annotationIndex, -1);
622   
623    /*
624    * cursor at top of first sequence, second wrapped width
625    */
626  0 y += 1;
627  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0,
628    0, false, 0);
629  0 pos = testee.findMousePosition(evt);
630  0 assertEquals(pos.seqIndex, 0);
631  0 assertEquals(pos.annotationIndex, -1);
632    }
633   
 
634  0 toggle @Test(groups = "Functional")
635    public void testFindMousePosition_wrapped_noAnnotations()
636    {
637  0 Cache.setPropertyNoSave("SHOW_ANNOTATIONS", "false");
638  0 Cache.setPropertyNoSave("WRAP_ALIGNMENT", "true");
639  0 Cache.setPropertyNoSave("FONT_SIZE", "10");
640  0 AlignFrame alignFrame = new FileLoader().LoadFileWaitTillLoaded(
641    "examples/uniref50.fa", DataSourceType.FILE);
642  0 AlignViewportI av = alignFrame.getViewport();
643  0 av.setScaleAboveWrapped(false);
644  0 av.setScaleLeftWrapped(false);
645  0 av.setScaleRightWrapped(false);
646  0 alignFrame.alignPanel.updateLayout();
647   
648  0 final int charHeight = av.getCharHeight();
649  0 final int charWidth = av.getCharWidth();
650  0 final int alignmentHeight = av.getAlignment().getHeight();
651   
652    // sanity checks:
653  0 assertTrue(charHeight > 0);
654  0 assertTrue(charWidth > 0);
655  0 assertTrue(alignFrame.alignPanel.getSeqPanel().getWidth() > 0);
656   
657  0 SeqPanel testee = alignFrame.alignPanel.getSeqPanel();
658  0 int x = 0;
659  0 int y = 0;
660   
661    /*
662    * mouse at top left of wrapped panel; there is a gap of charHeight
663    * above the alignment
664    */
665  0 MouseEvent evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0,
666    x, y, 0, 0, 0, false, 0);
667  0 MousePos pos = testee.findMousePosition(evt);
668  0 assertEquals(pos.column, 0);
669  0 assertEquals(pos.seqIndex, -1); // above sequences
670  0 assertEquals(pos.annotationIndex, -1);
671   
672    /*
673    * cursor over top of first sequence
674    */
675  0 y = charHeight;
676  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0,
677    0, false, 0);
678  0 pos = testee.findMousePosition(evt);
679  0 assertEquals(pos.seqIndex, 0);
680  0 assertEquals(pos.annotationIndex, -1);
681   
682    /*
683    * cursor at bottom of last sequence
684    */
685  0 y = charHeight * (1 + alignmentHeight) - 1;
686  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0,
687    0, false, 0);
688  0 pos = testee.findMousePosition(evt);
689  0 assertEquals(pos.seqIndex, alignmentHeight - 1);
690  0 assertEquals(pos.annotationIndex, -1);
691   
692    /*
693    * cursor below sequences, at top of charHeight gap between widths
694    */
695  0 y += 1;
696  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0,
697    0, false, 0);
698  0 pos = testee.findMousePosition(evt);
699  0 assertEquals(pos.seqIndex, -1);
700  0 assertEquals(pos.annotationIndex, -1);
701   
702    /*
703    * cursor below sequences, at top of charHeight gap between widths
704    */
705  0 y += charHeight - 1;
706  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0,
707    0, false, 0);
708  0 pos = testee.findMousePosition(evt);
709  0 assertEquals(pos.seqIndex, -1);
710  0 assertEquals(pos.annotationIndex, -1);
711   
712    /*
713    * cursor at the top of the first sequence, second width
714    */
715  0 y += 1;
716  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0,
717    0, false, 0);
718  0 pos = testee.findMousePosition(evt);
719  0 assertEquals(pos.seqIndex, 0);
720  0 assertEquals(pos.annotationIndex, -1);
721    }
722   
 
723  0 toggle @Test(groups = "Functional")
724    public void testFindColumn_unwrapped()
725    {
726  0 Cache.setPropertyNoSave("WRAP_ALIGNMENT", "false");
727  0 AlignFrame alignFrame = new FileLoader().LoadFileWaitTillLoaded(
728    "examples/uniref50.fa", DataSourceType.FILE);
729  0 SeqPanel testee = alignFrame.alignPanel.getSeqPanel();
730  0 int x = 0;
731  0 final int charWidth = alignFrame.getViewport().getCharWidth();
732  0 assertTrue(charWidth > 0); // sanity check
733  0 ViewportRanges ranges = alignFrame.getViewport().getRanges();
734  0 assertEquals(ranges.getStartRes(), 0);
735   
736    /*
737    * mouse at top left of unwrapped panel
738    */
739  0 MouseEvent evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0,
740    x, 0, 0, 0, 0, false, 0);
741  0 assertEquals(testee.findColumn(evt), 0);
742   
743    /*
744    * not quite one charWidth across
745    */
746  0 x = charWidth - 1;
747  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0, 0, 0,
748    0, false, 0);
749  0 assertEquals(testee.findColumn(evt), 0);
750   
751    /*
752    * one charWidth across
753    */
754  0 x = charWidth;
755  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0, 0, 0,
756    0, false, 0);
757  0 assertEquals(testee.findColumn(evt), 1);
758   
759    /*
760    * two charWidths across
761    */
762  0 x = 2 * charWidth;
763  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0, 0, 0,
764    0, false, 0);
765  0 assertEquals(testee.findColumn(evt), 2);
766   
767    /*
768    * limited to last column of seqcanvas
769    */
770  0 x = 20000;
771  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0, 0, 0,
772    0, false, 0);
773  0 SeqCanvas seqCanvas = alignFrame.alignPanel.getSeqPanel().seqCanvas;
774  0 int w = seqCanvas.getWidth();
775    // limited to number of whole columns, base 0,
776    // and to end of visible range
777  0 int expected = w / charWidth;
778  0 expected = Math.min(expected, ranges.getEndRes());
779  0 assertEquals(testee.findColumn(evt), expected);
780   
781    /*
782    * hide columns 5-10 (base 1)
783    */
784  0 alignFrame.getViewport().hideColumns(4, 9);
785  0 x = 5 * charWidth + 2;
786    // x is in 6th visible column, absolute column 12, or 11 base 0
787  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0, 0, 0,
788    0, false, 0);
789  0 assertEquals(testee.findColumn(evt), 11);
790    }
791   
 
792  0 toggle @Test(groups = "Functional")
793    public void testFindColumn_and_FindAlignmentColumn_wrapped()
794    {
795  0 Cache.setPropertyNoSave("WRAP_ALIGNMENT", "true");
796  0 AlignFrame alignFrame = new FileLoader().LoadFileWaitTillLoaded(
797    "examples/uniref50.fa", DataSourceType.FILE);
798  0 AlignViewport av = alignFrame.getViewport();
799  0 av.setScaleAboveWrapped(false);
800  0 av.setScaleLeftWrapped(false);
801  0 av.setScaleRightWrapped(false);
802  0 alignFrame.alignPanel.updateLayout();
803  0 SeqPanel testee = alignFrame.alignPanel.getSeqPanel();
804  0 int x = 0;
805  0 final int charWidth = av.getCharWidth();
806  0 assertTrue(charWidth > 0); // sanity check
807  0 assertEquals(av.getRanges().getStartRes(), 0);
808   
809    /*
810    * mouse at top left of wrapped panel, no West (left) scale
811    */
812  0 MouseEvent evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0,
813    x, 0, 0, 0, 0, false, 0);
814  0 assertEquals(testee.findColumn(evt), 0);
815  0 assertEquals(testee.findAlignmentColumn(evt), 0);
816   
817    /*
818    * not quite one charWidth across
819    */
820  0 x = charWidth - 1;
821  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0, 0, 0,
822    0, false, 0);
823  0 assertEquals(testee.findColumn(evt), 0);
824  0 assertEquals(testee.findAlignmentColumn(evt), 0);
825   
826    /*
827    * one charWidth across
828    */
829  0 x = charWidth;
830  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0, 0, 0,
831    0, false, 0);
832  0 assertEquals(testee.findColumn(evt), 1);
833  0 assertEquals(testee.findAlignmentColumn(evt), 1);
834   
835    /*
836    * x over scale left (before drawn columns) results in -1
837    */
838  0 av.setScaleLeftWrapped(true);
839  0 alignFrame.alignPanel.updateLayout();
840  0 SeqCanvas seqCanvas = testee.seqCanvas;
841  0 int labelWidth = (int) PA.getValue(seqCanvas, "labelWidthWest");
842  0 assertTrue(labelWidth > 0);
843  0 x = labelWidth - 1;
844  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0, 0, 0,
845    0, false, 0);
846  0 assertEquals(testee.findColumn(evt), -1);
847  0 assertEquals(testee.findAlignmentColumn(evt), 0);
848   
849  0 x = labelWidth;
850  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0, 0, 0,
851    0, false, 0);
852  0 assertEquals(testee.findColumn(evt), 0);
853  0 assertEquals(testee.findAlignmentColumn(evt), 0);
854   
855    /*
856    * x over right edge of last residue (including scale left)
857    */
858  0 int residuesWide = av.getRanges().getViewportWidth();
859  0 assertTrue(residuesWide > 0);
860  0 x = labelWidth + charWidth * residuesWide - 1;
861  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0, 0, 0,
862    0, false, 0);
863  0 assertEquals(testee.findColumn(evt), residuesWide - 1);
864  0 assertEquals(testee.findAlignmentColumn(evt), residuesWide - 1);
865   
866    /*
867    * x over scale right (beyond drawn columns) results in -1
868    */
869  0 av.setScaleRightWrapped(true);
870  0 alignFrame.alignPanel.updateLayout();
871  0 labelWidth = (int) PA.getValue(seqCanvas, "labelWidthEast");
872  0 assertTrue(labelWidth > 0);
873  0 int residuesWide2 = av.getRanges().getViewportWidth();
874  0 assertTrue(residuesWide2 > 0);
875  0 assertTrue(residuesWide2 < residuesWide); // available width reduced
876  0 x += 1; // just over left edge of scale right
877  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, 0, 0, 0,
878    0, false, 0);
879    // on scale
880  0 assertEquals(testee.findColumn(evt), -1);
881    // return right-most column visible
882  0 assertEquals(testee.findAlignmentColumn(evt), residuesWide2 - 1);
883   
884    // todo add startRes offset, hidden columns
885   
886    }
887   
 
888  0 toggle @BeforeClass(alwaysRun = true)
889    public static void setUpBeforeClass() throws Exception
890    {
891    /*
892    * use read-only test properties file
893    */
894  0 Cache.loadProperties("test/jalview/io/testProps.jvprops");
895  0 Jalview.main(new String[] { "--nonews" });
896    }
897   
898    /**
899    * waits for Swing event dispatch queue to empty
900    */
 
901  0 toggle synchronized void waitForSwing()
902    {
903  0 try
904    {
905  0 EventQueue.invokeAndWait(new Runnable()
906    {
 
907  0 toggle @Override
908    public void run()
909    {
910    }
911    });
912    } catch (InterruptedException | InvocationTargetException e)
913    {
914  0 e.printStackTrace();
915    }
916    }
917   
 
918  0 toggle @Test(groups = "Functional")
919    public void testFindMousePosition_wrapped_scales_longSequence()
920    {
921  0 Cache.setPropertyNoSave("SHOW_ANNOTATIONS", "false");
922  0 Cache.setPropertyNoSave("WRAP_ALIGNMENT", "true");
923  0 Cache.setPropertyNoSave("FONT_SIZE", "14");
924  0 Cache.setPropertyNoSave("FONT_NAME", "SansSerif");
925  0 Cache.setPropertyNoSave("FONT_STYLE", "0");
926    // sequence of 50 bases, doubled 10 times, = 51200 bases
927  0 String dna = "ATGGCCATTGGGCCCAAATTTCCCAAAGGGTTTCCCTGAGGTCAGTCAGA";
928  0 for (int i = 0; i < 10; i++)
929    {
930  0 dna += dna;
931    }
932  0 assertEquals(dna.length(), 51200);
933  0 AlignFrame alignFrame = new FileLoader()
934    .LoadFileWaitTillLoaded("dna " + dna, DataSourceType.PASTE);
935  0 SeqPanel testee = alignFrame.alignPanel.getSeqPanel();
936  0 AlignViewport av = alignFrame.getViewport();
937  0 av.setScaleAboveWrapped(true);
938  0 av.setScaleLeftWrapped(true);
939  0 av.setScaleRightWrapped(true);
940  0 alignFrame.alignPanel.updateLayout();
941   
942  0 try
943    {
944  0 Thread.sleep(200);
945    } catch (InterruptedException e)
946    {
947    }
948   
949  0 final int charHeight = av.getCharHeight();
950  0 final int charWidth = av.getCharWidth();
951  0 assertEquals(charHeight, 17);
952  0 assertEquals(charWidth, 12);
953   
954  0 double scaling = JvSwingUtilsTest.getScaling(alignFrame.alignPanel);
955   
956  0 FontMetrics fm = testee.getFontMetrics(av.getFont());
957  0 int labelWidth = fm.stringWidth("00000") + charWidth;
958   
959  0 System.err.println("SeqPanel Test Geometry:\n Font Height:"+fm.getHeight()+"\n LabelWidth: "+labelWidth+"\n PanelWidth:"+testee.getWidth()+"\n PanelHeight:"+testee.getHeight());
960   
961    // some leeway for different OS rendering of text
962  0 assertTrue(labelWidth >= 52 && labelWidth <= 57);
963  0 assertEquals(testee.seqCanvas.getLabelWidthWest(), labelWidth);
964   
965  0 int x = 0;
966  0 int y = 0;
967   
968    /*
969    * mouse at top left of wrapped panel; there is a gap of 2 * charHeight
970    * above the alignment
971    */
972  0 MouseEvent evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0,
973    x, y, 0, 0, 0, false, 0);
974  0 MousePos pos = testee.findMousePosition(evt);
975  0 assertEquals(pos.column, -1); // over scale left, not an alignment column
976  0 assertEquals(pos.seqIndex, -1); // above sequences
977  0 assertEquals(pos.annotationIndex, -1);
978   
979    /*
980    * cursor over scale above first sequence
981    */
982  0 y += charHeight;
983  0 x = labelWidth;
984  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0,
985    0, false, 0);
986  0 pos = testee.findMousePosition(evt);
987  0 assertEquals(pos.seqIndex, -1);
988  0 assertEquals(pos.column, 0);
989  0 assertEquals(pos.annotationIndex, -1);
990   
991    /*
992    * cursor over scale left of first sequence
993    */
994  0 y += charHeight;
995  0 x = 0;
996  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0,
997    0, false, 0);
998  0 pos = testee.findMousePosition(evt);
999  0 assertEquals(pos.seqIndex, 0);
1000  0 assertEquals(pos.column, -1);
1001  0 assertEquals(pos.annotationIndex, -1);
1002   
1003    /*
1004    * cursor over start of first sequence
1005    */
1006  0 x = labelWidth;
1007  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0,
1008    0, false, 0);
1009  0 pos = testee.findMousePosition(evt);
1010  0 assertEquals(pos.seqIndex, 0);
1011  0 assertEquals(pos.column, 0);
1012  0 assertEquals(pos.annotationIndex, -1);
1013   
1014    /*
1015    * move one character right, to bottom pixel of same row
1016    */
1017  0 x += charWidth;
1018  0 y += charHeight - 1;
1019  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0,
1020    0, false, 0);
1021  0 pos = testee.findMousePosition(evt);
1022  0 assertEquals(pos.seqIndex, 0);
1023  0 assertEquals(pos.column, 1);
1024   
1025    /*
1026    * move down one pixel - now in the no man's land between rows
1027    */
1028  0 y += 1;
1029  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0,
1030    0, false, 0);
1031  0 pos = testee.findMousePosition(evt);
1032  0 assertEquals(pos.seqIndex, -1);
1033  0 assertEquals(pos.column, 1);
1034   
1035    /*
1036    * move down two char heights less one pixel - still in the no man's land
1037    * (scale above + spacer line)
1038    */
1039  0 y += (2 * charHeight - 1);
1040  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0,
1041    0, false, 0);
1042  0 pos = testee.findMousePosition(evt);
1043  0 assertEquals(pos.seqIndex, -1);
1044  0 assertEquals(pos.column, 1);
1045   
1046    /*
1047    * move down one more pixel - now on the next row of the sequence
1048    */
1049  0 y += 1;
1050  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0,
1051    0, false, 0);
1052  0 pos = testee.findMousePosition(evt);
1053  0 assertEquals(pos.seqIndex, 0);
1054  0 assertEquals(pos.column, 1 + av.getWrappedWidth());
1055   
1056    /*
1057    * scroll to near the end of the sequence
1058    */
1059  0 SearchResultsI sr = new SearchResults();
1060  0 int scrollTo = dna.length() - 1000;
1061  0 sr.addResult(av.getAlignment().getSequenceAt(0), scrollTo, scrollTo);
1062  0 alignFrame.alignPanel.scrollToPosition(sr);
1063   
1064    /*
1065    * place the mouse on the first column of the 6th sequence, and
1066    * verify that (computed) findMousePosition matches (actual) ViewportRanges
1067    */
1068  0 x = labelWidth;
1069  0 y = 17 * charHeight; // 17 = 6 times two header rows and 5 sequence rows
1070  0 evt = new MouseEvent(testee, MouseEvent.MOUSE_MOVED, 0L, 0, x, y, 0, 0,
1071    0, false, 0);
1072  0 pos = testee.findMousePosition(evt);
1073  0 assertEquals(pos.seqIndex, 0);
1074  0 int expected = av.getRanges().getStartRes() + 5 * av.getWrappedWidth();
1075  0 assertEquals(pos.column, expected);
1076    }
1077    }