Merge branch 'develop' into JAL-1705_trialMerge
[jalview.git] / src / jalview / viewmodel / AlignmentViewport.java
index 2d9eb16..ab9740c 100644 (file)
@@ -65,7 +65,6 @@ import java.util.HashMap;
 import java.util.Hashtable;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
 /**
  * base class holding visualization and analysis attributes and common logic for
@@ -95,6 +94,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @param name
    * @see jalview.api.ViewStyleI#setFontName(java.lang.String)
    */
+  @Override
   public void setFontName(String name)
   {
     viewStyle.setFontName(name);
@@ -104,6 +104,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @param style
    * @see jalview.api.ViewStyleI#setFontStyle(int)
    */
+  @Override
   public void setFontStyle(int style)
   {
     viewStyle.setFontStyle(style);
@@ -113,6 +114,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @param size
    * @see jalview.api.ViewStyleI#setFontSize(int)
    */
+  @Override
   public void setFontSize(int size)
   {
     viewStyle.setFontSize(size);
@@ -122,6 +124,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getFontStyle()
    */
+  @Override
   public int getFontStyle()
   {
     return viewStyle.getFontStyle();
@@ -131,6 +134,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getFontName()
    */
+  @Override
   public String getFontName()
   {
     return viewStyle.getFontName();
@@ -140,6 +144,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getFontSize()
    */
+  @Override
   public int getFontSize()
   {
     return viewStyle.getFontSize();
@@ -149,6 +154,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @param upperCasebold
    * @see jalview.api.ViewStyleI#setUpperCasebold(boolean)
    */
+  @Override
   public void setUpperCasebold(boolean upperCasebold)
   {
     viewStyle.setUpperCasebold(upperCasebold);
@@ -158,6 +164,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#isUpperCasebold()
    */
+  @Override
   public boolean isUpperCasebold()
   {
     return viewStyle.isUpperCasebold();
@@ -167,6 +174,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#isSeqNameItalics()
    */
+  @Override
   public boolean isSeqNameItalics()
   {
     return viewStyle.isSeqNameItalics();
@@ -176,6 +184,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @param colourByReferenceSeq
    * @see jalview.api.ViewStyleI#setColourByReferenceSeq(boolean)
    */
+  @Override
   public void setColourByReferenceSeq(boolean colourByReferenceSeq)
   {
     viewStyle.setColourByReferenceSeq(colourByReferenceSeq);
@@ -185,6 +194,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @param b
    * @see jalview.api.ViewStyleI#setColourAppliesToAllGroups(boolean)
    */
+  @Override
   public void setColourAppliesToAllGroups(boolean b)
   {
     viewStyle.setColourAppliesToAllGroups(b);
@@ -194,6 +204,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getColourAppliesToAllGroups()
    */
+  @Override
   public boolean getColourAppliesToAllGroups()
   {
     return viewStyle.getColourAppliesToAllGroups();
@@ -203,6 +214,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getAbovePIDThreshold()
    */
+  @Override
   public boolean getAbovePIDThreshold()
   {
     return viewStyle.getAbovePIDThreshold();
@@ -212,6 +224,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @param inc
    * @see jalview.api.ViewStyleI#setIncrement(int)
    */
+  @Override
   public void setIncrement(int inc)
   {
     viewStyle.setIncrement(inc);
@@ -221,6 +234,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getIncrement()
    */
+  @Override
   public int getIncrement()
   {
     return viewStyle.getIncrement();
@@ -230,6 +244,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @param b
    * @see jalview.api.ViewStyleI#setConservationSelected(boolean)
    */
+  @Override
   public void setConservationSelected(boolean b)
   {
     viewStyle.setConservationSelected(b);
@@ -239,6 +254,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @param show
    * @see jalview.api.ViewStyleI#setShowHiddenMarkers(boolean)
    */
+  @Override
   public void setShowHiddenMarkers(boolean show)
   {
     viewStyle.setShowHiddenMarkers(show);
@@ -248,6 +264,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getShowHiddenMarkers()
    */
+  @Override
   public boolean getShowHiddenMarkers()
   {
     return viewStyle.getShowHiddenMarkers();
@@ -257,6 +274,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @param b
    * @see jalview.api.ViewStyleI#setScaleRightWrapped(boolean)
    */
+  @Override
   public void setScaleRightWrapped(boolean b)
   {
     viewStyle.setScaleRightWrapped(b);
@@ -266,6 +284,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @param b
    * @see jalview.api.ViewStyleI#setScaleLeftWrapped(boolean)
    */
+  @Override
   public void setScaleLeftWrapped(boolean b)
   {
     viewStyle.setScaleLeftWrapped(b);
@@ -275,6 +294,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @param b
    * @see jalview.api.ViewStyleI#setScaleAboveWrapped(boolean)
    */
+  @Override
   public void setScaleAboveWrapped(boolean b)
   {
     viewStyle.setScaleAboveWrapped(b);
@@ -284,6 +304,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getScaleLeftWrapped()
    */
+  @Override
   public boolean getScaleLeftWrapped()
   {
     return viewStyle.getScaleLeftWrapped();
@@ -293,6 +314,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getScaleAboveWrapped()
    */
+  @Override
   public boolean getScaleAboveWrapped()
   {
     return viewStyle.getScaleAboveWrapped();
@@ -302,6 +324,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getScaleRightWrapped()
    */
+  @Override
   public boolean getScaleRightWrapped()
   {
     return viewStyle.getScaleRightWrapped();
@@ -311,6 +334,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @param b
    * @see jalview.api.ViewStyleI#setAbovePIDThreshold(boolean)
    */
+  @Override
   public void setAbovePIDThreshold(boolean b)
   {
     viewStyle.setAbovePIDThreshold(b);
@@ -320,6 +344,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @param thresh
    * @see jalview.api.ViewStyleI#setThreshold(int)
    */
+  @Override
   public void setThreshold(int thresh)
   {
     viewStyle.setThreshold(thresh);
@@ -329,6 +354,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getThreshold()
    */
+  @Override
   public int getThreshold()
   {
     return viewStyle.getThreshold();
@@ -338,6 +364,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getShowJVSuffix()
    */
+  @Override
   public boolean getShowJVSuffix()
   {
     return viewStyle.getShowJVSuffix();
@@ -347,6 +374,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @param b
    * @see jalview.api.ViewStyleI#setShowJVSuffix(boolean)
    */
+  @Override
   public void setShowJVSuffix(boolean b)
   {
     viewStyle.setShowJVSuffix(b);
@@ -356,6 +384,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @param state
    * @see jalview.api.ViewStyleI#setWrapAlignment(boolean)
    */
+  @Override
   public void setWrapAlignment(boolean state)
   {
     viewStyle.setWrapAlignment(state);
@@ -365,6 +394,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @param state
    * @see jalview.api.ViewStyleI#setShowText(boolean)
    */
+  @Override
   public void setShowText(boolean state)
   {
     viewStyle.setShowText(state);
@@ -374,6 +404,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @param state
    * @see jalview.api.ViewStyleI#setRenderGaps(boolean)
    */
+  @Override
   public void setRenderGaps(boolean state)
   {
     viewStyle.setRenderGaps(state);
@@ -383,6 +414,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getColourText()
    */
+  @Override
   public boolean getColourText()
   {
     return viewStyle.getColourText();
@@ -392,6 +424,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @param state
    * @see jalview.api.ViewStyleI#setColourText(boolean)
    */
+  @Override
   public void setColourText(boolean state)
   {
     viewStyle.setColourText(state);
@@ -401,6 +434,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getWrapAlignment()
    */
+  @Override
   public boolean getWrapAlignment()
   {
     return viewStyle.getWrapAlignment();
@@ -410,6 +444,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getShowText()
    */
+  @Override
   public boolean getShowText()
   {
     return viewStyle.getShowText();
@@ -419,6 +454,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getWrappedWidth()
    */
+  @Override
   public int getWrappedWidth()
   {
     return viewStyle.getWrappedWidth();
@@ -428,6 +464,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @param w
    * @see jalview.api.ViewStyleI#setWrappedWidth(int)
    */
+  @Override
   public void setWrappedWidth(int w)
   {
     viewStyle.setWrappedWidth(w);
@@ -437,6 +474,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getCharHeight()
    */
+  @Override
   public int getCharHeight()
   {
     return viewStyle.getCharHeight();
@@ -446,6 +484,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @param h
    * @see jalview.api.ViewStyleI#setCharHeight(int)
    */
+  @Override
   public void setCharHeight(int h)
   {
     viewStyle.setCharHeight(h);
@@ -455,6 +494,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getCharWidth()
    */
+  @Override
   public int getCharWidth()
   {
     return viewStyle.getCharWidth();
@@ -464,6 +504,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @param w
    * @see jalview.api.ViewStyleI#setCharWidth(int)
    */
+  @Override
   public void setCharWidth(int w)
   {
     viewStyle.setCharWidth(w);
@@ -473,6 +514,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getShowBoxes()
    */
+  @Override
   public boolean getShowBoxes()
   {
     return viewStyle.getShowBoxes();
@@ -482,6 +524,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getShowUnconserved()
    */
+  @Override
   public boolean getShowUnconserved()
   {
     return viewStyle.getShowUnconserved();
@@ -491,6 +534,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @param showunconserved
    * @see jalview.api.ViewStyleI#setShowUnconserved(boolean)
    */
+  @Override
   public void setShowUnconserved(boolean showunconserved)
   {
     viewStyle.setShowUnconserved(showunconserved);
@@ -500,6 +544,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @param default1
    * @see jalview.api.ViewStyleI#setSeqNameItalics(boolean)
    */
+  @Override
   public void setSeqNameItalics(boolean default1)
   {
     viewStyle.setSeqNameItalics(default1);
@@ -540,7 +585,6 @@ public abstract class AlignmentViewport implements AlignViewportI,
     return isDataset;
   }
 
-
   private Map<SequenceI, SequenceCollectionI> hiddenRepSequences;
 
   protected ColumnSelection colSel = new ColumnSelection();
@@ -553,12 +597,11 @@ public abstract class AlignmentViewport implements AlignViewportI,
 
   protected ColourSchemeI globalColourScheme = null;
 
-
   @Override
   public void setGlobalColourScheme(ColourSchemeI cs)
   {
     // TODO: logic refactored from AlignFrame changeColour -
-    // autorecalc stuff should be changed to rely on the worker system
+    // TODO: autorecalc stuff should be changed to rely on the worker system
     // check to see if we should implement a changeColour(cs) method rather than
     // put th logic in here
     // - means that caller decides if they want to just modify state and defer
@@ -630,7 +673,6 @@ public abstract class AlignmentViewport implements AlignViewportI,
         }
       }
     }
-
   }
 
   @Override
@@ -794,15 +836,26 @@ public abstract class AlignmentViewport implements AlignViewportI,
 
     /*
      * A separate thread to compute cDNA consensus for a protein alignment
+     * which has mapping to cDNA
      */
     final AlignmentI al = this.getAlignment();
     if (!al.isNucleotide() && al.getCodonFrames() != null
             && !al.getCodonFrames().isEmpty())
     {
-      if (calculator
-              .getRegisteredWorkersOfClass(ComplementConsensusThread.class) == null)
+      /*
+       * fudge - check first mapping is protein-to-nucleotide
+       * (we don't want to do this for protein-to-protein)
+       */
+      AlignedCodonFrame mapping = al.getCodonFrames().iterator().next();
+      // TODO hold mapping type e.g. dna-to-protein in AlignedCodonFrame?
+      if (mapping.getdnaToProt()[0].getFromRatio() == 3)
       {
-        calculator.registerWorker(new ComplementConsensusThread(this, ap));
+        if (calculator
+                .getRegisteredWorkersOfClass(ComplementConsensusThread.class) == null)
+        {
+          calculator
+                  .registerWorker(new ComplementConsensusThread(this, ap));
+        }
       }
     }
   }
@@ -979,7 +1032,6 @@ public abstract class AlignmentViewport implements AlignViewportI,
    */
   public boolean sortByTree = false;
 
-
   /**
    * 
    * 
@@ -1055,17 +1107,10 @@ public abstract class AlignmentViewport implements AlignViewportI,
     // hasHiddenColumns = colSel.hasHiddenColumns();
   }
 
-  protected boolean hasHiddenRows = false;
-
   @Override
   public boolean hasHiddenRows()
   {
-    return hasHiddenRows;
-  }
-
-  public void setHasHiddenRows(boolean hasHiddenRows)
-  {
-    this.hasHiddenRows = hasHiddenRows;
+    return alignment.getHiddenSequences().getSize() > 0;
   }
 
   protected SequenceGroup selectionGroup;
@@ -1158,7 +1203,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    */
   public boolean isColSelChanged(boolean b)
   {
-    int hc = (colSel == null || colSel.size() == 0) ? -1 : colSel
+    int hc = (colSel == null || colSel.isEmpty()) ? -1 : colSel
             .hashCode();
     if (hc != -1 && hc != colselhash)
     {
@@ -1253,7 +1298,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
 
   public void hideSelectedColumns()
   {
-    if (colSel.size() < 1)
+    if (colSel.isEmpty())
     {
       return;
     }
@@ -1304,7 +1349,6 @@ public abstract class AlignmentViewport implements AlignViewportI,
         setSequenceAnnotationsVisible(seq, true);
       }
 
-      hasHiddenRows = false;
       hiddenRepSequences = null;
 
       firePropertyChange("alignment", null, alignment.getSequences());
@@ -1317,8 +1361,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
   public void showSequence(int index)
   {
     List<SequenceI> tmp = alignment.getHiddenSequences().showSequence(
-            index,
-            hiddenRepSequences);
+            index, hiddenRepSequences);
     if (tmp.size() > 0)
     {
       if (selectionGroup == null)
@@ -1332,12 +1375,6 @@ public abstract class AlignmentViewport implements AlignViewportI,
         selectionGroup.addSequence(seq, false);
         setSequenceAnnotationsVisible(seq, true);
       }
-      // JBPNote: refactor: only update flag if we modified visiblity (used to
-      // do this regardless)
-      if (alignment.getHiddenSequences().getSize() < 1)
-      {
-        hasHiddenRows = false;
-      }
       firePropertyChange("alignment", null, alignment.getSequences());
       sendSelection();
     }
@@ -1366,7 +1403,6 @@ public abstract class AlignmentViewport implements AlignViewportI,
         alignment.getHiddenSequences().hideSequence(seq[i]);
         setSequenceAnnotationsVisible(seq[i], false);
       }
-      hasHiddenRows = true;
       firePropertyChange("alignment", null, alignment.getSequences());
     }
   }
@@ -1398,7 +1434,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
 
     if (hiddenRepSequences == null)
     {
-      hiddenRepSequences = new Hashtable();
+      hiddenRepSequences = new Hashtable<SequenceI, SequenceCollectionI>();
     }
 
     hiddenRepSequences.put(repSequence, sg);
@@ -1426,8 +1462,9 @@ public abstract class AlignmentViewport implements AlignViewportI,
 
   public boolean isHiddenRepSequence(SequenceI seq)
   {
-    return alignment.getSeqrep()==seq || (hiddenRepSequences != null
-            && hiddenRepSequences.containsKey(seq));
+    return alignment.getSeqrep() == seq
+            || (hiddenRepSequences != null && hiddenRepSequences
+                    .containsKey(seq));
   }
 
   public SequenceGroup getRepresentedSequences(SequenceI seq)
@@ -1449,7 +1486,6 @@ public abstract class AlignmentViewport implements AlignViewportI,
     colSel.invertColumnSelection(0, alignment.getWidth());
   }
 
-
   @Override
   public SequenceI[] getSelectionAsNewSequence()
   {
@@ -1477,7 +1513,6 @@ public abstract class AlignmentViewport implements AlignViewportI,
     return sequences;
   }
 
-
   @Override
   public SequenceI[] getSequenceSelection()
   {
@@ -1493,16 +1528,13 @@ public abstract class AlignmentViewport implements AlignViewportI,
     return sequences;
   }
 
-
   @Override
-  public CigarArray getViewAsCigars(
-          boolean selectedRegionOnly)
+  public CigarArray getViewAsCigars(boolean selectedRegionOnly)
   {
     return new CigarArray(alignment, colSel,
             (selectedRegionOnly ? selectionGroup : null));
   }
 
-
   @Override
   public jalview.datamodel.AlignmentView getAlignmentView(
           boolean selectedOnly)
@@ -1510,7 +1542,6 @@ public abstract class AlignmentViewport implements AlignViewportI,
     return getAlignmentView(selectedOnly, false);
   }
 
-
   @Override
   public jalview.datamodel.AlignmentView getAlignmentView(
           boolean selectedOnly, boolean markGroups)
@@ -1520,7 +1551,6 @@ public abstract class AlignmentViewport implements AlignViewportI,
             markGroups);
   }
 
-
   @Override
   public String[] getViewAsString(boolean selectedRegionOnly)
   {
@@ -1558,7 +1588,6 @@ public abstract class AlignmentViewport implements AlignViewportI,
     return selection;
   }
 
-
   @Override
   public List<int[]> getVisibleRegionBoundaries(int min, int max)
   {
@@ -1586,8 +1615,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
         }
       }
 
-      regions.add(new int[]
-      { start, end });
+      regions.add(new int[] { start, end });
 
       if (colSel != null && colSel.hasHiddenColumns())
       {
@@ -1602,19 +1630,23 @@ public abstract class AlignmentViewport implements AlignViewportI,
   }
 
   @Override
-  public List<AlignmentAnnotation> getVisibleAlignmentAnnotation(boolean selectedOnly)
+  public List<AlignmentAnnotation> getVisibleAlignmentAnnotation(
+          boolean selectedOnly)
   {
     ArrayList<AlignmentAnnotation> ala = new ArrayList<AlignmentAnnotation>();
     AlignmentAnnotation[] aa;
-    if ((aa=alignment.getAlignmentAnnotation())!=null)
+    if ((aa = alignment.getAlignmentAnnotation()) != null)
     {
-      for (AlignmentAnnotation annot:aa)
+      for (AlignmentAnnotation annot : aa)
       {
         AlignmentAnnotation clone = new AlignmentAnnotation(annot);
-        if (selectedOnly && selectionGroup!=null)
+        if (selectedOnly && selectionGroup != null)
+        {
+          colSel.makeVisibleAnnotation(selectionGroup.getStartRes(),
+                  selectionGroup.getEndRes(), clone);
+        }
+        else
         {
-          colSel.makeVisibleAnnotation(selectionGroup.getStartRes(), selectionGroup.getEndRes(),clone);
-        } else {
           colSel.makeVisibleAnnotation(clone);
         }
         ala.add(clone);
@@ -1623,14 +1655,12 @@ public abstract class AlignmentViewport implements AlignViewportI,
     return ala;
   }
 
-
   @Override
   public boolean isPadGaps()
   {
     return padGaps;
   }
 
-
   @Override
   public void setPadGaps(boolean padGaps)
   {
@@ -1749,14 +1779,20 @@ public abstract class AlignmentViewport implements AlignViewportI,
   {
     if (!alignment.isNucleotide())
     {
-      final Set<AlignedCodonFrame> codonMappings = alignment
+      final List<AlignedCodonFrame> codonMappings = alignment
               .getCodonFrames();
       if (codonMappings != null && !codonMappings.isEmpty())
       {
-        complementConsensus = new AlignmentAnnotation("cDNA Consensus",
-                "PID for cDNA", new Annotation[1], 0f, 100f,
-                AlignmentAnnotation.BAR_GRAPH);
-        initConsensus(complementConsensus);
+        // fudge: check mappings are not protein-to-protein
+        // TODO: nicer
+        AlignedCodonFrame mapping = codonMappings.iterator().next();
+        if (mapping.getdnaToProt()[0].getFromRatio() == 3)
+        {
+          complementConsensus = new AlignmentAnnotation("cDNA Consensus",
+                  "PID for cDNA", new Annotation[1], 0f, 100f,
+                  AlignmentAnnotation.BAR_GRAPH);
+          initConsensus(complementConsensus);
+        }
       }
     }
   }
@@ -1958,6 +1994,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
     }
     oldrfs.clear();
   }
+
   @Override
   public boolean isDisplayReferenceSeq()
   {
@@ -2066,7 +2103,8 @@ public abstract class AlignmentViewport implements AlignViewportI,
   @Override
   public boolean areFeaturesDisplayed()
   {
-    return featuresDisplayed != null && featuresDisplayed.getRegisterdFeaturesCount()>0;
+    return featuresDisplayed != null
+            && featuresDisplayed.getRegisterdFeaturesCount() > 0;
   }
 
   /**
@@ -2080,6 +2118,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
   {
     viewStyle.setShowSequenceFeatures(b);
   }
+
   @Override
   public boolean isShowSequenceFeatures()
   {
@@ -2098,8 +2137,6 @@ public abstract class AlignmentViewport implements AlignViewportI,
     return viewStyle.isShowSequenceFeaturesHeight();
   }
 
-
-
   @Override
   public void setShowAnnotation(boolean b)
   {
@@ -2140,6 +2177,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getTextColour()
    */
+  @Override
   public Color getTextColour()
   {
     return viewStyle.getTextColour();
@@ -2149,6 +2187,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getTextColour2()
    */
+  @Override
   public Color getTextColour2()
   {
     return viewStyle.getTextColour2();
@@ -2158,6 +2197,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getThresholdTextColour()
    */
+  @Override
   public int getThresholdTextColour()
   {
     return viewStyle.getThresholdTextColour();
@@ -2167,6 +2207,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#isConservationColourSelected()
    */
+  @Override
   public boolean isConservationColourSelected()
   {
     return viewStyle.isConservationColourSelected();
@@ -2176,6 +2217,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#isRenderGaps()
    */
+  @Override
   public boolean isRenderGaps()
   {
     return viewStyle.isRenderGaps();
@@ -2185,6 +2227,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#isShowColourText()
    */
+  @Override
   public boolean isShowColourText()
   {
     return viewStyle.isShowColourText();
@@ -2194,6 +2237,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @param conservationColourSelected
    * @see jalview.api.ViewStyleI#setConservationColourSelected(boolean)
    */
+  @Override
   public void setConservationColourSelected(
           boolean conservationColourSelected)
   {
@@ -2204,6 +2248,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @param showColourText
    * @see jalview.api.ViewStyleI#setShowColourText(boolean)
    */
+  @Override
   public void setShowColourText(boolean showColourText)
   {
     viewStyle.setShowColourText(showColourText);
@@ -2213,6 +2258,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @param textColour
    * @see jalview.api.ViewStyleI#setTextColour(java.awt.Color)
    */
+  @Override
   public void setTextColour(Color textColour)
   {
     viewStyle.setTextColour(textColour);
@@ -2222,6 +2268,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @param thresholdTextColour
    * @see jalview.api.ViewStyleI#setThresholdTextColour(int)
    */
+  @Override
   public void setThresholdTextColour(int thresholdTextColour)
   {
     viewStyle.setThresholdTextColour(thresholdTextColour);
@@ -2231,6 +2278,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @param textColour2
    * @see jalview.api.ViewStyleI#setTextColour2(java.awt.Color)
    */
+  @Override
   public void setTextColour2(Color textColour2)
   {
     viewStyle.setTextColour2(textColour2);
@@ -2258,6 +2306,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getIdWidth()
    */
+  @Override
   public int getIdWidth()
   {
     return viewStyle.getIdWidth();
@@ -2267,6 +2316,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @param i
    * @see jalview.api.ViewStyleI#setIdWidth(int)
    */
+  @Override
   public void setIdWidth(int i)
   {
     viewStyle.setIdWidth(i);
@@ -2276,6 +2326,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#isCentreColumnLabels()
    */
+  @Override
   public boolean isCentreColumnLabels()
   {
     return viewStyle.isCentreColumnLabels();
@@ -2285,6 +2336,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @param centreColumnLabels
    * @see jalview.api.ViewStyleI#setCentreColumnLabels(boolean)
    */
+  @Override
   public void setCentreColumnLabels(boolean centreColumnLabels)
   {
     viewStyle.setCentreColumnLabels(centreColumnLabels);
@@ -2294,6 +2346,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @param showdbrefs
    * @see jalview.api.ViewStyleI#setShowDBRefs(boolean)
    */
+  @Override
   public void setShowDBRefs(boolean showdbrefs)
   {
     viewStyle.setShowDBRefs(showdbrefs);
@@ -2303,6 +2356,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#isShowDBRefs()
    */
+  @Override
   public boolean isShowDBRefs()
   {
     return viewStyle.isShowDBRefs();
@@ -2312,6 +2366,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#isShowNPFeats()
    */
+  @Override
   public boolean isShowNPFeats()
   {
     return viewStyle.isShowNPFeats();
@@ -2321,6 +2376,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @param shownpfeats
    * @see jalview.api.ViewStyleI#setShowNPFeats(boolean)
    */
+  @Override
   public void setShowNPFeats(boolean shownpfeats)
   {
     viewStyle.setShowNPFeats(shownpfeats);
@@ -2344,7 +2400,8 @@ public abstract class AlignmentViewport implements AlignViewportI,
 
   protected void broadcastCommand(CommandI command, boolean undo)
   {
-    getStructureSelectionManager().commandPerformed(command, undo, getVamsasSource());
+    getStructureSelectionManager().commandPerformed(command, undo,
+            getVamsasSource());
   }
 
   /**
@@ -2452,6 +2509,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
     return startRes;
   }
 
+  @Override
   public int getEndRes()
   {
     return endRes;
@@ -2515,21 +2573,21 @@ public abstract class AlignmentViewport implements AlignViewportI,
    */
   protected int findComplementScrollTarget(SearchResults sr)
   {
-    final AlignViewportI codingComplement = getCodingComplement();
-    if (codingComplement == null || !codingComplement.isFollowHighlight())
+    final AlignViewportI complement = getCodingComplement();
+    if (complement == null || !complement.isFollowHighlight())
     {
       return 0;
     }
     boolean iAmProtein = !getAlignment().isNucleotide();
-    AlignmentI proteinAlignment = iAmProtein ? getAlignment()
-            : codingComplement.getAlignment();
+    AlignmentI proteinAlignment = iAmProtein ? getAlignment() : complement
+            .getAlignment();
     if (proteinAlignment == null)
     {
       return 0;
     }
-    final Set<AlignedCodonFrame> mappings = proteinAlignment
+    final List<AlignedCodonFrame> mappings = proteinAlignment
             .getCodonFrames();
-  
+
     /*
      * Heuristic: find the first mapped sequence (if any) with a non-gapped
      * residue in the middle column of the visible region. Scroll the
@@ -2545,7 +2603,13 @@ public abstract class AlignmentViewport implements AlignViewportI,
     int middleColumn = getStartRes() + (getEndRes() - getStartRes()) / 2;
     final HiddenSequences hiddenSequences = getAlignment()
             .getHiddenSequences();
-    for (int seqNo = getStartSeq(); seqNo < getEndSeq(); seqNo++, seqOffset++)
+
+    /*
+     * searching to the bottom of the alignment gives smoother scrolling across
+     * all gapped visible regions
+     */
+    int lastSeq = alignment.getHeight() - 1;
+    for (int seqNo = getStartSeq(); seqNo < lastSeq; seqNo++, seqOffset++)
     {
       sequence = getAlignment().getSequenceAt(seqNo);
       if (hiddenSequences != null && hiddenSequences.isHidden(sequence))
@@ -2563,7 +2627,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
         break;
       }
     }
-  
+
     if (sequence == null)
     {
       /*