JAL-2388 Tidies and unit tests
authorkiramt <k.mourao@dundee.ac.uk>
Wed, 26 Apr 2017 09:55:48 +0000 (10:55 +0100)
committerkiramt <k.mourao@dundee.ac.uk>
Wed, 26 Apr 2017 09:55:48 +0000 (10:55 +0100)
12 files changed:
src/jalview/appletgui/OverviewCanvas.java
src/jalview/appletgui/OverviewPanel.java
src/jalview/datamodel/AllColsCollection.java
src/jalview/datamodel/VisibleColsCollection.java
src/jalview/gui/OverviewCanvas.java
src/jalview/gui/OverviewPanel.java
src/jalview/renderer/OverviewRenderer.java
src/jalview/viewmodel/OverviewDimensions.java
src/jalview/viewmodel/OverviewDimensionsHideHidden.java [moved from src/jalview/viewmodel/OverviewDimensionsAllVisible.java with 63% similarity]
src/jalview/viewmodel/OverviewDimensionsShowHidden.java [moved from src/jalview/viewmodel/OverviewDimensionsWithHidden.java with 77% similarity]
test/jalview/viewmodel/OverviewDimensionsHideHiddenTest.java [new file with mode: 0644]
test/jalview/viewmodel/OverviewDimensionsShowHiddenTest.java [moved from test/jalview/viewmodel/OverviewDimensionsTest.java with 98% similarity]

index ffba5b9..23e82df 100644 (file)
 package jalview.appletgui;
 
 import jalview.renderer.OverviewRenderer;
-import jalview.renderer.seqfeatures.FeatureColourFinder;
 import jalview.viewmodel.OverviewDimensions;
 
 import java.awt.Color;
+import java.awt.Component;
 import java.awt.Dimension;
 import java.awt.Frame;
 import java.awt.Graphics;
 import java.awt.Image;
 
-import javax.swing.JComponent;
-
-public class OverviewCanvas extends JComponent
+public class OverviewCanvas extends Component
 {
   // This is set true if the alignment view changes whilst
   // the overview is being calculated
@@ -112,26 +110,26 @@ public class OverviewCanvas extends JComponent
     {
       fr.transferSettings(transferRenderer);
     }
-    FeatureColourFinder finder = new FeatureColourFinder(fr);
 
     setPreferredSize(new Dimension(od.getWidth(), od.getHeight()));
 
-    OverviewRenderer or = new OverviewRenderer(sr, finder, od);
+    OverviewRenderer or = new OverviewRenderer(sr, fr, od);
     miniMe = nullFrame.createImage(od.getWidth(), od.getHeight());
     offscreen = nullFrame.createImage(od.getWidth(), od.getHeight());
 
     miniMe = or.draw(od.getRows(av.getAlignment()),
-            od.getColumns(av.getAlignment().getHiddenColumns()));
+            od.getColumns(av.getAlignment()));
 
     Graphics mg = miniMe.getGraphics();
 
-    // check for conservation annotation to make sure overview works for DNA too
+    // checks for conservation annotation to make sure overview works for DNA
+    // too
     if (showAnnotation)
     {
       mg.translate(0, od.getSequencesHeight());
       or.drawGraph(mg, av.getAlignmentConservationAnnotation(),
               av.getCharWidth(), od.getGraphHeight(),
-              od.getColumns(av.getAlignment().getHiddenColumns()));
+              od.getColumns(av.getAlignment()));
       mg.translate(0, -od.getSequencesHeight());
     }
     System.gc();
index 45dfbfc..8c2b54b 100755 (executable)
@@ -23,8 +23,8 @@ package jalview.appletgui;
 import jalview.util.MessageManager;
 import jalview.util.Platform;
 import jalview.viewmodel.OverviewDimensions;
-import jalview.viewmodel.OverviewDimensionsAllVisible;
-import jalview.viewmodel.OverviewDimensionsWithHidden;
+import jalview.viewmodel.OverviewDimensionsHideHidden;
+import jalview.viewmodel.OverviewDimensionsShowHidden;
 
 import java.awt.BorderLayout;
 import java.awt.Dimension;
@@ -61,7 +61,7 @@ public class OverviewPanel extends Panel implements Runnable,
     this.ap = alPanel;
     setLayout(null);
 
-    od = new OverviewDimensionsWithHidden(av.getRanges(),
+    od = new OverviewDimensionsShowHidden(av.getRanges(),
             (av.isShowAnnotation() && av.getSequenceConsensusHash() != null));
 
     oviewCanvas = new OverviewCanvas(od, av);
@@ -233,14 +233,14 @@ public class OverviewPanel extends Panel implements Runnable,
     if (showHidden)
     {
       showHidden = false;
-      od = new OverviewDimensionsAllVisible(av.getRanges(),
+      od = new OverviewDimensionsHideHidden(av.getRanges(),
               (av.isShowAnnotation() && av
                       .getAlignmentConservationAnnotation() != null));
     }
     else
     {
       showHidden = true;
-      od = new OverviewDimensionsWithHidden(av.getRanges(),
+      od = new OverviewDimensionsShowHidden(av.getRanges(),
               (av.isShowAnnotation() && av
                       .getAlignmentConservationAnnotation() != null));
     }
index 03f2fea..f84ba95 100644 (file)
@@ -31,11 +31,11 @@ public class AllColsCollection implements AlignmentColsCollectionI
 
   HiddenColumns hidden;
   
-  public AllColsCollection(int s, int e, HiddenColumns hiddenCols)
+  public AllColsCollection(int s, int e, AlignmentI al)
   {
     start = s;
     end = e;
-    hidden = hiddenCols;
+    hidden = al.getHiddenColumns();
   }
   
   @Override
index 8b6c2a4..86233ab 100644 (file)
@@ -31,11 +31,11 @@ public class VisibleColsCollection implements AlignmentColsCollectionI
 
   HiddenColumns hidden;
 
-  public VisibleColsCollection(int s, int e, HiddenColumns hiddenCols)
+  public VisibleColsCollection(int s, int e, AlignmentI al)
   {
     start = s;
     end = e;
-    hidden = hiddenCols;
+    hidden = al.getHiddenColumns();
   }
 
   @Override
index 920547f..6f9fbbf 100644 (file)
@@ -22,7 +22,6 @@ package jalview.gui;
 
 import jalview.api.AlignViewportI;
 import jalview.renderer.OverviewRenderer;
-import jalview.renderer.seqfeatures.FeatureColourFinder;
 import jalview.viewmodel.OverviewDimensions;
 
 import java.awt.Color;
@@ -118,15 +117,12 @@ public class OverviewCanvas extends JComponent
     {
       fr.transferSettings(transferRenderer);
     }
-    FeatureColourFinder finder = new FeatureColourFinder(fr);
 
-    // why do we need to set preferred size again? was set in
-    // updateOverviewImage
     setPreferredSize(new Dimension(od.getWidth(), od.getHeight()));
 
-    OverviewRenderer or = new OverviewRenderer(sr, finder, od);
+    OverviewRenderer or = new OverviewRenderer(sr, fr, od);
     miniMe = or.draw(od.getRows(av.getAlignment()),
-            od.getColumns(av.getAlignment().getHiddenColumns()));
+            od.getColumns(av.getAlignment()));
 
     Graphics mg = miniMe.getGraphics();
 
@@ -135,7 +131,7 @@ public class OverviewCanvas extends JComponent
       mg.translate(0, od.getSequencesHeight());
       or.drawGraph(mg, av.getAlignmentConservationAnnotation(),
               av.getCharWidth(), od.getGraphHeight(),
-              od.getColumns(av.getAlignment().getHiddenColumns()));
+              od.getColumns(av.getAlignment()));
       mg.translate(0, -od.getSequencesHeight());
     }
     System.gc();
index ac385c3..7750374 100755 (executable)
@@ -23,8 +23,8 @@ package jalview.gui;
 import jalview.util.MessageManager;
 import jalview.util.Platform;
 import jalview.viewmodel.OverviewDimensions;
-import jalview.viewmodel.OverviewDimensionsAllVisible;
-import jalview.viewmodel.OverviewDimensionsWithHidden;
+import jalview.viewmodel.OverviewDimensionsHideHidden;
+import jalview.viewmodel.OverviewDimensionsShowHidden;
 
 import java.awt.BorderLayout;
 import java.awt.Dimension;
@@ -71,7 +71,7 @@ public class OverviewPanel extends JPanel implements Runnable
     this.av = alPanel.av;
     this.ap = alPanel;
 
-    od = new OverviewDimensionsWithHidden(av.getRanges(),
+    od = new OverviewDimensionsShowHidden(av.getRanges(),
             (av.isShowAnnotation() && av
                     .getAlignmentConservationAnnotation() != null));
 
@@ -173,14 +173,14 @@ public class OverviewPanel extends JPanel implements Runnable
     if (showHidden)
     {
       showHidden = false;
-      od = new OverviewDimensionsAllVisible(av.getRanges(),
+      od = new OverviewDimensionsHideHidden(av.getRanges(),
               (av.isShowAnnotation() && av
                       .getAlignmentConservationAnnotation() != null));
     }
     else
     {
       showHidden = true;
-      od = new OverviewDimensionsWithHidden(av.getRanges(),
+      od = new OverviewDimensionsShowHidden(av.getRanges(),
               (av.isShowAnnotation() && av
                       .getAlignmentConservationAnnotation() != null));
     }
index 75b8198..69676c8 100644 (file)
@@ -26,6 +26,7 @@ import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.Annotation;
 import jalview.datamodel.SequenceI;
 import jalview.renderer.seqfeatures.FeatureColourFinder;
+import jalview.renderer.seqfeatures.FeatureRenderer;
 import jalview.viewmodel.OverviewDimensions;
 
 import java.awt.Color;
@@ -48,10 +49,11 @@ public class OverviewRenderer
   private float pixelsPerSeq;
 
   public OverviewRenderer(jalview.api.SequenceRenderer seqRenderer,
-          FeatureColourFinder colfinder, OverviewDimensions od)
+          FeatureRenderer fr, OverviewDimensions od)
+  // FeatureColourFinder colfinder, OverviewDimensions od)
   {
     sr = seqRenderer;
-    finder = colfinder;
+    finder = new FeatureColourFinder(fr); // colfinder;
 
     pixelsPerCol = od.getPixelsPerCol();
     pixelsPerSeq = od.getPixelsPerSeq();
index eb4a6e6..a837d53 100644 (file)
@@ -202,8 +202,7 @@ public abstract class OverviewDimensions
    *          the alignment's hidden columns
    * @return a column collection
    */
-  public abstract AlignmentColsCollectionI getColumns(
-          HiddenColumns hiddenCols);
+  public abstract AlignmentColsCollectionI getColumns(AlignmentI al);
 
   /**
    * Get the collection of rows used by this overview dimensions object
@@ -218,4 +217,23 @@ public abstract class OverviewDimensions
    * Updates overview dimensions to account for current alignment dimensions
    */
   protected abstract void resetAlignmentDims();
+
+  protected void setBoxPosition(int startRes, int endRes, int startSeq,
+          int endSeq)
+  {
+    resetAlignmentDims();
+
+    // boxX, boxY is the x,y location equivalent to startRes, startSeq
+    boxX = Math.round((float) startRes * width / alwidth);
+    boxY = Math.round((float) startSeq * sequencesHeight / alheight);
+
+    // boxWidth is the width in residues translated to pixels
+    // since the box includes both the start and end residues, add 1 to the
+    // difference
+    boxWidth = Math
+            .round((float) (endRes - startRes + 1) * width / alwidth);
+    // boxHeight is the height in sequences translated to pixels
+    boxHeight = Math.round((float) (endSeq - startSeq + 1)
+            * sequencesHeight / alheight);
+  }
 }
\ No newline at end of file
@@ -8,15 +8,15 @@ import jalview.datamodel.HiddenSequences;
 import jalview.datamodel.VisibleColsCollection;
 import jalview.datamodel.VisibleRowsCollection;
 
-public class OverviewDimensionsAllVisible extends OverviewDimensions
+public class OverviewDimensionsHideHidden extends OverviewDimensions
 {
-  private ViewportRanges alRanges;
+  private ViewportRanges ranges;
 
-  public OverviewDimensionsAllVisible(ViewportRanges ranges,
+  public OverviewDimensionsHideHidden(ViewportRanges vpranges,
           boolean showAnnotationPanel)
   {
-    super(ranges, showAnnotationPanel);
-    alRanges = ranges;
+    super(vpranges, showAnnotationPanel);
+    ranges = vpranges;
     resetAlignmentDims();
   }
 
@@ -51,7 +51,7 @@ public class OverviewDimensionsAllVisible extends OverviewDimensions
     int xAsRes = Math.round((float) x * alwidth / width);
 
     // get viewport width in residues
-    int vpwidth = alRanges.getEndRes() - alRanges.getStartRes() + 1;
+    int vpwidth = ranges.getEndRes() - ranges.getStartRes() + 1;
 
     if (xAsRes + vpwidth > alwidth)
     {
@@ -78,7 +78,7 @@ public class OverviewDimensionsAllVisible extends OverviewDimensions
 
     // get viewport height in sequences
     // add 1 because height includes both endSeq and startSeq
-    int vpheight = alRanges.getEndSeq() - alRanges.getStartSeq() + 1;
+    int vpheight = ranges.getEndSeq() - ranges.getStartSeq() + 1;
 
     if (yAsSeq + vpheight > alheight)
     {
@@ -103,49 +103,35 @@ public class OverviewDimensionsAllVisible extends OverviewDimensions
   public void setBoxPosition(HiddenSequences hiddenSeqs,
           HiddenColumns hiddenCols)
   {
-    resetAlignmentDims();
-
     // work with visible values of startRes and endRes
-    int startRes = alRanges.getStartRes();
-    int endRes = alRanges.getEndRes();
+    int startRes = ranges.getStartRes();
+    int endRes = ranges.getEndRes();
 
     // work with visible values of startSeq and endSeq
-    int startSeq = alRanges.getStartSeq();
-    int endSeq = alRanges.getEndSeq();
-
-    // boxX, boxY is the x,y location equivalent to startRes, startSeq
-    boxX = Math.round((float) startRes * width / alwidth);
-    boxY = Math.round((float) startSeq * sequencesHeight / alheight);
-
-    // boxWidth is the width in residues translated to pixels
-    // since the box includes both the start and end residues, add 1 to the
-    // difference
-    boxWidth = Math
-            .round((float) (endRes - startRes + 1) * width / alwidth);
-    // boxHeight is the height in sequences translated to pixels
-    boxHeight = Math.round((float) (endSeq - startSeq + 1)
-            * sequencesHeight / alheight);
+    int startSeq = ranges.getStartSeq();
+    int endSeq = ranges.getEndSeq();
 
+    setBoxPosition(startRes, endRes, startSeq, endSeq);
   }
 
   @Override
-  public AlignmentColsCollectionI getColumns(HiddenColumns hiddenCols)
+  public AlignmentColsCollectionI getColumns(AlignmentI al)
   {
     return new VisibleColsCollection(0,
-            alRanges.getAbsoluteAlignmentWidth() - 1, hiddenCols);
+            ranges.getAbsoluteAlignmentWidth() - 1, al);
   }
 
   @Override
   public AlignmentRowsCollectionI getRows(AlignmentI al)
   {
     return new VisibleRowsCollection(0,
-            alRanges.getAbsoluteAlignmentHeight() - 1, al);
+            ranges.getAbsoluteAlignmentHeight() - 1, al);
   }
 
   @Override
   protected void resetAlignmentDims()
   {
-    alwidth = alRanges.getVisibleAlignmentWidth();
-    alheight = alRanges.getVisibleAlignmentHeight();
+    alwidth = ranges.getVisibleAlignmentWidth();
+    alheight = ranges.getVisibleAlignmentHeight();
   }
 }
@@ -28,9 +28,9 @@ import jalview.datamodel.AllRowsCollection;
 import jalview.datamodel.HiddenColumns;
 import jalview.datamodel.HiddenSequences;
 
-public class OverviewDimensionsWithHidden extends OverviewDimensions
+public class OverviewDimensionsShowHidden extends OverviewDimensions
 {
-  private ViewportRanges alRanges;
+  private ViewportRanges ranges;
 
   /**
    * Create an OverviewDimensions object
@@ -40,11 +40,11 @@ public class OverviewDimensionsWithHidden extends OverviewDimensions
    * @param showAnnotationPanel
    *          true if the annotation panel is to be shown, false otherwise
    */
-  public OverviewDimensionsWithHidden(ViewportRanges ranges,
+  public OverviewDimensionsShowHidden(ViewportRanges vpranges,
           boolean showAnnotationPanel)
   {
-    super(ranges, showAnnotationPanel);
-    alRanges = ranges;
+    super(vpranges, showAnnotationPanel);
+    ranges = vpranges;
     resetAlignmentDims();
   }
 
@@ -93,7 +93,7 @@ public class OverviewDimensionsWithHidden extends OverviewDimensions
     int xAsRes = Math.round((float) x * alwidth / width);
 
     // get viewport width in residues
-    int vpwidth = alRanges.getEndRes() - alRanges.getStartRes() + 1;
+    int vpwidth = ranges.getEndRes() - ranges.getStartRes() + 1;
 
     // get where x should be when accounting for hidden cols
     // if x is in a hidden col region, shift to left - but we still need
@@ -128,7 +128,7 @@ public class OverviewDimensionsWithHidden extends OverviewDimensions
 
     // get viewport height in sequences
     // add 1 because height includes both endSeq and startSeq
-    int vpheight = alRanges.getEndSeq() - alRanges.getStartSeq() + 1;
+    int vpheight = ranges.getEndSeq() - ranges.getStartSeq() + 1;
 
     // get where y should be when accounting for hidden rows
     // if y is in a hidden row region, shift up - but we still need absolute
@@ -175,52 +175,37 @@ public class OverviewDimensionsWithHidden extends OverviewDimensions
   public void setBoxPosition(HiddenSequences hiddenSeqs,
           HiddenColumns hiddenCols)
   {
-    resetAlignmentDims();
-
     // work with absolute values of startRes and endRes
     int startRes = hiddenCols
-            .adjustForHiddenColumns(alRanges.getStartRes());
-    int endRes = hiddenCols.adjustForHiddenColumns(alRanges.getEndRes());
+            .adjustForHiddenColumns(ranges.getStartRes());
+    int endRes = hiddenCols.adjustForHiddenColumns(ranges.getEndRes());
 
     // work with absolute values of startSeq and endSeq
-    int startSeq = hiddenSeqs.adjustForHiddenSeqs(alRanges.getStartSeq());
-    int endSeq = hiddenSeqs.adjustForHiddenSeqs(alRanges.getEndSeq());
-
-    // boxX, boxY is the x,y location equivalent to startRes, startSeq
-    boxX = Math.round((float) startRes * width / alwidth);
-    boxY = Math.round((float) startSeq * sequencesHeight / alheight);
-
-    // boxWidth is the width in residues translated to pixels
-    // since the box includes both the start and end residues, add 1 to the
-    // difference
-    boxWidth = Math
-            .round((float) (endRes - startRes + 1) * width / alwidth);
-    // boxHeight is the height in sequences translated to pixels
-    boxHeight = Math.round((float) (endSeq - startSeq + 1)
-            * sequencesHeight
-            / alheight);
+    int startSeq = hiddenSeqs.adjustForHiddenSeqs(ranges.getStartSeq());
+    int endSeq = hiddenSeqs.adjustForHiddenSeqs(ranges.getEndSeq());
+
+    setBoxPosition(startRes, endRes, startSeq, endSeq);
   }
 
   @Override
-  public AlignmentColsCollectionI getColumns(HiddenColumns hiddenCols)
+  public AlignmentColsCollectionI getColumns(AlignmentI al)
   {
     return new AllColsCollection(0,
-            alRanges.getAbsoluteAlignmentWidth() - 1,
-            hiddenCols);
+            ranges.getAbsoluteAlignmentWidth() - 1, al);
   }
 
   @Override
   public AlignmentRowsCollectionI getRows(AlignmentI al)
   {
     return new AllRowsCollection(0,
-            alRanges.getAbsoluteAlignmentHeight() - 1,
+            ranges.getAbsoluteAlignmentHeight() - 1,
             al);
   }
 
   @Override
   protected void resetAlignmentDims()
   {
-    alwidth = alRanges.getAbsoluteAlignmentWidth();
-    alheight = alRanges.getAbsoluteAlignmentHeight();
+    alwidth = ranges.getAbsoluteAlignmentWidth();
+    alheight = ranges.getAbsoluteAlignmentHeight();
   }
 }
diff --git a/test/jalview/viewmodel/OverviewDimensionsHideHiddenTest.java b/test/jalview/viewmodel/OverviewDimensionsHideHiddenTest.java
new file mode 100644 (file)
index 0000000..2bd9c47
--- /dev/null
@@ -0,0 +1,989 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.viewmodel;
+
+import static org.testng.Assert.assertEquals;
+
+import jalview.analysis.AlignmentGenerator;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.HiddenColumns;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceCollectionI;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+
+import java.util.Hashtable;
+
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+@Test(singleThreaded = true)
+public class OverviewDimensionsHideHiddenTest
+{
+  AlignmentI al;
+
+  OverviewDimensionsHideHidden od;
+
+  // cached widths and heights
+  int boxWidth;
+  int boxHeight;
+  int viewHeight;
+  int viewWidth;
+  int alheight;
+  int alwidth;
+
+  ViewportRanges vpranges;
+
+  Hashtable<SequenceI, SequenceCollectionI> hiddenRepSequences = new Hashtable<SequenceI, SequenceCollectionI>();
+
+  HiddenColumns hiddenCols = new HiddenColumns();
+
+  @BeforeClass(alwaysRun = true)
+  public void setUpAlignment()
+  {
+    // create random alignment
+    AlignmentGenerator gen = new AlignmentGenerator(false);
+    al = gen.generate(157, 525, 123, 5, 5);
+  }
+
+  @BeforeMethod(alwaysRun = true)
+  public void setUp()
+  {
+    if (!hiddenRepSequences.isEmpty())
+    {
+      al.getHiddenSequences().showAll(hiddenRepSequences);
+    }
+    ColumnSelection colsel = new ColumnSelection();
+    hiddenCols.revealAllHiddenColumns(colsel);
+    
+    vpranges = new ViewportRanges(al);
+    vpranges.setStartRes(0);
+    vpranges.setEndRes(62);
+    vpranges.setStartSeq(0);
+    vpranges.setEndSeq(17);
+
+    viewHeight = vpranges.getEndSeq() - vpranges.getStartSeq() + 1;
+    viewWidth = vpranges.getEndRes() - vpranges.getStartRes() + 1;
+
+    HiddenColumns hiddenCols = new HiddenColumns();
+
+    od = new OverviewDimensionsHideHidden(vpranges, true);
+    // Initial box sizing - default path through code
+    od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
+
+    mouseClick(od, 0, 0);
+    moveViewport(0, 0);
+
+    // calculate with visible values
+    alheight = vpranges.getVisibleAlignmentHeight();
+    alwidth = vpranges.getVisibleAlignmentWidth();
+
+    boxWidth = Math.round((float) (vpranges.getEndRes()
+            - vpranges.getStartRes() + 1)
+            * od.getWidth() / alwidth);
+    boxHeight = Math.round((float) (vpranges.getEndSeq()
+            - vpranges.getStartSeq() + 1)
+            * od.getSequencesHeight() / alheight);
+  }
+
+  @AfterClass(alwaysRun = true)
+  public void cleanUp()
+  {
+    al = null;
+  }
+
+  /**
+   * Test that the OverviewDimensions constructor sets width and height
+   * correctly
+   */
+  @Test(groups = { "Functional" })
+  public void testConstructor()
+  {
+    SequenceI seqa = new Sequence("Seq1", "ABC");
+    SequenceI seqb = new Sequence("Seq2", "ABC");
+    SequenceI seqc = new Sequence("Seq3", "ABC");
+    SequenceI seqd = new Sequence("Seq4", "ABC");
+    SequenceI seqe = new Sequence("Seq5",
+            "ABCABCABCABCABCABCABCABCBACBACBACBAC");
+
+    int defaultGraphHeight = 20;
+    int maxWidth = 400;
+    int minWidth = 120;
+    int maxSeqHeight = 300;
+    int minSeqHeight = 40;
+
+    // test for alignment with width > height
+    SequenceI[] seqs1 = new SequenceI[] { seqa, seqb };
+    Alignment al1 = new Alignment(seqs1);
+    ViewportRanges props = new ViewportRanges(al1);
+
+    OverviewDimensions od = new OverviewDimensionsHideHidden(props, true);
+    int scaledHeight = 267;
+    assertEquals(od.getGraphHeight(), defaultGraphHeight);
+    assertEquals(od.getSequencesHeight(), scaledHeight);
+    assertEquals(od.getWidth(), maxWidth);
+    assertEquals(od.getHeight(), scaledHeight + defaultGraphHeight);
+
+    // test for alignment with width < height
+    SequenceI[] seqs2 = new SequenceI[] { seqa, seqb, seqc, seqd };
+    Alignment al2 = new Alignment(seqs2);
+    props = new ViewportRanges(al2);
+
+    od = new OverviewDimensionsHideHidden(props, true);
+    int scaledWidth = 300;
+    assertEquals(od.getGraphHeight(), defaultGraphHeight);
+    assertEquals(od.getSequencesHeight(), maxSeqHeight);
+    assertEquals(od.getWidth(), scaledWidth);
+    assertEquals(od.getHeight(), scaledWidth + defaultGraphHeight);
+
+    // test for alignment with width > height and sequence height scaled below
+    // min value
+    SequenceI[] seqs3 = new SequenceI[] { seqe };
+    Alignment al3 = new Alignment(seqs3);
+    props = new ViewportRanges(al3);
+
+    od = new OverviewDimensionsHideHidden(props, true);
+    assertEquals(od.getGraphHeight(), defaultGraphHeight);
+    assertEquals(od.getSequencesHeight(), minSeqHeight);
+    assertEquals(od.getWidth(), maxWidth);
+    assertEquals(od.getHeight(), minSeqHeight + defaultGraphHeight);
+
+    // test for alignment with width < height and width scaled below min value
+    SequenceI[] seqs4 = new SequenceI[] { seqa, seqb, seqc, seqd, seqa,
+        seqb, seqc, seqd, seqa, seqb, seqc, seqd, seqa, seqb, seqc, seqd };
+    Alignment al4 = new Alignment(seqs4);
+    props = new ViewportRanges(al4);
+
+    od = new OverviewDimensionsHideHidden(props, true);
+    assertEquals(od.getGraphHeight(), defaultGraphHeight);
+    assertEquals(od.getSequencesHeight(), maxSeqHeight);
+    assertEquals(od.getWidth(), minWidth);
+    assertEquals(od.getHeight(), maxSeqHeight + defaultGraphHeight);
+
+    Alignment al5 = new Alignment(seqs4);
+    props = new ViewportRanges(al5);
+
+    od = new OverviewDimensionsHideHidden(props, false);
+    assertEquals(od.getGraphHeight(), 0);
+    assertEquals(od.getSequencesHeight(), maxSeqHeight);
+    assertEquals(od.getWidth(), minWidth);
+    assertEquals(od.getHeight(), maxSeqHeight);
+  }
+
+  /**
+   * Test that validation after mouse adjustments to boxX and boxY sets box
+   * dimensions and scroll values correctly, when there are no hidden rows or
+   * columns.
+   */
+  @Test(groups = { "Functional" })
+  public void testSetBoxFromMouseClick()
+  {
+    od.updateViewportFromMouse(0, 0, al.getHiddenSequences(), hiddenCols);
+    assertEquals(od.getBoxX(), 0);
+    assertEquals(od.getBoxY(), 0);
+    assertEquals(od.getBoxWidth(), boxWidth);
+    assertEquals(od.getScrollCol(), 0);
+    assertEquals(od.getScrollRow(), 0);
+
+    // negative boxX value reset to 0
+    mouseClick(od, -5, 10);
+    assertEquals(od.getBoxX(), 0);
+    assertEquals(od.getBoxWidth(), boxWidth);
+    assertEquals(od.getBoxHeight(), boxHeight);
+    assertEquals(od.getScrollRow(),
+            Math.round((float) 10 * alheight / od.getSequencesHeight()));
+    assertEquals(od.getScrollCol(), 0);
+
+    // negative boxY value reset to 0
+    mouseClick(od, 6, -2);
+    assertEquals(od.getBoxY(), 0);
+    assertEquals(od.getBoxWidth(), boxWidth);
+    assertEquals(od.getBoxHeight(), boxHeight);
+    assertEquals(od.getScrollCol(),
+            Math.round((float) 6 * alwidth / od.getWidth()));
+    assertEquals(od.getScrollRow(), 0);
+
+    // overly large boxX value reset to width-boxWidth
+    mouseClick(od, 100, 6);
+    assertEquals(od.getBoxX(), od.getWidth() - od.getBoxWidth());
+    assertEquals(od.getBoxY(), 6);
+    assertEquals(od.getBoxWidth(), boxWidth);
+    assertEquals(od.getBoxHeight(), boxHeight);
+    assertEquals(od.getScrollCol(),
+            Math.round((float) od.getBoxX() * alwidth / od.getWidth()));
+    assertEquals(od.getScrollRow(),
+            Math.round((float) od.getBoxY() * alheight
+                    / od.getSequencesHeight()));
+
+    // overly large boxY value reset to sequenceHeight - boxHeight
+    mouseClick(od, 10, 520);
+    assertEquals(od.getBoxX(), 10);
+    assertEquals(od.getBoxY(), od.getSequencesHeight() - od.getBoxHeight());
+    assertEquals(od.getBoxWidth(), boxWidth);
+    assertEquals(od.getBoxHeight(), boxHeight);
+    assertEquals(od.getScrollCol(),
+            Math.round((float) od.getBoxX() * alwidth / od.getWidth()));
+
+    // here (float) od.getBoxY() * alheight / od.getSequencesHeight() = 507.5
+    // and round rounds to 508; however we get 507 working with row values
+    // hence the subtraction of 1
+    assertEquals(od.getScrollRow(),
+            Math.round((float) od.getBoxY() * alheight
+                    / od.getSequencesHeight()) - 1);
+
+    // click past end of alignment, as above
+    mouseClick(od, 3000, 5);
+    assertEquals(od.getBoxX(), od.getWidth() - od.getBoxWidth());
+    assertEquals(od.getBoxWidth(), boxWidth);
+    assertEquals(od.getBoxHeight(), boxHeight);
+    assertEquals(od.getScrollCol(),
+            Math.round((float) od.getBoxX() * alwidth / od.getWidth()));
+    assertEquals(od.getScrollRow(),
+            Math.round((float) od.getBoxY() * alheight
+                    / od.getSequencesHeight()));
+
+    // move viewport so startRes non-zero and then mouseclick
+    moveViewportH(50);
+
+    // click at viewport position
+    int oldboxx = od.getBoxX();
+    int oldboxy = od.getBoxY();
+    mouseClick(od, od.getBoxX() + 5, od.getBoxY() + 2);
+    assertEquals(od.getBoxX(), oldboxx + 5);
+    assertEquals(od.getBoxWidth(), boxWidth);
+    assertEquals(od.getBoxHeight(), boxHeight);
+    assertEquals(od.getScrollCol(),
+            Math.round((float) od.getBoxX() * alwidth / od.getWidth()));
+    assertEquals(od.getBoxY(), oldboxy + 2);
+    assertEquals(od.getScrollRow(),
+            Math.round((float) od.getBoxY() * alheight
+                    / od.getSequencesHeight()));
+
+    // click at top corner
+    mouseClick(od, 0, 0);
+    assertEquals(od.getBoxX(), 0);
+    assertEquals(od.getScrollCol(), 0);
+    assertEquals(od.getBoxY(), 0);
+    assertEquals(od.getScrollRow(), 0);
+    assertEquals(od.getBoxWidth(), boxWidth);
+    assertEquals(od.getBoxHeight(), boxHeight);
+  }
+
+  /**
+   * Test setting of the box position, when there are hidden cols at the start
+   * of the alignment
+   */
+  @Test(groups = { "Functional" })
+  public void testFromMouseWithHiddenColsAtStart()
+  {
+    od.updateViewportFromMouse(0, 0, al.getHiddenSequences(), hiddenCols);
+    assertEquals(od.getBoxX(), 0);
+    assertEquals(od.getBoxY(), 0);
+    assertEquals(od.getBoxWidth(), boxWidth);
+    assertEquals(od.getScrollCol(), 0);
+    assertEquals(od.getScrollRow(), 0);
+
+    // hide cols at start and check updated box position is correct
+    int lastHiddenCol = 30;
+    hiddenCols.hideColumns(0, lastHiddenCol);
+
+    testBoxIsAtClickPoint(0, 0);
+
+    // click to right of hidden columns, box moves to click point
+    testBoxIsAtClickPoint(40, 0);
+    assertEquals(od.getScrollRow(), 0);
+    assertEquals(od.getScrollCol(),
+            Math.round((float) 40 * alwidth / od.getWidth()));
+
+    // click to right of hidden columns such that box runs over right hand side
+    // of alignment
+    // box position is adjusted away from the edge
+    // overly large boxX value reset to width-boxWidth
+    int xpos = 100;
+    mouseClick(od, xpos, 0);
+    assertEquals(od.getBoxX(), Math.round(od.getWidth()) - boxWidth);
+    assertEquals(od.getBoxY(), 0);
+    assertEquals(od.getBoxWidth(), boxWidth);
+    assertEquals(od.getBoxHeight(), boxHeight);
+    assertEquals(od.getScrollCol(),
+            Math.round((float) od.getBoxX() * alwidth / od.getWidth()));
+    assertEquals(od.getScrollRow(), 0);
+  }
+
+  /**
+   * Test setting of the box position, when there are hidden cols in the middle
+   * of the alignment
+   */
+  @Test(groups = { "Functional" })
+  public void testFromMouseWithHiddenColsInMiddle()
+  {
+    od.updateViewportFromMouse(0, 0, al.getHiddenSequences(), hiddenCols);
+    testBoxIsAtClickPoint(0, 0);
+    assertEquals(od.getBoxX(), 0);
+    assertEquals(od.getBoxY(), 0);
+    assertEquals(od.getBoxWidth(), boxWidth);
+    assertEquals(od.getScrollCol(), 0);
+    assertEquals(od.getScrollRow(), 0);
+    
+    // hide columns 63-73, no change to box position or dimensions
+    int firstHidden = 63;
+    int lastHidden = 73;
+    hiddenCols.hideColumns(firstHidden, lastHidden);
+
+    od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
+    testBoxIsAtClickPoint(0, 0);
+    assertEquals(od.getBoxX(), 0);
+    assertEquals(od.getBoxY(), 0);
+    assertEquals(od.getBoxWidth(), boxWidth);
+    assertEquals(od.getScrollCol(), 0);
+    assertEquals(od.getScrollRow(), 0);
+
+    // move box so that it overlaps with hidden cols on one side
+    // box width, boxX and scrollCol as for unhidden case
+    int xpos = 55 - boxWidth; // 55 is position in overview approx halfway
+                              // between cols 60 and 70
+    mouseClick(od, xpos, 0);
+    testBoxIsAtClickPoint(xpos, 0);
+    assertEquals(od.getScrollCol(),
+            Math.round(xpos * alwidth / od.getWidth()));
+    assertEquals(od.getScrollRow(), 0);
+
+    // move box so that it completely covers hidden cols
+    // box width, boxX and scrollCol as for unhidden case
+    xpos = 33;
+    mouseClick(od, xpos, 0);
+    testBoxIsAtClickPoint(xpos, 0);
+    assertEquals(od.getScrollCol(),
+            Math.round((float) xpos * alwidth / od.getWidth()));
+    assertEquals(od.getScrollRow(), 0);
+
+    // move box so boxX is in hidden cols, box overhangs at right
+    // boxX and scrollCol at left of hidden area, box width unchanged
+    xpos = 50;
+    mouseClick(od, xpos, 0);
+    testBoxIsAtClickPoint(xpos, 0);
+    assertEquals(od.getScrollCol(),
+            Math.round((float) xpos * alwidth / od.getWidth()));
+    assertEquals(od.getScrollRow(), 0);
+
+    // move box so boxX is to right of hidden cols, but does not go beyond full
+    // width of alignment
+    // box width, boxX and scrollCol all as for non-hidden case
+    xpos = 75;
+    testBoxIsAtClickPoint(xpos, 0);
+    assertEquals(od.getScrollRow(), 0);
+    assertEquals(od.getScrollCol(),
+            Math.round(xpos * alwidth / od.getWidth()));
+    
+    // move box so it goes beyond full width of alignment
+    // boxX, scrollCol adjusted back, box width normal
+    xpos = 3000;
+    mouseClick(od, xpos, 0);
+    assertEquals(od.getBoxX(), Math.round(od.getWidth()) - boxWidth);
+    assertEquals(od.getBoxY(), 0);
+    assertEquals(od.getBoxWidth(), boxWidth);
+    assertEquals(od.getBoxHeight(), boxHeight);
+    assertEquals(od.getScrollCol(),
+            Math.round((float) od.getBoxX() * alwidth / od.getWidth()));
+    assertEquals(od.getScrollRow(), 0);
+
+  }
+
+  /**
+   * Test setting of the box position, when there are hidden cols at the end of
+   * the alignment
+   */
+  @Test(groups = { "Functional" })
+  public void testFromMouseWithHiddenColsAtEnd()
+  {
+    od.updateViewportFromMouse(0, 0, al.getHiddenSequences(), hiddenCols);
+    assertEquals(od.getBoxX(), 0);
+    assertEquals(od.getBoxY(), 0);
+    assertEquals(od.getBoxWidth(), boxWidth);
+    assertEquals(od.getScrollCol(), 0);
+    assertEquals(od.getScrollRow(), 0);
+
+    // hide columns 140-164, no change to box position or dimensions
+    int firstHidden = 140;
+    int lastHidden = 164;
+    hiddenCols.hideColumns(firstHidden, lastHidden);
+    od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
+    assertEquals(od.getBoxX(), 0);
+    assertEquals(od.getBoxY(), 0);
+    assertEquals(od.getBoxWidth(), boxWidth);
+    assertEquals(od.getScrollCol(), 0);
+    assertEquals(od.getScrollRow(), 0);
+
+    // click to left of hidden cols, without overlapping
+    // boxX, scrollCol and width as normal
+    int xpos = 5;
+    testBoxIsAtClickPoint(xpos, 0);
+    assertEquals(od.getScrollRow(), 0);
+    assertEquals(od.getScrollCol(),
+            Math.round((float) xpos * alwidth / od.getWidth()));
+
+    // click to left of hidden cols, with overlap
+    // boxX and scrollCol adjusted for hidden cols, width normal
+    xpos = Math.round((float) 145 * od.getWidth() / alwidth) - boxWidth;
+    mouseClick(od, xpos, 0);
+    testBoxIsAtClickPoint(xpos, 0);
+    assertEquals(od.getScrollCol(),
+            Math.round((float) xpos * alwidth / od.getWidth()));
+    assertEquals(od.getScrollRow(), 0);
+
+    // click off end of alignment
+    // boxX and scrollCol adjusted backwards, width normal
+    xpos = 3000;
+    mouseClick(od, xpos, 0);
+    assertEquals(od.getBoxX(), Math.round(od.getWidth()) - boxWidth);
+    assertEquals(od.getBoxY(), 0);
+    assertEquals(od.getBoxWidth(), boxWidth);
+    assertEquals(od.getBoxHeight(), boxHeight);
+    assertEquals(od.getScrollCol(),
+            Math.round((float) od.getBoxX() * alwidth / od.getWidth()));
+    assertEquals(od.getScrollRow(), 0);
+  }
+
+  /**
+   * Test that the box position is set correctly when set from the viewport,
+   * with no hidden rows or columns
+   */
+  @Test(groups = { "Functional" })
+  public void testSetBoxFromViewport()
+  {
+    // move viewport to start of alignment
+    moveViewport(0, 0);
+    assertEquals(od.getBoxX(), 0);
+    assertEquals(od.getBoxY(), 0);
+    assertEquals(od.getBoxWidth(), boxWidth);
+    assertEquals(od.getBoxHeight(), boxHeight);
+
+    // move viewport to right
+    moveViewportH(70);
+    assertEquals(od.getBoxX(),
+            Math.round((float) 70 * od.getWidth() / alwidth));
+    assertEquals(od.getBoxY(), 0);
+    assertEquals(od.getBoxWidth(), boxWidth);
+    assertEquals(od.getBoxHeight(), boxHeight);
+
+    // move viewport down
+    moveViewportV(100);
+    assertEquals(od.getBoxX(),
+            Math.round((float) 70 * od.getWidth() / alwidth));
+    assertEquals(od.getBoxY(),
+            Math.round(100 * od.getSequencesHeight() / alheight));
+    assertEquals(od.getBoxWidth(), boxWidth);
+    assertEquals(od.getBoxHeight(), boxHeight);
+
+    // move viewport to bottom right
+    moveViewport(98, 508);
+    assertEquals(od.getBoxX(),
+            Math.round((float) 98 * od.getWidth() / alwidth));
+    assertEquals(od.getBoxY(),
+            Math.round((float) 508 * od.getSequencesHeight() / alheight));
+    assertEquals(od.getBoxWidth(), boxWidth);
+    assertEquals(od.getBoxHeight(), boxHeight);
+  }
+
+  /**
+   * Test that the box position is set correctly when there are hidden columns
+   * at the start
+   */
+  @Test(groups = { "Functional" })
+  public void testSetBoxFromViewportHiddenColsAtStart()
+  {
+    int firstHidden = 0;
+    int lastHidden = 20;
+    hiddenCols.hideColumns(firstHidden, lastHidden);
+
+    // move viewport to start of alignment
+    moveViewport(0, 0);
+    assertEquals(od.getBoxX(), 0);
+    assertEquals(od.getBoxY(), 0);
+    assertEquals(od.getBoxWidth(), boxWidth);
+    assertEquals(od.getBoxHeight(), boxHeight);
+
+    // move viewport to end of alignment - need to make startRes by removing
+    // hidden cols because of how viewport/overview are implemented
+    moveViewport(98 - lastHidden - 1, 0);
+    assertEquals(od.getBoxX(),
+            Math.round((float) (98 - lastHidden - 1) * od.getWidth()
+                    / alwidth));
+    assertEquals(od.getBoxY(), 0);
+    assertEquals(od.getBoxWidth(), boxWidth);
+    assertEquals(od.getBoxHeight(), boxHeight);
+  }
+
+  /**
+   * Test that the box position is set correctly when there are hidden columns
+   * in the middle
+   */
+  @Test(groups = { "Functional" })
+  public void testSetBoxFromViewportHiddenColsInMiddle()
+  {
+    int firstHidden = 68;
+    int lastHidden = 78;
+    hiddenCols.hideColumns(firstHidden, lastHidden);
+
+    // move viewport before hidden columns
+    moveViewport(3, 0);
+
+    assertEquals(od.getBoxX(),
+            Math.round((float) 3 * od.getWidth() / alwidth));
+    assertEquals(od.getBoxY(), 0);
+    assertEquals(od.getBoxWidth(), boxWidth);
+    assertEquals(od.getBoxHeight(), boxHeight);
+
+    // move viewport to left of hidden columns with overlap
+    moveViewport(10, 0);
+    assertEquals(od.getBoxX(),
+            Math.round((float) 10 * od.getWidth() / alwidth));
+    assertEquals(od.getBoxY(), 0);
+    assertEquals(od.getBoxWidth(), boxWidth);
+    assertEquals(od.getBoxHeight(), boxHeight);
+
+    // move viewport to straddle hidden columns
+    moveViewport(63, 0);
+    assertEquals(od.getBoxX(),
+            Math.round((float) 63 * od.getWidth() / alwidth));
+    assertEquals(od.getBoxY(), 0);
+    assertEquals(od.getBoxWidth(), boxWidth);
+    assertEquals(od.getBoxHeight(), boxHeight);
+
+    // move viewport to right of hidden columns, no overlap
+    moveViewport(80 - (lastHidden - firstHidden + 1), 0);
+    assertEquals(od.getBoxX(),
+            Math.round((float) (80 - (lastHidden - firstHidden + 1))
+                    * od.getWidth() / alwidth));
+    assertEquals(od.getBoxY(), 0);
+    assertEquals(od.getBoxWidth(), boxWidth);
+    assertEquals(od.getBoxHeight(), boxHeight);
+
+  }
+
+  /**
+   * Test that the box position is set correctly when there are hidden columns
+   * at the end
+   */
+  @Test(groups = { "Functional" })
+  public void testSetBoxFromViewportHiddenColsAtEnd()
+  {
+    int firstHidden = 152;
+    int lastHidden = 164;
+    hiddenCols.hideColumns(firstHidden, lastHidden);
+
+    // move viewport before hidden columns
+    moveViewport(3, 0);
+    assertEquals(od.getBoxX(),
+            Math.round((float) 3 * od.getWidth() / alwidth));
+    assertEquals(od.getBoxY(), 0);
+    assertEquals(od.getBoxWidth(), boxWidth);
+    assertEquals(od.getBoxHeight(), boxHeight);
+
+    // move viewport to hidden columns
+    // viewport can't actually extend into hidden cols,
+    // so move to the far right edge of the viewport
+    moveViewport(firstHidden - viewWidth, 0);
+    assertEquals(od.getBoxX(),
+            Math.round((float) (firstHidden - viewWidth)
+                    * od.getWidth() / alwidth));
+    assertEquals(od.getBoxY(), 0);
+    assertEquals(od.getBoxWidth(), boxWidth);
+    assertEquals(od.getBoxHeight(), boxHeight);
+  }
+
+  /**
+   * Test that the box position is set correctly when there are hidden rows at
+   * the start
+   */
+  @Test(groups = { "Functional" })
+  public void testSetBoxFromViewportHiddenRowsAtStart()
+  {
+    int firstHidden = 0;
+    int lastHidden = 20;
+    hideSequences(firstHidden, lastHidden);
+
+    // calculate with visible values
+    alheight = vpranges.getVisibleAlignmentHeight();
+    alwidth = vpranges.getVisibleAlignmentWidth();
+
+    boxWidth = Math.round((float) (vpranges.getEndRes()
+            - vpranges.getStartRes() + 1)
+            * od.getWidth() / alwidth);
+    boxHeight = Math.round((float) (vpranges.getEndSeq()
+            - vpranges.getStartSeq() + 1)
+            * od.getSequencesHeight() / alheight);
+
+    // move viewport to start of alignment:
+    // box moves to below hidden rows, height remains same
+    moveViewport(0, 0);
+    assertEquals(od.getBoxX(), 0);
+    assertEquals(od.getBoxY(), 0);
+    assertEquals(od.getBoxWidth(), boxWidth);
+    assertEquals(od.getBoxHeight(), boxHeight);
+
+    // move viewport to end of alignment
+    moveViewport(0, 525 - viewHeight - lastHidden - 1);
+    assertEquals(od.getBoxX(), 0);
+    assertEquals(
+            od.getBoxY(),
+            Math.round((float) (525 - viewHeight - lastHidden - 1)
+                    * od.getSequencesHeight()
+                    / alheight));
+    assertEquals(od.getBoxWidth(), boxWidth);
+    assertEquals(od.getBoxHeight(), boxHeight);
+  }
+
+  /**
+   * Test that the box position is set correctly when there are hidden rows in
+   * the middle
+   */
+  @Test(groups = { "Functional" })
+  public void testSetBoxFromViewportHiddenRowsInMiddle()
+  {
+    int firstHidden = 200;
+    int lastHidden = 210;
+    hideSequences(firstHidden, lastHidden);
+
+    // calculate with visible values
+    alheight = vpranges.getVisibleAlignmentHeight();
+    alwidth = vpranges.getVisibleAlignmentWidth();
+
+    boxWidth = Math.round((float) (vpranges.getEndRes()
+            - vpranges.getStartRes() + 1)
+            * od.getWidth() / alwidth);
+    boxHeight = Math.round((float) (vpranges.getEndSeq()
+            - vpranges.getStartSeq() + 1)
+            * od.getSequencesHeight() / alheight);
+
+    // move viewport to start of alignment:
+    // box, height etc as in non-hidden case
+    moveViewport(0, 0);
+    assertEquals(od.getBoxX(), 0);
+    assertEquals(od.getBoxY(), 0);
+    assertEquals(od.getBoxWidth(), boxWidth);
+    assertEquals(od.getBoxHeight(), boxHeight);
+
+    // move viewport to straddle hidden rows
+    moveViewport(0, 198);
+    assertEquals(od.getBoxX(), 0);
+    assertEquals(od.getBoxY(), Math.round ((float)198 * od.getSequencesHeight()
+            / alheight));
+    assertEquals(od.getBoxWidth(), boxWidth);
+    assertEquals(od.getBoxHeight(), boxHeight);
+  }
+
+  /**
+   * Test that the box position is set correctly when there are hidden rows at
+   * the bottom
+   */
+  @Test(groups = { "Functional" })
+  public void testSetBoxFromViewportHiddenRowsAtEnd()
+  {
+    int firstHidden = 500;
+    int lastHidden = 524;
+    hideSequences(firstHidden, lastHidden);
+
+    // calculate with visible values
+    alheight = vpranges.getVisibleAlignmentHeight();
+    alwidth = vpranges.getVisibleAlignmentWidth();
+
+    boxWidth = Math.round((float) (vpranges.getEndRes()
+            - vpranges.getStartRes() + 1)
+            * od.getWidth() / alwidth);
+    boxHeight = Math.round((float) (vpranges.getEndSeq()
+            - vpranges.getStartSeq() + 1)
+            * od.getSequencesHeight() / alheight);
+
+    // move viewport to start of alignment:
+    // box, height etc as in non-hidden case
+    moveViewport(0, 0);
+    assertEquals(od.getBoxX(), 0);
+    assertEquals(od.getBoxY(), 0);
+    assertEquals(od.getBoxWidth(), boxWidth);
+    assertEquals(od.getBoxHeight(), boxHeight);
+
+    // move viewport to end of alignment
+    // viewport sits above hidden rows and does not include them
+    moveViewport(0, firstHidden - viewHeight - 1);
+    assertEquals(od.getBoxX(), 0);
+    assertEquals(
+            od.getBoxY(),
+            Math.round((float) (firstHidden - viewHeight - 1)
+                    * od.getSequencesHeight() / alheight));
+    assertEquals(od.getBoxWidth(), boxWidth);
+    assertEquals(od.getBoxHeight(), boxHeight);
+
+  }
+
+  /**
+   * Test setting of the box position, when there are hidden rows at the start
+   * of the alignment
+   */
+  @Test(groups = { "Functional" })
+  public void testFromMouseWithHiddenRowsAtStart()
+  {
+    od.updateViewportFromMouse(0, 0, al.getHiddenSequences(), hiddenCols);
+    assertEquals(od.getBoxX(), 0);
+    assertEquals(od.getBoxY(), 0);
+    assertEquals(od.getBoxHeight(), boxHeight);
+    assertEquals(od.getBoxWidth(), boxWidth);
+    assertEquals(od.getScrollCol(), 0);
+    assertEquals(od.getScrollRow(), 0);
+
+    // hide rows at start and check updated box position is correct
+    int lastHiddenRow = 30;
+    hideSequences(0, lastHiddenRow);
+
+    // calculate with visible values
+    alheight = vpranges.getVisibleAlignmentHeight();
+    alwidth = vpranges.getVisibleAlignmentWidth();
+
+    boxWidth = Math.round((float) (vpranges.getEndRes()
+            - vpranges.getStartRes() + 1)
+            * od.getWidth() / alwidth);
+    boxHeight = Math.round((float) (vpranges.getEndSeq()
+            - vpranges.getStartSeq() + 1)
+            * od.getSequencesHeight() / alheight);
+
+    od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
+    assertEquals(od.getBoxX(), 0);
+    assertEquals(od.getBoxY(), 0);
+    assertEquals(od.getBoxWidth(), boxWidth);
+    assertEquals(od.getBoxHeight(), boxHeight);
+
+    // click below hidden rows
+    mouseClick(od, 0, 150);
+    assertEquals(od.getBoxX(), 0);
+    assertEquals(od.getBoxY(), 150);
+    assertEquals(od.getBoxWidth(), boxWidth);
+    assertEquals(od.getBoxHeight(), boxHeight);
+  }
+
+  /**
+   * Test setting of the box position, when there are hidden rows at the middle
+   * of the alignment
+   */
+  @Test(groups = { "Functional" })
+  public void testFromMouseWithHiddenRowsInMiddle()
+  {
+    od.updateViewportFromMouse(0, 0, al.getHiddenSequences(), hiddenCols);
+
+    assertEquals(od.getBoxX(), 0);
+    assertEquals(od.getBoxY(), 0);
+    assertEquals(od.getBoxWidth(), boxWidth);
+    assertEquals(od.getBoxHeight(), boxHeight);
+    assertEquals(od.getScrollCol(), 0);
+    assertEquals(od.getScrollRow(), 0);
+
+    // hide rows in middle and check updated box position is correct
+    // no changes
+    int firstHiddenRow = 50;
+    int lastHiddenRow = 54;
+    hideSequences(firstHiddenRow, lastHiddenRow);
+
+    // calculate with visible values
+    alheight = vpranges.getVisibleAlignmentHeight();
+    alwidth = vpranges.getVisibleAlignmentWidth();
+
+    boxWidth = Math.round((float) (vpranges.getEndRes()
+            - vpranges.getStartRes() + 1)
+            * od.getWidth() / alwidth);
+    boxHeight = Math.round((float) (vpranges.getEndSeq()
+            - vpranges.getStartSeq() + 1)
+            * od.getSequencesHeight() / alheight);
+
+    od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
+
+    assertEquals(od.getBoxX(), 0);
+    assertEquals(od.getBoxY(), 0);
+    assertEquals(od.getBoxWidth(), boxWidth);
+    assertEquals(od.getBoxHeight(), boxHeight);
+
+    // click above hidden rows, so that box overlaps
+    int ypos = 35; // column value in residues
+    mouseClick(od, 0,
+            Math.round((float) ypos * od.getSequencesHeight() / alheight));
+    assertEquals(od.getBoxX(), 0);
+    assertEquals(od.getBoxY(),
+            Math.round((float) ypos * od.getSequencesHeight() / alheight));
+    assertEquals(od.getBoxWidth(), boxWidth);
+    assertEquals(od.getBoxHeight(), boxHeight);
+
+    // click so that box straddles hidden rows
+    ypos = 44; // column value in residues
+    mouseClick(od, 0,
+            Math.round((float) ypos * od.getSequencesHeight() / alheight));
+    assertEquals(od.getBoxX(), 0);
+    assertEquals(od.getBoxY(),
+            Math.round((float) ypos * od.getSequencesHeight() / alheight));
+    assertEquals(od.getBoxWidth(), boxWidth);
+    assertEquals(od.getBoxHeight(), boxHeight);
+  }
+
+  /**
+   * Test setting of the box position, when there are hidden rows at the end of
+   * the alignment
+   */
+  @Test(groups = { "Functional" })
+  public void testFromMouseWithHiddenRowsAtEnd()
+  {
+    od.updateViewportFromMouse(0, 0, al.getHiddenSequences(), hiddenCols);
+    assertEquals(od.getBoxX(), 0);
+    assertEquals(od.getBoxY(), 0);
+    assertEquals(od.getBoxWidth(), boxWidth);
+    assertEquals(od.getBoxHeight(), boxHeight);
+    assertEquals(od.getScrollCol(), 0);
+    assertEquals(od.getScrollRow(), 0);
+
+    // hide rows at end and check updated box position is correct
+    // no changes
+    int firstHidden = 500;
+    int lastHidden = 524;
+    hideSequences(firstHidden, lastHidden);
+
+    // calculate with visible values
+    alheight = vpranges.getVisibleAlignmentHeight();
+    alwidth = vpranges.getVisibleAlignmentWidth();
+
+    boxWidth = Math.round((float) (vpranges.getEndRes()
+            - vpranges.getStartRes() + 1)
+            * od.getWidth() / alwidth);
+    boxHeight = Math.round((float) (vpranges.getEndSeq()
+            - vpranges.getStartSeq() + 1)
+            * od.getSequencesHeight() / alheight);
+
+    od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
+    assertEquals(od.getBoxX(), 0);
+    assertEquals(od.getBoxY(), 0);
+    assertEquals(od.getBoxWidth(), boxWidth);
+    assertEquals(od.getBoxHeight(), boxHeight);
+
+    // click above hidden rows
+    int ypos = 40; // row 40
+    mouseClick(od, 0,
+            Math.round((float) ypos * od.getSequencesHeight() / alheight));
+    assertEquals(od.getBoxX(), 0);
+    assertEquals(od.getBoxY(),
+            Math.round((float) ypos * od.getSequencesHeight() / alheight));
+    assertEquals(od.getBoxWidth(), boxWidth);
+    assertEquals(od.getBoxHeight(), boxHeight);
+
+    // click above hidden rows so box overlaps
+    // boxY, boxHeight remains same
+    ypos = 497; // row 497
+    mouseClick(od, 0,
+            Math.round((float) ypos * od.getSequencesHeight() / alheight));
+    assertEquals(od.getBoxX(), 0);
+    assertEquals(
+            od.getBoxY(),
+            Math.round((float) firstHidden * od.getSequencesHeight()
+                    / alheight)
+                    - boxHeight);
+    assertEquals(od.getBoxWidth(), boxWidth);
+    assertEquals(od.getBoxHeight(), boxHeight);
+  }
+
+  /*
+   * Move viewport horizontally: startRes + previous width gives new horizontal extent. Vertical extent stays the same.
+   */
+  private void moveViewportH(int startRes)
+  {
+    vpranges.setStartRes(startRes);
+    vpranges.setEndRes(startRes + viewWidth - 1);
+    od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
+  }
+
+  /*
+   * Move viewport vertically: startSeq and endSeq give new vertical extent. Horizontal extent stays the same.
+   */
+  private void moveViewportV(int startSeq)
+  {
+    vpranges.setStartSeq(startSeq);
+    vpranges.setEndSeq(startSeq + viewHeight - 1);
+    od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
+  }
+
+  /*
+   * Move viewport horizontally and vertically.
+   */
+  private void moveViewport(int startRes, int startSeq)
+  {
+    vpranges.setStartRes(startRes);
+    vpranges.setEndRes(startRes + viewWidth - 1);
+    vpranges.setStartSeq(startSeq);
+    vpranges.setEndSeq(startSeq + viewHeight - 1);
+    od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
+  }
+
+  /*
+   * Mouse click as position x,y in overview window
+   */
+  private void mouseClick(OverviewDimensionsHideHidden od, int x, int y)
+  {
+    od.updateViewportFromMouse(x, y, al.getHiddenSequences(), hiddenCols);
+
+    // updates require an OverviewPanel to exist which it doesn't here
+    // so call setBoxPosition() as it would be called by the AlignmentPanel
+    // normally
+
+    vpranges.setStartRes(od.getScrollCol());
+    vpranges.setEndRes(od.getScrollCol() + viewWidth - 1);
+    vpranges.setStartSeq(od.getScrollRow());
+    vpranges.setEndSeq(od.getScrollRow() + viewHeight - 1);
+    od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
+  }
+  
+  /*
+   * Test that the box is positioned with the top left corner at xpos, ypos
+   * and with the original width and height
+   */
+  private void testBoxIsAtClickPoint(int xpos, int ypos)
+  {
+    mouseClick(od, xpos, ypos);
+    assertEquals(od.getBoxX(), xpos);
+    assertEquals(od.getBoxY(), ypos);
+    assertEquals(od.getBoxWidth(), boxWidth);
+    assertEquals(od.getBoxHeight(), boxHeight);
+
+  }
+
+  /*
+   * Hide sequences between start and end
+   */
+  private void hideSequences(int start, int end)
+  {
+    SequenceI[] allseqs = al.getSequencesArray();
+    SequenceGroup theseSeqs = new SequenceGroup();
+    
+    for (int i = start; i <= end; i++)
+    {
+      theseSeqs.addSequence(allseqs[i], false);
+      al.getHiddenSequences().hideSequence(allseqs[i]);
+    }
+
+    hiddenRepSequences.put(allseqs[start], theseSeqs);
+  }
+}
@@ -40,10 +40,10 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 @Test(singleThreaded = true)
-public class OverviewDimensionsTest
+public class OverviewDimensionsShowHiddenTest
 {
   AlignmentI al;
-  OverviewDimensionsWithHidden od;
+  OverviewDimensionsShowHidden od;
 
   // cached widths and heights
   int boxWidth;
@@ -60,7 +60,7 @@ public class OverviewDimensionsTest
   HiddenColumns hiddenCols = new HiddenColumns();
 
   @BeforeClass(alwaysRun = true)
-  public void setUpJvOptionPane()
+  public void setUpAlignment()
   {
     // create random alignment
     AlignmentGenerator gen = new AlignmentGenerator(false);
@@ -88,7 +88,7 @@ public class OverviewDimensionsTest
 
     HiddenColumns hiddenCols = new HiddenColumns();
 
-    od = new OverviewDimensionsWithHidden(vpranges, true);
+    od = new OverviewDimensionsShowHidden(vpranges, true);
     // Initial box sizing - default path through code
     od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
 
@@ -138,7 +138,7 @@ public class OverviewDimensionsTest
     Alignment al1 = new Alignment(seqs1);
     ViewportRanges props = new ViewportRanges(al1);
 
-    OverviewDimensions od = new OverviewDimensionsWithHidden(props, true);
+    OverviewDimensions od = new OverviewDimensionsShowHidden(props, true);
     int scaledHeight = 267;
     assertEquals(od.getGraphHeight(), defaultGraphHeight);
     assertEquals(od.getSequencesHeight(), scaledHeight);
@@ -150,7 +150,7 @@ public class OverviewDimensionsTest
     Alignment al2 = new Alignment(seqs2);
     props = new ViewportRanges(al2);
 
-    od = new OverviewDimensionsWithHidden(props, true);
+    od = new OverviewDimensionsShowHidden(props, true);
     int scaledWidth = 300;
     assertEquals(od.getGraphHeight(), defaultGraphHeight);
     assertEquals(od.getSequencesHeight(), maxSeqHeight);
@@ -163,7 +163,7 @@ public class OverviewDimensionsTest
     Alignment al3 = new Alignment(seqs3);
     props = new ViewportRanges(al3);
 
-    od = new OverviewDimensionsWithHidden(props, true);
+    od = new OverviewDimensionsShowHidden(props, true);
     assertEquals(od.getGraphHeight(), defaultGraphHeight);
     assertEquals(od.getSequencesHeight(), minSeqHeight);
     assertEquals(od.getWidth(), maxWidth);
@@ -175,7 +175,7 @@ public class OverviewDimensionsTest
     Alignment al4 = new Alignment(seqs4);
     props = new ViewportRanges(al4);
 
-    od = new OverviewDimensionsWithHidden(props, true);
+    od = new OverviewDimensionsShowHidden(props, true);
     assertEquals(od.getGraphHeight(), defaultGraphHeight);
     assertEquals(od.getSequencesHeight(), maxSeqHeight);
     assertEquals(od.getWidth(), minWidth);
@@ -184,7 +184,7 @@ public class OverviewDimensionsTest
     Alignment al5 = new Alignment(seqs4);
     props = new ViewportRanges(al5);
 
-    od = new OverviewDimensionsWithHidden(props, false);
+    od = new OverviewDimensionsShowHidden(props, false);
     assertEquals(od.getGraphHeight(), 0);
     assertEquals(od.getSequencesHeight(), maxSeqHeight);
     assertEquals(od.getWidth(), minWidth);
@@ -616,9 +616,7 @@ public class OverviewDimensionsTest
     assertEquals(od.getBoxX(),
             Math.round((float) 3 * od.getWidth() / alwidth));
     assertEquals(od.getBoxY(), 0);
-    System.out.println(od.getBoxWidth());
     assertEquals(od.getBoxWidth(), boxWidth);
-    System.out.println(od.getBoxWidth());
     assertEquals(od.getBoxHeight(), boxHeight);
 
     // move viewport to left of hidden columns with overlap
@@ -983,7 +981,7 @@ public class OverviewDimensionsTest
   /*
    * Mouse click as position x,y in overview window
    */
-  private void mouseClick(OverviewDimensionsWithHidden od, int x, int y)
+  private void mouseClick(OverviewDimensionsShowHidden od, int x, int y)
   {
     od.updateViewportFromMouse(x, y, al.getHiddenSequences(), hiddenCols);