JAL-1989 more unit tests and encapsulation for ColumnSelection
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Mon, 11 Jan 2016 11:03:50 +0000 (11:03 +0000)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Mon, 11 Jan 2016 11:03:50 +0000 (11:03 +0000)
14 files changed:
src/jalview/appletgui/AlignFrame.java
src/jalview/appletgui/AnnotationPanel.java
src/jalview/appletgui/ScalePanel.java
src/jalview/appletgui/SeqPanel.java
src/jalview/controller/AlignViewController.java
src/jalview/datamodel/ColumnSelection.java
src/jalview/gui/AlignFrame.java
src/jalview/gui/AnnotationPanel.java
src/jalview/gui/ScalePanel.java
src/jalview/gui/SeqPanel.java
src/jalview/javascript/JsSelectionSender.java
src/jalview/renderer/AnnotationRenderer.java
src/jalview/viewmodel/AlignmentViewport.java
test/jalview/datamodel/ColumnSelectionTest.java

index 28442a9..cd679fc 100644 (file)
@@ -2272,7 +2272,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     ColumnSelection colSel = viewport.getColumnSelection();
     int column;
 
-    if (colSel.size() > 0)
+    if (!colSel.isEmpty())
     {
       if (trimLeft)
       {
index 32d528c..d642c14 100755 (executable)
@@ -150,7 +150,7 @@ public class AnnotationPanel extends Panel implements AwtRenderPanelI,
 
     String label = "";
     if (av.getColumnSelection() != null
-            && av.getColumnSelection().size() > 0
+            && !av.getColumnSelection().isEmpty()
             && anot[av.getColumnSelection().getMin()] != null)
     {
       label = anot[av.getColumnSelection().getMin()].displayCharacter;
@@ -158,9 +158,9 @@ public class AnnotationPanel extends Panel implements AwtRenderPanelI,
 
     if (evt.getActionCommand().equals(REMOVE))
     {
-      for (int i = 0; i < av.getColumnSelection().size(); i++)
+      for (int sel : av.getColumnSelection().getSelected())
       {
-        anot[av.getColumnSelection().columnAt(i)] = null;
+        anot[sel] = null;
       }
     }
     else if (evt.getActionCommand().equals(LABEL))
@@ -177,10 +177,8 @@ public class AnnotationPanel extends Panel implements AwtRenderPanelI,
         aa[activeRow].hasText = true;
       }
 
-      for (int i = 0; i < av.getColumnSelection().size(); i++)
+      for (int index : av.getColumnSelection().getSelected())
       {
-        int index = av.getColumnSelection().columnAt(i);
-
         if (!av.getColumnSelection().isVisible(index))
         {
           continue;
@@ -201,10 +199,8 @@ public class AnnotationPanel extends Panel implements AwtRenderPanelI,
 
       Color col = udc.getColor();
 
-      for (int i = 0; i < av.getColumnSelection().size(); i++)
+      for (int index : av.getColumnSelection().getSelected())
       {
-        int index = av.getColumnSelection().columnAt(i);
-
         if (!av.getColumnSelection().isVisible(index))
         {
           continue;
@@ -262,10 +258,8 @@ public class AnnotationPanel extends Panel implements AwtRenderPanelI,
         }
       }
 
-      for (int i = 0; i < av.getColumnSelection().size(); i++)
+      for (int index : av.getColumnSelection().getSelected())
       {
-        int index = av.getColumnSelection().columnAt(i);
-
         if (!av.getColumnSelection().isVisible(index))
         {
           continue;
index 769ac8b..cd50f3f 100755 (executable)
@@ -70,6 +70,7 @@ public class ScalePanel extends Panel implements MouseMotionListener,
 
   }
 
+  @Override
   public void mousePressed(MouseEvent evt)
   {
     int x = (evt.getX() / av.getCharWidth()) + av.getStartRes();
@@ -95,6 +96,7 @@ public class ScalePanel extends Panel implements MouseMotionListener,
                 MessageManager.getString("label.reveal"));
         item.addActionListener(new ActionListener()
         {
+          @Override
           public void actionPerformed(ActionEvent e)
           {
             av.showColumn(reveal[0]);
@@ -113,6 +115,7 @@ public class ScalePanel extends Panel implements MouseMotionListener,
           item = new MenuItem(MessageManager.getString("action.reveal_all"));
           item.addActionListener(new ActionListener()
           {
+            @Override
             public void actionPerformed(ActionEvent e)
             {
               av.showAllHiddenColumns();
@@ -135,6 +138,7 @@ public class ScalePanel extends Panel implements MouseMotionListener,
                 MessageManager.getString("label.hide_columns"));
         item.addActionListener(new ActionListener()
         {
+          @Override
           public void actionPerformed(ActionEvent e)
           {
             av.hideColumns(res, res);
@@ -193,6 +197,7 @@ public class ScalePanel extends Panel implements MouseMotionListener,
     av.sendSelection();
   }
 
+  @Override
   public void mouseReleased(MouseEvent evt)
   {
     mouseDragging = false;
@@ -232,6 +237,7 @@ public class ScalePanel extends Panel implements MouseMotionListener,
     av.sendSelection();
   }
 
+  @Override
   public void mouseDragged(MouseEvent evt)
   {
     mouseDragging = true;
@@ -301,6 +307,7 @@ public class ScalePanel extends Panel implements MouseMotionListener,
     }
   }
 
+  @Override
   public void mouseEntered(MouseEvent evt)
   {
     if (mouseDragging)
@@ -309,6 +316,7 @@ public class ScalePanel extends Panel implements MouseMotionListener,
     }
   }
 
+  @Override
   public void mouseExited(MouseEvent evt)
   {
     if (mouseDragging)
@@ -317,11 +325,13 @@ public class ScalePanel extends Panel implements MouseMotionListener,
     }
   }
 
+  @Override
   public void mouseClicked(MouseEvent evt)
   {
 
   }
 
+  @Override
   public void mouseMoved(MouseEvent evt)
   {
     if (!av.hasHiddenColumns())
@@ -346,11 +356,13 @@ public class ScalePanel extends Panel implements MouseMotionListener,
     repaint();
   }
 
+  @Override
   public void update(Graphics g)
   {
     paint(g);
   }
 
+  @Override
   public void paint(Graphics g)
   {
     drawScale(g, av.getStartRes(), av.getEndRes(), getSize().width,
@@ -371,9 +383,8 @@ public class ScalePanel extends Panel implements MouseMotionListener,
     ColumnSelection cs = av.getColumnSelection();
     gg.setColor(new Color(220, 0, 0));
     int avcharWidth = av.getCharWidth(), avcharHeight = av.getCharHeight();
-    for (int i = 0; i < cs.size(); i++)
+    for (int sel : cs.getSelected())
     {
-      int sel = cs.columnAt(i);
       if (av.hasHiddenColumns())
       {
         sel = av.getColumnSelection().findColumnPosition(sel);
index b4fefec..479b746 100644 (file)
@@ -489,6 +489,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
     return false;
   }
 
+  @Override
   public void mousePressed(MouseEvent evt)
   {
     lastMousePress = evt.getPoint();
@@ -539,6 +540,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
     return;
   }
 
+  @Override
   public void mouseClicked(MouseEvent evt)
   {
     SequenceI sequence = av.getAlignment().getSequenceAt(findSeq(evt));
@@ -572,6 +574,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
     }
   }
 
+  @Override
   public void mouseReleased(MouseEvent evt)
   {
     mouseDragging = false;
@@ -715,6 +718,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
 
   String lastMessage;
 
+  @Override
   public void mouseOverSequence(SequenceI sequence, int index, int pos)
   {
     String tmp = sequence.hashCode() + index + "";
@@ -726,6 +730,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
     lastMessage = tmp;
   }
 
+  @Override
   public void highlightSequence(SearchResults results)
   {
     if (av.isFollowHighlight())
@@ -746,12 +751,14 @@ public class SeqPanel extends Panel implements MouseMotionListener,
     return this.ap == null ? null : this.ap.av;
   }
 
+  @Override
   public void updateColours(SequenceI seq, int index)
   {
     System.out.println("update the seqPanel colours");
     // repaint();
   }
 
+  @Override
   public void mouseMoved(MouseEvent evt)
   {
     int res = findRes(evt);
@@ -912,6 +919,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
 
   Tooltip tooltip;
 
+  @Override
   public void mouseDragged(MouseEvent evt)
   {
     if (mouseWheelPressed)
@@ -1659,6 +1667,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
     seqCanvas.repaint();
   }
 
+  @Override
   public void mouseEntered(MouseEvent e)
   {
     if (oldSeq < 0)
@@ -1673,6 +1682,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
     }
   }
 
+  @Override
   public void mouseExited(MouseEvent e)
   {
     if (av.getWrapAlignment())
@@ -1732,6 +1742,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
       running = false;
     }
 
+    @Override
     public void run()
     {
       running = true;
@@ -1776,6 +1787,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
   /**
    * modify current selection according to a received message.
    */
+  @Override
   public void selection(SequenceGroup seqsel, ColumnSelection colsel,
           SelectionSource source)
   {
@@ -1821,7 +1833,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
         sgroup = seqsel.intersect(av.getAlignment(),
                 (av.hasHiddenRows()) ? av.getHiddenRepSequences() : null);
         if ((sgroup == null || sgroup.getSize() == 0)
-                && (colsel == null || colsel.size() == 0))
+                && (colsel == null || colsel.isEmpty()))
         {
           // don't copy columns if the region didn't intersect.
           copycolsel = false;
@@ -1843,7 +1855,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
     {
       // the current selection is unset or from a previous message
       // so import the new colsel.
-      if (colsel == null || colsel.size() == 0)
+      if (colsel == null || colsel.isEmpty())
       {
         if (av.getColumnSelection() != null)
         {
index a39dc80..06b1e4c 100644 (file)
@@ -83,8 +83,7 @@ public class AlignViewController implements AlignViewControllerI
     SequenceGroup sg = viewport.getSelectionGroup();
     ColumnSelection cs = viewport.getColumnSelection();
     SequenceGroup[] gps = null;
-    if (sg != null
-            && (cs == null || cs.getSelected() == null || cs.size() == 0))
+    if (sg != null && (cs == null || cs.isEmpty()))
     {
       gps = jalview.analysis.Grouping.makeGroupsFrom(viewport
               .getSequenceSelection(), viewport.getAlignmentView(true)
index 57db830..6fb584c 100644 (file)
@@ -34,9 +34,15 @@ import java.util.Vector;
  */
 public class ColumnSelection
 {
+  /*
+   * list of selected columns (not ordered)
+   */
   Vector<Integer> selected = new Vector<Integer>();
 
-  // Vector of int [] {startCol, endCol}
+  /*
+   * list of hidden column [start, end] ranges; the list is maintained in
+   * ascending start column order
+   */
   Vector<int[]> hiddenColumns;
 
   /**
@@ -102,10 +108,10 @@ public class ColumnSelection
   }
 
   /**
-   * 
-   * @return Vector containing selected columns as Integers
+   * Returns a list of selected columns. The list contains no duplicates but is
+   * not necessarily ordered.
    */
-  public Vector<Integer> getSelected()
+  public List<Integer> getSelected()
   {
     return selected;
   }
@@ -123,26 +129,11 @@ public class ColumnSelection
   }
 
   /**
-   * Column number at position i in selection
-   * 
-   * @param i
-   *          index into selected columns
-   * 
-   * @return column number in alignment
-   */
-  public int columnAt(int i)
-  {
-    return selected.elementAt(i).intValue();
-  }
-
-  /**
-   * DOCUMENT ME!
-   * 
-   * @return DOCUMENT ME!
+   * Answers true if no columns are selected, else false
    */
-  public int size()
+  public boolean isEmpty()
   {
-    return selected.size();
+    return selected == null || selected.isEmpty();
   }
 
   /**
@@ -154,11 +145,11 @@ public class ColumnSelection
   {
     int max = -1;
 
-    for (int i = 0; i < selected.size(); i++)
+    for (int sel : getSelected())
     {
-      if (columnAt(i) > max)
+      if (sel > max)
       {
-        max = columnAt(i);
+        max = sel;
       }
     }
 
@@ -174,11 +165,11 @@ public class ColumnSelection
   {
     int min = 1000000000;
 
-    for (int i = 0; i < selected.size(); i++)
+    for (int sel : getSelected())
     {
-      if (columnAt(i) < min)
+      if (sel < min)
       {
-        min = columnAt(i);
+        min = sel;
       }
     }
 
@@ -196,9 +187,9 @@ public class ColumnSelection
   public List<int[]> compensateForEdit(int start, int change)
   {
     List<int[]> deletedHiddenColumns = null;
-    for (int i = 0; i < size(); i++)
+    for (int i = 0; i < selected.size(); i++)
     {
-      int temp = columnAt(i);
+      int temp = selected.get(i);
 
       if (temp >= start)
       {
@@ -254,13 +245,13 @@ public class ColumnSelection
    */
   private void compensateForDelEdits(int start, int change)
   {
-    for (int i = 0; i < size(); i++)
+    for (int i = 0; i < selected.size(); i++)
     {
-      int temp = columnAt(i);
+      int temp = selected.get(i);
 
       if (temp >= start)
       {
-        // if this ever changes to List.set(), swap parameter order!!
+        // if this ever changes to List.set(), must swap parameter order!!!
         selected.setElementAt(new Integer(temp - change), i);
       }
     }
@@ -638,14 +629,20 @@ public class ColumnSelection
 
   public void hideSelectedColumns()
   {
-    while (size() > 0)
+    while (!selected.isEmpty())
     {
-      int column = getSelected().firstElement().intValue();
+      int column = selected.get(0).intValue();
       hideColumns(column);
     }
 
   }
 
+  /**
+   * Adds the specified column range to the hidden columns
+   * 
+   * @param start
+   * @param end
+   */
   public void hideColumns(int start, int end)
   {
     if (hiddenColumns == null)
@@ -653,48 +650,68 @@ public class ColumnSelection
       hiddenColumns = new Vector<int[]>();
     }
 
-    boolean added = false;
-    boolean overlap = false;
-
+    /*
+     * traverse existing hidden ranges and insert / amend / append as
+     * appropriate
+     */
     for (int i = 0; i < hiddenColumns.size(); i++)
     {
       int[] region = hiddenColumns.elementAt(i);
-      if (start <= region[1] && end >= region[0])
+
+      if (end < region[0] - 1)
       {
-        hiddenColumns.removeElementAt(i);
-        overlap = true;
-        break;
+        /*
+         * insert discontiguous preceding range
+         */
+        hiddenColumns.insertElementAt(new int[] { start, end }, i);
+        return;
       }
-      else if (end < region[0] && start < region[0])
+
+      if (end <= region[1])
       {
-        hiddenColumns.insertElementAt(new int[] { start, end }, i);
-        added = true;
-        break;
+        /*
+         * new range overlaps existing, or is contiguous preceding it - adjust
+         * start column
+         */
+        region[0] = Math.min(region[0], start);
+        return;
       }
-    }
 
-    if (overlap)
-    {
-      hideColumns(start, end);
-    }
-    else if (!added)
-    {
-      hiddenColumns.addElement(new int[] { start, end });
+      if (start <= region[1] + 1)
+      {
+        /*
+         * new range overlaps existing, or is contiguous following it - adjust
+         * start and end columns
+         */
+        region[0] = Math.min(region[0], start);
+        region[1] = Math.max(region[1], end);
+        return;
+      }
     }
 
+    /*
+     * remaining case is that the new range follows everything else
+     */
+      hiddenColumns.addElement(new int[] { start, end });
   }
 
   /**
-   * This method will find a range of selected columns around the column
-   * specified
+   * Hides the specified column and any adjacent selected columns
    * 
    * @param res
    *          int
    */
   public void hideColumns(int col)
   {
-    // First find out range of columns to hide
-    int min = col, max = col + 1;
+    /*
+     * deselect column (whether selected or not!)
+     */
+    removeElement(col);
+
+    /*
+     * find adjacent selected columns
+     */
+    int min = col - 1, max = col + 1;
     while (contains(min))
     {
       removeElement(min);
@@ -707,6 +724,9 @@ public class ColumnSelection
       max++;
     }
 
+    /*
+     * min, max are now the closest unselected columns
+     */
     min++;
     max--;
     if (min > max)
@@ -717,6 +737,9 @@ public class ColumnSelection
     hideColumns(min, max);
   }
 
+  /**
+   * Unhides, and adds to the selection list, all hidden columns
+   */
   public void revealAllHiddenColumns()
   {
     if (hiddenColumns != null)
@@ -734,12 +757,18 @@ public class ColumnSelection
     hiddenColumns = null;
   }
 
-  public void revealHiddenColumns(int res)
+  /**
+   * Reveals, and marks as selected, the hidden column range with the given
+   * start column
+   * 
+   * @param start
+   */
+  public void revealHiddenColumns(int start)
   {
     for (int i = 0; i < hiddenColumns.size(); i++)
     {
       int[] region = hiddenColumns.elementAt(i);
-      if (res == region[0])
+      if (start == region[0])
       {
         for (int j = region[0]; j < region[1] + 1; j++)
         {
@@ -760,9 +789,8 @@ public class ColumnSelection
   {
     if (hiddenColumns != null)
     {
-      for (int i = 0; i < hiddenColumns.size(); i++)
+      for (int[] region : hiddenColumns)
       {
-        int[] region = hiddenColumns.elementAt(i);
         if (column >= region[0] && column <= region[1])
         {
           return false;
@@ -1078,7 +1106,7 @@ public class ColumnSelection
    */
   public void addElementsFrom(ColumnSelection colsel)
   {
-    if (colsel != null && colsel.size() > 0)
+    if (colsel != null && !colsel.isEmpty())
     {
       for (Integer col : colsel.getSelected())
       {
index 5e15195..8aae64f 100644 (file)
@@ -2547,7 +2547,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     ColumnSelection colSel = viewport.getColumnSelection();
     int column;
 
-    if (colSel.size() > 0)
+    if (!colSel.isEmpty())
     {
       if (trimLeft)
       {
index 77d6b51..a70d4b9 100755 (executable)
@@ -289,14 +289,14 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
 
     if (evt.getActionCommand().equals(REMOVE))
     {
-      for (int i = 0; i < av.getColumnSelection().size(); i++)
+      for (int sel : av.getColumnSelection().getSelected())
       {
-        anot[av.getColumnSelection().columnAt(i)] = null;
+        anot[sel] = null;
       }
     }
     else if (evt.getActionCommand().equals(LABEL))
     {
-      String exMesg = collectAnnotVals(anot, av.getColumnSelection(), LABEL);
+      String exMesg = collectAnnotVals(anot, LABEL);
       String label = JOptionPane.showInputDialog(this,
               MessageManager.getString("label.enter_label"), exMesg);
 
@@ -310,10 +310,8 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
         aa[activeRow].hasText = true;
       }
 
-      for (int i = 0; i < av.getColumnSelection().size(); i++)
+      for (int index : av.getColumnSelection().getSelected())
       {
-        int index = av.getColumnSelection().columnAt(i);
-
         if (!av.getColumnSelection().isVisible(index))
         {
           continue;
@@ -338,10 +336,8 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
               MessageManager.getString("label.select_foreground_colour"),
               Color.black);
 
-      for (int i = 0; i < av.getColumnSelection().size(); i++)
+      for (int index : av.getColumnSelection().getSelected())
       {
-        int index = av.getColumnSelection().columnAt(i);
-
         if (!av.getColumnSelection().isVisible(index))
         {
           continue;
@@ -399,10 +395,8 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
           aa[activeRow].showAllColLabels = true;
         }
       }
-      for (int i = 0; i < av.getColumnSelection().size(); i++)
+      for (int index : av.getColumnSelection().getSelected())
       {
-        int index = av.getColumnSelection().columnAt(i);
-
         if (!av.getColumnSelection().isVisible(index))
         {
           continue;
@@ -428,16 +422,14 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
     return;
   }
 
-  private String collectAnnotVals(Annotation[] anot,
-          ColumnSelection columnSelection, String label2)
+  private String collectAnnotVals(Annotation[] anot, String label2)
   {
     String collatedInput = "";
     String last = "";
     ColumnSelection viscols = av.getColumnSelection();
     // TODO: refactor and save av.getColumnSelection for efficiency
-    for (int i = 0; i < columnSelection.size(); i++)
+    for (int index : viscols.getSelected())
     {
-      int index = columnSelection.columnAt(i);
       // always check for current display state - just in case
       if (!viscols.isVisible(index))
       {
index 62cd3f1..10963b6 100755 (executable)
@@ -84,6 +84,7 @@ public class ScalePanel extends JPanel implements MouseMotionListener,
    * @param evt
    *          DOCUMENT ME!
    */
+  @Override
   public void mousePressed(MouseEvent evt)
   {
     int x = (evt.getX() / av.getCharWidth()) + av.getStartRes();
@@ -115,6 +116,7 @@ public class ScalePanel extends JPanel implements MouseMotionListener,
                 MessageManager.getString("label.reveal"));
         item.addActionListener(new ActionListener()
         {
+          @Override
           public void actionPerformed(ActionEvent e)
           {
             av.showColumn(reveal[0]);
@@ -134,6 +136,7 @@ public class ScalePanel extends JPanel implements MouseMotionListener,
                   MessageManager.getString("action.reveal_all"));
           item.addActionListener(new ActionListener()
           {
+            @Override
             public void actionPerformed(ActionEvent e)
             {
               av.showAllHiddenColumns();
@@ -155,6 +158,7 @@ public class ScalePanel extends JPanel implements MouseMotionListener,
                 MessageManager.getString("label.hide_columns"));
         item.addActionListener(new ActionListener()
         {
+          @Override
           public void actionPerformed(ActionEvent e)
           {
             av.hideColumns(res, res);
@@ -170,6 +174,7 @@ public class ScalePanel extends JPanel implements MouseMotionListener,
             {
               ap.overviewPanel.updateOverviewImage();
             }
+            av.sendSelection();
           }
         });
         pop.add(item);
@@ -221,6 +226,7 @@ public class ScalePanel extends JPanel implements MouseMotionListener,
    * @param evt
    *          DOCUMENT ME!
    */
+  @Override
   public void mouseReleased(MouseEvent evt)
   {
     mouseDragging = false;
@@ -268,6 +274,7 @@ public class ScalePanel extends JPanel implements MouseMotionListener,
    * @param evt
    *          DOCUMENT ME!
    */
+  @Override
   public void mouseDragged(MouseEvent evt)
   {
     mouseDragging = true;
@@ -337,6 +344,7 @@ public class ScalePanel extends JPanel implements MouseMotionListener,
     }
   }
 
+  @Override
   public void mouseEntered(MouseEvent evt)
   {
     if (mouseDragging)
@@ -345,6 +353,7 @@ public class ScalePanel extends JPanel implements MouseMotionListener,
     }
   }
 
+  @Override
   public void mouseExited(MouseEvent evt)
   {
     if (mouseDragging)
@@ -353,10 +362,12 @@ public class ScalePanel extends JPanel implements MouseMotionListener,
     }
   }
 
+  @Override
   public void mouseClicked(MouseEvent evt)
   {
   }
 
+  @Override
   public void mouseMoved(MouseEvent evt)
   {
     if (!av.hasHiddenColumns())
@@ -398,6 +409,7 @@ public class ScalePanel extends JPanel implements MouseMotionListener,
    * @param g
    *          DOCUMENT ME!
    */
+  @Override
   public void paintComponent(Graphics g)
   {
     drawScale(g, av.getStartRes(), av.getEndRes(), getWidth(), getHeight());
@@ -430,9 +442,8 @@ public class ScalePanel extends JPanel implements MouseMotionListener,
     {
       gg.setColor(new Color(220, 0, 0));
 
-      for (int i = 0; i < cs.size(); i++)
+      for (int sel : cs.getSelected())
       {
-        int sel = cs.columnAt(i);
         if (av.hasHiddenColumns())
         {
           if (cs.isVisible(sel))
index fe05e6e..cce2ee0 100644 (file)
@@ -801,6 +801,7 @@ public class SeqPanel extends JPanel implements MouseListener,
    * 
    * @see javax.swing.JComponent#getToolTipLocation(java.awt.event.MouseEvent)
    */
+  @Override
   public Point getToolTipLocation(MouseEvent event)
   {
     int x = event.getX(), w = getWidth();
@@ -1962,7 +1963,7 @@ public class SeqPanel extends JPanel implements MouseListener,
       sgroup = seqsel.intersect(av.getAlignment(),
               (av.hasHiddenRows()) ? av.getHiddenRepSequences() : null);
       if ((sgroup == null || sgroup.getSize() == 0)
-              || (colsel == null || colsel.size() == 0))
+              || (colsel == null || colsel.isEmpty()))
       {
         // don't copy columns if the region didn't intersect.
         copycolsel = false;
@@ -1983,7 +1984,7 @@ public class SeqPanel extends JPanel implements MouseListener,
     {
       // the current selection is unset or from a previous message
       // so import the new colsel.
-      if (colsel == null || colsel.size() == 0)
+      if (colsel == null || colsel.isEmpty())
       {
         if (av.getColumnSelection() != null)
         {
index 60cff9a..dc08b59 100644 (file)
@@ -50,7 +50,6 @@ public class JsSelectionSender extends JSFunctionExec implements
     try
     {
       String setid = "";
-      String viewid = "";
       AlignFrame src = _af;
       if (source != null)
       {
@@ -82,19 +81,16 @@ public class JsSelectionSender extends JSFunctionExec implements
           end = seqsel.getEndRes();
         }
       }
-      if (colsel != null && colsel.size() > 0)
+      if (colsel != null && !colsel.isEmpty())
       {
         if (end == -1)
         {
           end = colsel.getMax() + 1;
         }
         cols = new String[colsel.getSelected().size()];
-        int d = 0, r = -1;
         for (int i = 0; i < cols.length; i++)
         {
-          cols[i] = ""
-                  + (1 + ((Integer) colsel.getSelected().elementAt(i))
-                          .intValue());
+          cols[i] = "" + (1 + colsel.getSelected().get(i).intValue());
         }
       }
       else
index e5c2218..007df3e 100644 (file)
@@ -598,10 +598,8 @@ public class AnnotationRenderer
 
               if (columnSelection != null)
               {
-                for (int n = 0; n < columnSelection.size(); n++)
+                for (int v : columnSelection.getSelected())
                 {
-                  int v = columnSelection.columnAt(n);
-
                   if (v == column)
                   {
                     g.fillRect(x * charWidth, y, charWidth, charHeight);
index 3f1946e..c4ae76d 100644 (file)
@@ -95,6 +95,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 +105,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 +115,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 +125,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getFontStyle()
    */
+  @Override
   public int getFontStyle()
   {
     return viewStyle.getFontStyle();
@@ -131,6 +135,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getFontName()
    */
+  @Override
   public String getFontName()
   {
     return viewStyle.getFontName();
@@ -140,6 +145,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getFontSize()
    */
+  @Override
   public int getFontSize()
   {
     return viewStyle.getFontSize();
@@ -149,6 +155,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 +165,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#isUpperCasebold()
    */
+  @Override
   public boolean isUpperCasebold()
   {
     return viewStyle.isUpperCasebold();
@@ -167,6 +175,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#isSeqNameItalics()
    */
+  @Override
   public boolean isSeqNameItalics()
   {
     return viewStyle.isSeqNameItalics();
@@ -176,6 +185,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 +195,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 +205,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getColourAppliesToAllGroups()
    */
+  @Override
   public boolean getColourAppliesToAllGroups()
   {
     return viewStyle.getColourAppliesToAllGroups();
@@ -203,6 +215,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getAbovePIDThreshold()
    */
+  @Override
   public boolean getAbovePIDThreshold()
   {
     return viewStyle.getAbovePIDThreshold();
@@ -212,6 +225,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 +235,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getIncrement()
    */
+  @Override
   public int getIncrement()
   {
     return viewStyle.getIncrement();
@@ -230,6 +245,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 +255,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 +265,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getShowHiddenMarkers()
    */
+  @Override
   public boolean getShowHiddenMarkers()
   {
     return viewStyle.getShowHiddenMarkers();
@@ -257,6 +275,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 +285,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 +295,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 +305,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getScaleLeftWrapped()
    */
+  @Override
   public boolean getScaleLeftWrapped()
   {
     return viewStyle.getScaleLeftWrapped();
@@ -293,6 +315,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getScaleAboveWrapped()
    */
+  @Override
   public boolean getScaleAboveWrapped()
   {
     return viewStyle.getScaleAboveWrapped();
@@ -302,6 +325,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getScaleRightWrapped()
    */
+  @Override
   public boolean getScaleRightWrapped()
   {
     return viewStyle.getScaleRightWrapped();
@@ -311,6 +335,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 +345,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 +355,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getThreshold()
    */
+  @Override
   public int getThreshold()
   {
     return viewStyle.getThreshold();
@@ -338,6 +365,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getShowJVSuffix()
    */
+  @Override
   public boolean getShowJVSuffix()
   {
     return viewStyle.getShowJVSuffix();
@@ -347,6 +375,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 +385,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 +395,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 +405,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 +415,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getColourText()
    */
+  @Override
   public boolean getColourText()
   {
     return viewStyle.getColourText();
@@ -392,6 +425,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 +435,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getWrapAlignment()
    */
+  @Override
   public boolean getWrapAlignment()
   {
     return viewStyle.getWrapAlignment();
@@ -410,6 +445,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getShowText()
    */
+  @Override
   public boolean getShowText()
   {
     return viewStyle.getShowText();
@@ -419,6 +455,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getWrappedWidth()
    */
+  @Override
   public int getWrappedWidth()
   {
     return viewStyle.getWrappedWidth();
@@ -428,6 +465,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 +475,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getCharHeight()
    */
+  @Override
   public int getCharHeight()
   {
     return viewStyle.getCharHeight();
@@ -446,6 +485,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 +495,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getCharWidth()
    */
+  @Override
   public int getCharWidth()
   {
     return viewStyle.getCharWidth();
@@ -464,6 +505,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 +515,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getShowBoxes()
    */
+  @Override
   public boolean getShowBoxes()
   {
     return viewStyle.getShowBoxes();
@@ -482,6 +525,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getShowUnconserved()
    */
+  @Override
   public boolean getShowUnconserved()
   {
     return viewStyle.getShowUnconserved();
@@ -491,6 +535,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 +545,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @param default1
    * @see jalview.api.ViewStyleI#setSeqNameItalics(boolean)
    */
+  @Override
   public void setSeqNameItalics(boolean default1)
   {
     viewStyle.setSeqNameItalics(default1);
@@ -1147,7 +1193,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)
     {
@@ -1242,7 +1288,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
 
   public void hideSelectedColumns()
   {
-    if (colSel.size() < 1)
+    if (colSel.isEmpty())
     {
       return;
     }
@@ -2115,6 +2161,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getTextColour()
    */
+  @Override
   public Color getTextColour()
   {
     return viewStyle.getTextColour();
@@ -2124,6 +2171,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getTextColour2()
    */
+  @Override
   public Color getTextColour2()
   {
     return viewStyle.getTextColour2();
@@ -2133,6 +2181,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getThresholdTextColour()
    */
+  @Override
   public int getThresholdTextColour()
   {
     return viewStyle.getThresholdTextColour();
@@ -2142,6 +2191,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#isConservationColourSelected()
    */
+  @Override
   public boolean isConservationColourSelected()
   {
     return viewStyle.isConservationColourSelected();
@@ -2151,6 +2201,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#isRenderGaps()
    */
+  @Override
   public boolean isRenderGaps()
   {
     return viewStyle.isRenderGaps();
@@ -2160,6 +2211,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#isShowColourText()
    */
+  @Override
   public boolean isShowColourText()
   {
     return viewStyle.isShowColourText();
@@ -2169,6 +2221,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @param conservationColourSelected
    * @see jalview.api.ViewStyleI#setConservationColourSelected(boolean)
    */
+  @Override
   public void setConservationColourSelected(
           boolean conservationColourSelected)
   {
@@ -2179,6 +2232,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @param showColourText
    * @see jalview.api.ViewStyleI#setShowColourText(boolean)
    */
+  @Override
   public void setShowColourText(boolean showColourText)
   {
     viewStyle.setShowColourText(showColourText);
@@ -2188,6 +2242,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);
@@ -2197,6 +2252,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @param thresholdTextColour
    * @see jalview.api.ViewStyleI#setThresholdTextColour(int)
    */
+  @Override
   public void setThresholdTextColour(int thresholdTextColour)
   {
     viewStyle.setThresholdTextColour(thresholdTextColour);
@@ -2206,6 +2262,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);
@@ -2233,6 +2290,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#getIdWidth()
    */
+  @Override
   public int getIdWidth()
   {
     return viewStyle.getIdWidth();
@@ -2242,6 +2300,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @param i
    * @see jalview.api.ViewStyleI#setIdWidth(int)
    */
+  @Override
   public void setIdWidth(int i)
   {
     viewStyle.setIdWidth(i);
@@ -2251,6 +2310,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#isCentreColumnLabels()
    */
+  @Override
   public boolean isCentreColumnLabels()
   {
     return viewStyle.isCentreColumnLabels();
@@ -2260,6 +2320,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @param centreColumnLabels
    * @see jalview.api.ViewStyleI#setCentreColumnLabels(boolean)
    */
+  @Override
   public void setCentreColumnLabels(boolean centreColumnLabels)
   {
     viewStyle.setCentreColumnLabels(centreColumnLabels);
@@ -2269,6 +2330,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @param showdbrefs
    * @see jalview.api.ViewStyleI#setShowDBRefs(boolean)
    */
+  @Override
   public void setShowDBRefs(boolean showdbrefs)
   {
     viewStyle.setShowDBRefs(showdbrefs);
@@ -2278,6 +2340,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#isShowDBRefs()
    */
+  @Override
   public boolean isShowDBRefs()
   {
     return viewStyle.isShowDBRefs();
@@ -2287,6 +2350,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @return
    * @see jalview.api.ViewStyleI#isShowNPFeats()
    */
+  @Override
   public boolean isShowNPFeats()
   {
     return viewStyle.isShowNPFeats();
@@ -2296,6 +2360,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    * @param shownpfeats
    * @see jalview.api.ViewStyleI#setShowNPFeats(boolean)
    */
+  @Override
   public void setShowNPFeats(boolean shownpfeats)
   {
     viewStyle.setShowNPFeats(shownpfeats);
@@ -2428,6 +2493,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
     return startRes;
   }
 
+  @Override
   public int getEndRes()
   {
     return endRes;
index f4c5b77..698f259 100644 (file)
 package jalview.datamodel;
 
 import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertFalse;
+import static org.testng.AssertJUnit.assertSame;
+import static org.testng.AssertJUnit.assertTrue;
 
+import java.util.Arrays;
 import java.util.List;
 
 import org.testng.annotations.Test;
@@ -35,10 +39,10 @@ public class ColumnSelectionTest
     ColumnSelection cs = new ColumnSelection();
     cs.addElement(2);
     cs.addElement(5);
+    cs.addElement(3);
+    cs.addElement(5); // ignored
     List<Integer> sel = cs.getSelected();
-    assertEquals(2, sel.size());
-    assertEquals(new Integer(2), sel.get(0));
-    assertEquals(new Integer(5), sel.get(1));
+    assertEquals("[2, 5, 3]", sel.toString());
   }
 
   /**
@@ -80,10 +84,6 @@ public class ColumnSelectionTest
     cs.hideColumns(6, 6);
     assertEquals(5, cs.findColumnPosition(5));
 
-    // hiding column 5 makes no difference
-    cs.hideColumns(5, 5);
-    assertEquals(5, cs.findColumnPosition(5));
-
     // hiding column 4 moves column 5 to column 4
     cs.hideColumns(4, 4);
     assertEquals(4, cs.findColumnPosition(5));
@@ -92,4 +92,255 @@ public class ColumnSelectionTest
     cs.hideColumns(1, 2);
     assertEquals(2, cs.findColumnPosition(5));
   }
+
+  @Test(groups = { "Functional" })
+  public void testHideColumns()
+  {
+    ColumnSelection cs = new ColumnSelection();
+    cs.hideColumns(5);
+    List<int[]> hidden = cs.getHiddenColumns();
+    assertEquals(1, hidden.size());
+    assertEquals("[5, 5]", Arrays.toString(hidden.get(0)));
+
+    cs.hideColumns(3);
+    assertEquals(2, hidden.size());
+    // two hidden ranges, in order:
+    assertSame(hidden, cs.getHiddenColumns());
+    assertEquals("[3, 3]", Arrays.toString(hidden.get(0)));
+    assertEquals("[5, 5]", Arrays.toString(hidden.get(1)));
+
+    // hiding column 4 expands [3, 3] to [3, 4]
+    // not fancy enough to coalesce this into [3, 5] though
+    cs.hideColumns(4);
+    hidden = cs.getHiddenColumns();
+    assertEquals(2, hidden.size());
+    assertEquals("[3, 4]", Arrays.toString(hidden.get(0)));
+    assertEquals("[5, 5]", Arrays.toString(hidden.get(1)));
+
+    // clear hidden columns (note they are added to selected)
+    cs.revealAllHiddenColumns();
+    // it is now actually null but getter returns an empty list
+    assertTrue(cs.getHiddenColumns().isEmpty());
+
+    cs.hideColumns(3, 6);
+    hidden = cs.getHiddenColumns();
+    int[] firstHiddenRange = hidden.get(0);
+    assertEquals("[3, 6]", Arrays.toString(firstHiddenRange));
+
+    // adding a subrange of already hidden should do nothing
+    cs.hideColumns(4, 5);
+    assertEquals(1, hidden.size());
+    assertSame(firstHiddenRange, cs.getHiddenColumns().get(0));
+    cs.hideColumns(3, 5);
+    assertEquals(1, hidden.size());
+    assertSame(firstHiddenRange, cs.getHiddenColumns().get(0));
+    cs.hideColumns(4, 6);
+    assertEquals(1, hidden.size());
+    assertSame(firstHiddenRange, cs.getHiddenColumns().get(0));
+    cs.hideColumns(3, 6);
+    assertEquals(1, hidden.size());
+    assertSame(firstHiddenRange, cs.getHiddenColumns().get(0));
+
+    cs.revealAllHiddenColumns();
+    cs.hideColumns(2, 4);
+    hidden = cs.getHiddenColumns();
+    assertEquals(1, hidden.size());
+    assertEquals("[2, 4]", Arrays.toString(hidden.get(0)));
+
+    // extend contiguous with 2 positions overlap
+    cs.hideColumns(3, 5);
+    assertEquals(1, hidden.size());
+    assertEquals("[2, 5]", Arrays.toString(hidden.get(0)));
+
+    // extend contiguous with 1 position overlap
+    cs.hideColumns(5, 6);
+    assertEquals(1, hidden.size());
+    assertEquals("[2, 6]", Arrays.toString(hidden.get(0)));
+
+    // extend contiguous with overlap both ends:
+    cs.hideColumns(1, 7);
+    assertEquals(1, hidden.size());
+    assertEquals("[1, 7]", Arrays.toString(hidden.get(0)));
+  }
+
+  /**
+   * Test the method that hides a specified column including any adjacent
+   * selected columns. This is a convenience method for the case where multiple
+   * column regions are selected and then hidden using menu option View | Hide |
+   * Selected Columns.
+   */
+  @Test(groups = { "Functional" })
+  public void testHideColumns_withSelection()
+  {
+    ColumnSelection cs = new ColumnSelection();
+    // select columns 4-6
+    cs.addElement(4);
+    cs.addElement(5);
+    cs.addElement(6);
+    // hide column 5 (and adjacent):
+    cs.hideColumns(5);
+    // 4,5,6 now hidden:
+    List<int[]> hidden = cs.getHiddenColumns();
+    assertEquals(1, hidden.size());
+    assertEquals("[4, 6]", Arrays.toString(hidden.get(0)));
+    // none now selected:
+    assertTrue(cs.getSelected().isEmpty());
+
+    // repeat, hiding column 4 (5 and 6)
+    cs = new ColumnSelection();
+    cs.addElement(4);
+    cs.addElement(5);
+    cs.addElement(6);
+    cs.hideColumns(4);
+    hidden = cs.getHiddenColumns();
+    assertEquals(1, hidden.size());
+    assertEquals("[4, 6]", Arrays.toString(hidden.get(0)));
+    assertTrue(cs.getSelected().isEmpty());
+
+    // repeat, hiding column (4, 5 and) 6
+    cs = new ColumnSelection();
+    cs.addElement(4);
+    cs.addElement(5);
+    cs.addElement(6);
+    cs.hideColumns(6);
+    hidden = cs.getHiddenColumns();
+    assertEquals(1, hidden.size());
+    assertEquals("[4, 6]", Arrays.toString(hidden.get(0)));
+    assertTrue(cs.getSelected().isEmpty());
+
+    // repeat, with _only_ adjacent columns selected
+    cs = new ColumnSelection();
+    cs.addElement(4);
+    cs.addElement(6);
+    cs.hideColumns(5);
+    hidden = cs.getHiddenColumns();
+    assertEquals(1, hidden.size());
+    assertEquals("[4, 6]", Arrays.toString(hidden.get(0)));
+    assertTrue(cs.getSelected().isEmpty());
+  }
+
+  /**
+   * Test the method that hides all (possibly disjoint) selected column ranges
+   */
+  @Test(groups = { "Functional" })
+  public void testHideSelectedColumns()
+  {
+    ColumnSelection cs = new ColumnSelection();
+    int[] sel = { 2, 3, 4, 7, 8, 9, 20, 21, 22 };
+    for (int col : sel)
+    {
+      cs.addElement(col);
+    }
+    cs.hideColumns(15, 18);
+
+    cs.hideSelectedColumns();
+    assertTrue(cs.getSelected().isEmpty());
+    List<int[]> hidden = cs.getHiddenColumns();
+    assertEquals(4, hidden.size());
+    assertEquals("[2, 4]", Arrays.toString(hidden.get(0)));
+    assertEquals("[7, 9]", Arrays.toString(hidden.get(1)));
+    assertEquals("[15, 18]", Arrays.toString(hidden.get(2)));
+    assertEquals("[20, 22]", Arrays.toString(hidden.get(3)));
+  }
+
+  /**
+   * Test the method that reveals a range of hidden columns given the start
+   * column of the range
+   */
+  @Test(groups = { "Functional" })
+  public void testRevealHiddenColumns()
+  {
+    ColumnSelection cs = new ColumnSelection();
+    cs.hideColumns(5, 8);
+    cs.addElement(10);
+    cs.revealHiddenColumns(5);
+    // hidden columns list now null but getter returns empty list:
+    assertTrue(cs.getHiddenColumns().isEmpty());
+    // revealed columns are marked as selected (added to selection):
+    assertEquals("[10, 5, 6, 7, 8]", cs.getSelected().toString());
+
+    // calling with a column other than the range start does nothing:
+    cs = new ColumnSelection();
+    cs.hideColumns(5, 8);
+    List<int[]> hidden = cs.getHiddenColumns();
+    cs.revealHiddenColumns(6);
+    assertSame(hidden, cs.getHiddenColumns());
+    assertTrue(cs.getSelected().isEmpty());
+  }
+
+  @Test(groups = { "Functional" })
+  public void testRevealAllHiddenColumns()
+  {
+    ColumnSelection cs = new ColumnSelection();
+    cs.hideColumns(5, 8);
+    cs.hideColumns(2, 3);
+    cs.addElement(11);
+    cs.addElement(1);
+    cs.revealAllHiddenColumns();
+
+    /*
+     * revealing hidden columns adds them (in order) to the (unordered)
+     * selection list
+     */
+    assertTrue(cs.getHiddenColumns().isEmpty());
+    assertEquals("[11, 1, 2, 3, 5, 6, 7, 8]", cs.getSelected().toString());
+  }
+
+  @Test(groups = { "Functional" })
+  public void testIsVisible()
+  {
+    ColumnSelection cs = new ColumnSelection();
+    cs.hideColumns(2, 4);
+    cs.hideColumns(6, 7);
+    assertTrue(cs.isVisible(0));
+    assertTrue(cs.isVisible(-99));
+    assertTrue(cs.isVisible(1));
+    assertFalse(cs.isVisible(2));
+    assertFalse(cs.isVisible(3));
+    assertFalse(cs.isVisible(4));
+    assertTrue(cs.isVisible(5));
+    assertFalse(cs.isVisible(6));
+    assertFalse(cs.isVisible(7));
+  }
+
+  @Test(groups = { "Functional" })
+  public void testGetVisibleContigs()
+  {
+    ColumnSelection cs = new ColumnSelection();
+    cs.hideColumns(3, 6);
+    cs.hideColumns(8, 9);
+    cs.hideColumns(12, 12);
+
+    // start position is inclusive, end position exclusive:
+    int[] visible = cs.getVisibleContigs(1, 13);
+    assertEquals("[1, 2, 7, 7, 10, 11]", Arrays.toString(visible));
+
+    visible = cs.getVisibleContigs(4, 14);
+    assertEquals("[7, 7, 10, 11, 13, 13]", Arrays.toString(visible));
+
+    visible = cs.getVisibleContigs(3, 10);
+    assertEquals("[7, 7]", Arrays.toString(visible));
+
+    visible = cs.getVisibleContigs(4, 6);
+    assertEquals("[]", Arrays.toString(visible));
+  }
+
+  @Test(groups = { "Functional" })
+  public void testInvertColumnSelection()
+  {
+    ColumnSelection cs = new ColumnSelection();
+    cs.addElement(4);
+    cs.addElement(6);
+    cs.addElement(8);
+    cs.hideColumns(3, 3);
+    cs.hideColumns(6, 6);
+
+    // invert selection from start (inclusive) to end (exclusive)
+    // hidden columns are _not_ changed
+    cs.invertColumnSelection(2, 9);
+    assertEquals("[2, 5, 7]", cs.getSelected().toString());
+
+    cs.invertColumnSelection(1, 9);
+    assertEquals("[1, 4, 8]", cs.getSelected().toString());
+  }
 }