JAL-3093 unit tests for SeqPanel.findMousePosition
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Tue, 2 Oct 2018 16:08:07 +0000 (17:08 +0100)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Tue, 2 Oct 2018 16:08:07 +0000 (17:08 +0100)
src/jalview/gui/SeqCanvas.java
src/jalview/gui/SeqPanel.java
test/jalview/gui/SeqPanelTest.java

index 5c404f0..31c8a47 100755 (executable)
@@ -55,6 +55,11 @@ import javax.swing.JComponent;
  */
 public class SeqCanvas extends JComponent implements ViewportListenerI
 {
+  /*
+   * pixels gap between sequences and annotations when in wrapped mode
+   */
+  static final int SEQS_ANNOTATION_GAP = 3;
+
   private static final String ZEROS = "0000000000";
 
   final FeatureRenderer fr;
@@ -705,7 +710,7 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
 
     if (av.isShowAnnotation())
     {
-      g.translate(0, cHeight + ypos + 3);
+      g.translate(0, cHeight + ypos + SEQS_ANNOTATION_GAP);
       if (annotations == null)
       {
         annotations = new AnnotationPanel(av);
@@ -713,7 +718,7 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
 
       annotations.renderer.drawComponent(annotations, av, g, -1,
               startColumn, endx + 1);
-      g.translate(0, -cHeight - ypos - 3);
+      g.translate(0, -cHeight - ypos - SEQS_ANNOTATION_GAP);
     }
     g.setClip(clip);
     g.translate(-xOffset, 0);
index 3f740a1..0b62629 100644 (file)
@@ -255,7 +255,7 @@ public class SeqPanel extends JPanel
   int wrappedBlock = -1;
 
   /**
-   * Computes the column and sequence row (or possibly annotation row when in
+   * Computes the column and sequence row (and possibly annotation row when in
    * wrapped mode) for the given mouse position
    * 
    * @param evt
@@ -264,7 +264,7 @@ public class SeqPanel extends JPanel
   MousePos findMousePosition(MouseEvent evt)
   {
     int col = findColumn(evt);
-    int seq = -1;
+    int seqIndex = -1;
     int annIndex = -1;
     int y = evt.getY();
 
@@ -280,20 +280,23 @@ public class SeqPanel extends JPanel
 
       final int alignmentHeightPixels = alignmentHeight * charHeight + hgap;
       final int annotationHeight = seqCanvas.getAnnotationHeight();
-      final int cHeight = alignmentHeightPixels + annotationHeight;
+      final int cHeight = alignmentHeightPixels + annotationHeight
+              + SeqCanvas.SEQS_ANNOTATION_GAP;
 
       int yOffsetPx = y % cHeight; // yPos below repeating width(s)
-      if (yOffsetPx > alignmentHeightPixels)
+      if (yOffsetPx >= alignmentHeightPixels
+              + SeqCanvas.SEQS_ANNOTATION_GAP)
       {
         /*
-         * mouse is over annotations
+         * mouse is over annotations; find annotation index, also
+         * last sequence above (for backwards compatible behaviour)
          */
         AlignmentAnnotation[] anns = av.getAlignment()
                 .getAlignmentAnnotation();
-        int rowOffsetPx = yOffsetPx - alignmentHeightPixels;
+        int rowOffsetPx = yOffsetPx - alignmentHeightPixels
+                - SeqCanvas.SEQS_ANNOTATION_GAP;
         annIndex = AnnotationPanel.getRowIndex(rowOffsetPx, anns);
-        // also last sequence in alignment (for backwards compatible behaviour)
-        seq = alignmentHeight - 1;
+        seqIndex = alignmentHeight - 1;
       }
       else
       {
@@ -301,18 +304,17 @@ public class SeqPanel extends JPanel
          * mouse is over sequence (or the space above sequences)
          */
         yOffsetPx -= hgap;
-        if (yOffsetPx > 0)
+        if (yOffsetPx >= 0)
         {
-          seq = Math.min(yOffsetPx / charHeight, alignmentHeight - 1);
+          seqIndex = Math.min(yOffsetPx / charHeight, alignmentHeight - 1);
         }
       }
     }
     else
     {
-      seq = Math.min((y / charHeight) + av.getRanges().getStartSeq(),
+      seqIndex = Math.min((y / charHeight) + av.getRanges().getStartSeq(),
               alignmentHeight - 1);
     }
-    int seqIndex = seq;
 
     return new MousePos(col, seqIndex, annIndex);
   }
index a5d244d..4177acc 100644 (file)
 package jalview.gui;
 
 import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
 
+import jalview.api.AlignViewportI;
+import jalview.bin.Cache;
+import jalview.bin.Jalview;
 import jalview.datamodel.Alignment;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceI;
+import jalview.gui.SeqPanel.MousePos;
+import jalview.io.DataSourceType;
+import jalview.io.FileLoader;
 
+import java.awt.Event;
+import java.awt.event.MouseEvent;
+
+import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
@@ -88,4 +99,490 @@ public class SeqPanelTest
     assertEquals(alignFrame.statusBar.getText(),
             "Sequence 2 ID: Seq2 Residue: B (2)");
   }
+
+  @Test(groups = "Functional")
+  public void testFindMousePosition_unwrapped()
+  {
+    String seqData = ">Seq1\nAACDE\n>Seq2\nAA--E\n";
+    AlignFrame alignFrame = new FileLoader().LoadFileWaitTillLoaded(seqData,
+            DataSourceType.PASTE);
+    AlignViewportI av = alignFrame.getViewport();
+    av.setShowAnnotation(true);
+    av.setWrapAlignment(false);
+    final int charHeight = av.getCharHeight();
+    final int charWidth = av.getCharWidth();
+    // sanity checks:
+    assertTrue(charHeight > 0);
+    assertTrue(charWidth > 0);
+    assertTrue(alignFrame.alignPanel.getSeqPanel().getWidth() > 0);
+
+    SeqPanel testee = alignFrame.alignPanel.getSeqPanel();
+    int x = 0;
+    int y = 0;
+
+    /*
+     * mouse at top left of unwrapped panel
+     */
+    MouseEvent evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y,
+            0, 0, 0, false, 0);
+    MousePos pos = testee.findMousePosition(evt);
+    assertEquals(pos.column, 0);
+    assertEquals(pos.seqIndex, 0);
+    assertEquals(pos.annotationIndex, -1);
+  }
+
+  @AfterMethod(alwaysRun = true)
+  public void tearDown()
+  {
+    Desktop.instance.closeAll_actionPerformed(null);
+  }
+
+  @Test(groups = "Functional")
+  public void testFindMousePosition_wrapped()
+  {
+    Cache.applicationProperties.setProperty("SHOW_ANNOTATIONS", "true");
+    Cache.applicationProperties.setProperty("WRAP_ALIGNMENT", "true");
+    AlignFrame alignFrame = new FileLoader().LoadFileWaitTillLoaded(
+            "examples/uniref50.fa", DataSourceType.FILE);
+    AlignViewportI av = alignFrame.getViewport();
+    av.setScaleAboveWrapped(false);
+    av.setScaleLeftWrapped(false);
+    av.setScaleRightWrapped(false);
+    alignFrame.alignPanel.paintAlignment(false, false);
+
+    final int charHeight = av.getCharHeight();
+    final int charWidth = av.getCharWidth();
+    final int alignmentHeight = av.getAlignment().getHeight();
+    
+    // sanity checks:
+    assertTrue(charHeight > 0);
+    assertTrue(charWidth > 0);
+    assertTrue(alignFrame.alignPanel.getSeqPanel().getWidth() > 0);
+  
+    SeqPanel testee = alignFrame.alignPanel.getSeqPanel();
+    int x = 0;
+    int y = 0;
+  
+    /*
+     * mouse at top left of wrapped panel; there is a gap of charHeight
+     * above the alignment
+     */
+    MouseEvent evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y,
+            0, 0, 0, false, 0);
+    MousePos pos = testee.findMousePosition(evt);
+    assertEquals(pos.column, 0);
+    assertEquals(pos.seqIndex, -1); // above sequences
+    assertEquals(pos.annotationIndex, -1);
+
+    /*
+     * cursor at bottom of gap above
+     */
+    y = charHeight - 1;
+    evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
+            false, 0);
+    pos = testee.findMousePosition(evt);
+    assertEquals(pos.seqIndex, -1);
+    assertEquals(pos.annotationIndex, -1);
+
+    /*
+     * cursor over top of first sequence
+     */
+    y = charHeight;
+    evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
+            false, 0);
+    pos = testee.findMousePosition(evt);
+    assertEquals(pos.seqIndex, 0);
+    assertEquals(pos.annotationIndex, -1);
+
+    /*
+     * cursor at bottom of first sequence
+     */
+    y = 2 * charHeight - 1;
+    evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
+            false, 0);
+    pos = testee.findMousePosition(evt);
+    assertEquals(pos.seqIndex, 0);
+    assertEquals(pos.annotationIndex, -1);
+
+    /*
+     * cursor at top of second sequence
+     */
+    y = 2 * charHeight;
+    evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
+            false, 0);
+    pos = testee.findMousePosition(evt);
+    assertEquals(pos.seqIndex, 1);
+    assertEquals(pos.annotationIndex, -1);
+
+    /*
+     * cursor at bottom of second sequence
+     */
+    y = 3 * charHeight - 1;
+    evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
+            false, 0);
+    pos = testee.findMousePosition(evt);
+    assertEquals(pos.seqIndex, 1);
+    assertEquals(pos.annotationIndex, -1);
+
+    /*
+     * cursor at bottom of last sequence
+     */
+    y = charHeight * (1 + alignmentHeight) - 1;
+    evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
+            false, 0);
+    pos = testee.findMousePosition(evt);
+    assertEquals(pos.seqIndex, alignmentHeight - 1);
+    assertEquals(pos.annotationIndex, -1);
+
+    /*
+     * cursor below sequences, in 3-pixel gap above annotations
+     */
+    y += 1;
+    evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
+            false, 0);
+    pos = testee.findMousePosition(evt);
+    assertEquals(pos.seqIndex, alignmentHeight - 1);
+    assertEquals(pos.annotationIndex, -1);
+
+    /*
+     * cursor still in the gap above annotations, now at the bottom of it
+     * method reports index of nearest sequence above  
+     */
+    y += SeqCanvas.SEQS_ANNOTATION_GAP - 1; // 3-1 = 2
+    evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
+            false, 0);
+    pos = testee.findMousePosition(evt);
+    assertEquals(pos.seqIndex, alignmentHeight - 1);
+    assertEquals(pos.annotationIndex, -1);
+
+    /*
+     * cursor at the top of the first annotation  
+     */
+    y += 1;
+    evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
+            false, 0);
+    pos = testee.findMousePosition(evt);
+    assertEquals(pos.seqIndex, alignmentHeight - 1);
+    assertEquals(pos.annotationIndex, 0); // over first annotation
+
+    /*
+     * cursor at the bottom of the first annotation  
+     */
+    y += av.getAlignment().getAlignmentAnnotation()[0].height - 1;
+    evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
+            false, 0);
+    pos = testee.findMousePosition(evt);
+    assertEquals(pos.seqIndex, alignmentHeight - 1);
+    assertEquals(pos.annotationIndex, 0);
+
+    /*
+     * cursor at the top of the second annotation  
+     */
+    y += 1;
+    evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
+            false, 0);
+    pos = testee.findMousePosition(evt);
+    assertEquals(pos.seqIndex, alignmentHeight - 1);
+    assertEquals(pos.annotationIndex, 1);
+
+    /*
+     * cursor at the bottom of the second annotation  
+     */
+    y += av.getAlignment().getAlignmentAnnotation()[1].height - 1;
+    evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
+            false, 0);
+    pos = testee.findMousePosition(evt);
+    assertEquals(pos.seqIndex, alignmentHeight - 1);
+    assertEquals(pos.annotationIndex, 1);
+
+    /*
+     * cursor at the top of the third annotation  
+     */
+    y += 1;
+    evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
+            false, 0);
+    pos = testee.findMousePosition(evt);
+    assertEquals(pos.seqIndex, alignmentHeight - 1);
+    assertEquals(pos.annotationIndex, 2);
+
+    /*
+     * cursor at the bottom of the third annotation  
+     */
+    y += av.getAlignment().getAlignmentAnnotation()[2].height - 1;
+    evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
+            false, 0);
+    pos = testee.findMousePosition(evt);
+    assertEquals(pos.seqIndex, alignmentHeight - 1);
+    assertEquals(pos.annotationIndex, 2);
+
+    /*
+     * cursor in gap between wrapped widths  
+     */
+    y += 1;
+    evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
+            false, 0);
+    pos = testee.findMousePosition(evt);
+    assertEquals(pos.seqIndex, -1);
+    assertEquals(pos.annotationIndex, -1);
+
+    /*
+     * cursor at bottom of gap between wrapped widths  
+     */
+    y += charHeight - 1;
+    evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
+            false, 0);
+    pos = testee.findMousePosition(evt);
+    assertEquals(pos.seqIndex, -1);
+    assertEquals(pos.annotationIndex, -1);
+
+    /*
+     * cursor at top of first sequence, second wrapped width  
+     */
+    y += 1;
+    evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
+            false, 0);
+    pos = testee.findMousePosition(evt);
+    assertEquals(pos.seqIndex, 0);
+    assertEquals(pos.annotationIndex, -1);
+  }
+
+  @Test(groups = "Functional")
+  public void testFindMousePosition_wrapped_scaleAbove()
+  {
+    Cache.applicationProperties.setProperty("SHOW_ANNOTATIONS", "true");
+    Cache.applicationProperties.setProperty("WRAP_ALIGNMENT", "true");
+    AlignFrame alignFrame = new FileLoader().LoadFileWaitTillLoaded(
+            "examples/uniref50.fa", DataSourceType.FILE);
+    AlignViewportI av = alignFrame.getViewport();
+    av.setScaleAboveWrapped(true);
+    av.setScaleLeftWrapped(false);
+    av.setScaleRightWrapped(false);
+    alignFrame.alignPanel.paintAlignment(false, false);
+  
+    final int charHeight = av.getCharHeight();
+    final int charWidth = av.getCharWidth();
+    final int alignmentHeight = av.getAlignment().getHeight();
+    
+    // sanity checks:
+    assertTrue(charHeight > 0);
+    assertTrue(charWidth > 0);
+    assertTrue(alignFrame.alignPanel.getSeqPanel().getWidth() > 0);
+  
+    SeqPanel testee = alignFrame.alignPanel.getSeqPanel();
+    int x = 0;
+    int y = 0;
+  
+    /*
+     * mouse at top left of wrapped panel; there is a gap of charHeight
+     * above the alignment
+     */
+    MouseEvent evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y,
+            0, 0, 0, false, 0);
+    MousePos pos = testee.findMousePosition(evt);
+    assertEquals(pos.column, 0);
+    assertEquals(pos.seqIndex, -1); // above sequences
+    assertEquals(pos.annotationIndex, -1);
+  
+    /*
+     * cursor at bottom of gap above
+     * two charHeights including scale panel
+     */
+    y = 2 * charHeight - 1;
+    evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
+            false, 0);
+    pos = testee.findMousePosition(evt);
+    assertEquals(pos.seqIndex, -1);
+    assertEquals(pos.annotationIndex, -1);
+  
+    /*
+     * cursor over top of first sequence
+     */
+    y += 1;
+    evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
+            false, 0);
+    pos = testee.findMousePosition(evt);
+    assertEquals(pos.seqIndex, 0);
+    assertEquals(pos.annotationIndex, -1);
+  
+    /*
+     * cursor at bottom of first sequence
+     */
+    y += charHeight - 1;
+    evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
+            false, 0);
+    pos = testee.findMousePosition(evt);
+    assertEquals(pos.seqIndex, 0);
+    assertEquals(pos.annotationIndex, -1);
+  
+    /*
+     * cursor at top of second sequence
+     */
+    y += 1;
+    evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
+            false, 0);
+    pos = testee.findMousePosition(evt);
+    assertEquals(pos.seqIndex, 1);
+    assertEquals(pos.annotationIndex, -1);
+  
+    /*
+     * cursor at bottom of second sequence
+     */
+    y += charHeight - 1;
+    evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
+            false, 0);
+    pos = testee.findMousePosition(evt);
+    assertEquals(pos.seqIndex, 1);
+    assertEquals(pos.annotationIndex, -1);
+  
+    /*
+     * cursor at bottom of last sequence
+     * (scale + gap + sequences)
+     */
+    y = charHeight * (2 + alignmentHeight) - 1;
+    evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
+            false, 0);
+    pos = testee.findMousePosition(evt);
+    assertEquals(pos.seqIndex, alignmentHeight - 1);
+    assertEquals(pos.annotationIndex, -1);
+  
+    /*
+     * cursor below sequences, in 3-pixel gap above annotations
+     */
+    y += 1;
+    evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
+            false, 0);
+    pos = testee.findMousePosition(evt);
+    assertEquals(pos.seqIndex, alignmentHeight - 1);
+    assertEquals(pos.annotationIndex, -1);
+  
+    /*
+     * cursor still in the gap above annotations, now at the bottom of it
+     * method reports index of nearest sequence above  
+     */
+    y += SeqCanvas.SEQS_ANNOTATION_GAP - 1; // 3-1 = 2
+    evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
+            false, 0);
+    pos = testee.findMousePosition(evt);
+    assertEquals(pos.seqIndex, alignmentHeight - 1);
+    assertEquals(pos.annotationIndex, -1);
+  
+    /*
+     * cursor at the top of the first annotation  
+     */
+    y += 1;
+    evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
+            false, 0);
+    pos = testee.findMousePosition(evt);
+    assertEquals(pos.seqIndex, alignmentHeight - 1);
+    assertEquals(pos.annotationIndex, 0); // over first annotation
+  
+    /*
+     * cursor at the bottom of the first annotation  
+     */
+    y += av.getAlignment().getAlignmentAnnotation()[0].height - 1;
+    evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
+            false, 0);
+    pos = testee.findMousePosition(evt);
+    assertEquals(pos.seqIndex, alignmentHeight - 1);
+    assertEquals(pos.annotationIndex, 0);
+  
+    /*
+     * cursor at the top of the second annotation  
+     */
+    y += 1;
+    evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
+            false, 0);
+    pos = testee.findMousePosition(evt);
+    assertEquals(pos.seqIndex, alignmentHeight - 1);
+    assertEquals(pos.annotationIndex, 1);
+  
+    /*
+     * cursor at the bottom of the second annotation  
+     */
+    y += av.getAlignment().getAlignmentAnnotation()[1].height - 1;
+    evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
+            false, 0);
+    pos = testee.findMousePosition(evt);
+    assertEquals(pos.seqIndex, alignmentHeight - 1);
+    assertEquals(pos.annotationIndex, 1);
+  
+    /*
+     * cursor at the top of the third annotation  
+     */
+    y += 1;
+    evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
+            false, 0);
+    pos = testee.findMousePosition(evt);
+    assertEquals(pos.seqIndex, alignmentHeight - 1);
+    assertEquals(pos.annotationIndex, 2);
+  
+    /*
+     * cursor at the bottom of the third annotation  
+     */
+    y += av.getAlignment().getAlignmentAnnotation()[2].height - 1;
+    evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
+            false, 0);
+    pos = testee.findMousePosition(evt);
+    assertEquals(pos.seqIndex, alignmentHeight - 1);
+    assertEquals(pos.annotationIndex, 2);
+  
+    /*
+     * cursor in gap between wrapped widths  
+     */
+    y += 1;
+    evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
+            false, 0);
+    pos = testee.findMousePosition(evt);
+    assertEquals(pos.seqIndex, -1);
+    assertEquals(pos.annotationIndex, -1);
+  
+    /*
+     * cursor at bottom of gap between wrapped widths  
+     */
+    y += charHeight - 1;
+    evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
+            false, 0);
+    pos = testee.findMousePosition(evt);
+    assertEquals(pos.seqIndex, -1);
+    assertEquals(pos.annotationIndex, -1);
+  
+    /*
+     * cursor at top of scale, second wrapped width  
+     */
+    y += 1;
+    evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
+            false, 0);
+    pos = testee.findMousePosition(evt);
+    assertEquals(pos.seqIndex, -1);
+    assertEquals(pos.annotationIndex, -1);
+
+    /*
+     * cursor at bottom of scale, second wrapped width  
+     */
+    y += charHeight - 1;
+    evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
+            false, 0);
+    pos = testee.findMousePosition(evt);
+    assertEquals(pos.seqIndex, -1);
+    assertEquals(pos.annotationIndex, -1);
+
+    /*
+     * cursor at top of first sequence, second wrapped width  
+     */
+    y += 1;
+    evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, y, 0, 0, 0,
+            false, 0);
+    pos = testee.findMousePosition(evt);
+    assertEquals(pos.seqIndex, 0);
+    assertEquals(pos.annotationIndex, -1);
+  }
+  @BeforeClass(alwaysRun = true)
+  public static void setUpBeforeClass() throws Exception
+  {
+    /*
+     * use read-only test properties file
+     */
+    Cache.loadProperties("test/jalview/io/testProps.jvprops");
+    Jalview.main(new String[] { "-nonews" });
+  }
 }