JAL-2346 remove refactored fields, fix test for above threshold
[jalview.git] / src / jalview / gui / AnnotationRowFilter.java
index 9e205c4..bc5bc54 100644 (file)
@@ -1,19 +1,45 @@
+/*
+ * 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.gui;
 
-import jalview.api.AnnotationRowFilterI;
 import jalview.datamodel.AlignmentAnnotation;
-import jalview.datamodel.Annotation;
-import jalview.datamodel.ColumnSelection;
 import jalview.datamodel.GraphLine;
-import jalview.datamodel.SequenceGroup;
 import jalview.schemes.AnnotationColourGradient;
 import jalview.util.MessageManager;
 
+import java.awt.Color;
+import java.awt.Dimension;
 import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.FocusAdapter;
+import java.awt.event.FocusEvent;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.Vector;
 
+import javax.swing.JButton;
 import javax.swing.JCheckBox;
 import javax.swing.JComboBox;
 import javax.swing.JInternalFrame;
@@ -24,8 +50,7 @@ import javax.swing.event.ChangeEvent;
 import javax.swing.event.ChangeListener;
 
 @SuppressWarnings("serial")
-public abstract class AnnotationRowFilter extends JPanel implements
-        AnnotationRowFilterI
+public abstract class AnnotationRowFilter extends JPanel
 {
   protected AlignViewport av;
 
@@ -33,33 +58,58 @@ public abstract class AnnotationRowFilter extends JPanel implements
 
   protected int[] annmap;
 
-  protected boolean enableSeqAss = false;
-
-  private jalview.datamodel.AlignmentAnnotation currentAnnotation;
-
   protected boolean adjusting = false;
 
-  protected JCheckBox currentColours = new JCheckBox();
-
-  protected JPanel minColour = new JPanel();
-
-  protected JPanel maxColour = new JPanel();
-
   protected JCheckBox seqAssociated = new JCheckBox();
 
-  protected JCheckBox thresholdIsMin = new JCheckBox();
-
   protected JSlider slider = new JSlider();
 
   protected JTextField thresholdValue = new JTextField(20);
 
   protected JInternalFrame frame;
+
+  protected JButton ok = new JButton();
+
+  protected JButton cancel = new JButton();
+
   /**
    * enabled if the user is dragging the slider - try to keep updates to a
    * minimun
    */
   protected boolean sliderDragging = false;
 
+  protected JComboBox<String> threshold = new JComboBox<String>();
+
+  protected JComboBox<String> annotations;
+
+  /*
+   * map from annotation to its menu item display label
+   * - so we know which item to pre-select on restore
+   */
+  private Map<AlignmentAnnotation, String> annotationLabels;
+
+  private AlignmentAnnotation currentAnnotation;
+
+  /**
+   * Constructor
+   * 
+   * @param av
+   * @param ap
+   */
+  public AnnotationRowFilter(AlignViewport av, final AlignmentPanel ap)
+  {
+    this.av = av;
+    this.ap = ap;
+    thresholdValue.addFocusListener(new FocusAdapter()
+    {
+      @Override
+      public void focusLost(FocusEvent e)
+      {
+        thresholdValue_actionPerformed();
+      }
+    });
+  }
+
   protected void addSliderChangeListener()
   {
 
@@ -109,27 +159,27 @@ public abstract class AnnotationRowFilter extends JPanel implements
     });
   }
 
-
-  public AnnotationRowFilter(AlignViewport av, final AlignmentPanel ap)
-  {
-    this.av = av;
-    this.ap = ap;
-  }
-
-  public AnnotationRowFilter()
-  {
-
-  }
-
-  @Override
+  /**
+   * Builds and returns a list of menu items (display text) for choice of
+   * annotation. Also builds maps between annotations, their positions in the
+   * list, and their display labels in the list.
+   * 
+   * @param isSeqAssociated
+   * @return
+   */
   public Vector<String> getAnnotationItems(boolean isSeqAssociated)
   {
+    annotationLabels = new HashMap<AlignmentAnnotation, String>();
+
     Vector<String> list = new Vector<String>();
     int index = 1;
     int[] anmap = new int[av.getAlignment().getAlignmentAnnotation().length];
+    seqAssociated.setEnabled(false);
     for (int i = 0; i < av.getAlignment().getAlignmentAnnotation().length; i++)
     {
-      if (av.getAlignment().getAlignmentAnnotation()[i].sequenceRef == null)
+      AlignmentAnnotation annotation = av.getAlignment()
+              .getAlignmentAnnotation()[i];
+      if (annotation.sequenceRef == null)
       {
         if (isSeqAssociated)
         {
@@ -138,25 +188,32 @@ public abstract class AnnotationRowFilter extends JPanel implements
       }
       else
       {
-        enableSeqAss = true;
+        seqAssociated.setEnabled(true);
       }
-      String label = av.getAlignment().getAlignmentAnnotation()[i].label;
+      String label = annotation.label;
+      // add associated sequence ID if available
+      if (!isSeqAssociated && annotation.sequenceRef != null)
+      {
+        label = label + "_" + annotation.sequenceRef.getName();
+      }
+      // make label unique
       if (!list.contains(label))
       {
         anmap[list.size()] = i;
         list.add(label);
-
+        annotationLabels.put(annotation, label);
       }
       else
       {
         if (!isSeqAssociated)
         {
           anmap[list.size()] = i;
-          list.add(label + "_" + (index++));
+          label = label + "_" + (index++);
+          list.add(label);
+          annotationLabels.put(annotation, label);
         }
       }
     }
-    // seqAssociated.setEnabled(enableSeqAss);
     this.annmap = new int[list.size()];
     System.arraycopy(anmap, 0, this.annmap, 0, this.annmap.length);
     return list;
@@ -176,14 +233,8 @@ public abstract class AnnotationRowFilter extends JPanel implements
     return selectedThresholdItem;
   }
 
-  public void modelChanged()
+  public void ok_actionPerformed()
   {
-    seqAssociated.setEnabled(enableSeqAss);
-  }
-
-  public void ok_actionPerformed(ActionEvent e)
-  {
-    updateView();
     try
     {
       frame.setClosed(true);
@@ -192,7 +243,7 @@ public abstract class AnnotationRowFilter extends JPanel implements
     }
   }
 
-  public void cancel_actionPerformed(ActionEvent e)
+  public void cancel_actionPerformed()
   {
     reset();
     ap.paintAlignment(true);
@@ -204,22 +255,22 @@ public abstract class AnnotationRowFilter extends JPanel implements
     }
   }
 
-  public void thresholdCheck_actionPerformed(ActionEvent e)
+  protected void thresholdCheck_actionPerformed()
   {
     updateView();
   }
 
-  public void annotations_actionPerformed(ActionEvent e)
+  protected void selectedAnnotationChanged()
   {
     updateView();
   }
 
-  public void threshold_actionPerformed(ActionEvent e)
+  protected void threshold_actionPerformed()
   {
     updateView();
   }
 
-  public void thresholdValue_actionPerformed(ActionEvent e)
+  protected void thresholdValue_actionPerformed()
   {
     try
     {
@@ -231,28 +282,34 @@ public abstract class AnnotationRowFilter extends JPanel implements
     }
   }
 
-  public void thresholdIsMin_actionPerformed(ActionEvent actionEvent)
+  protected void thresholdIsMin_actionPerformed()
   {
     updateView();
   }
 
-  protected void populateThresholdComboBox(JComboBox<String> threshold)
+  protected void populateThresholdComboBox(JComboBox<String> thresh)
   {
-    threshold.addItem(MessageManager
-            .getString("label.threshold_feature_no_thereshold"));
-    threshold.addItem(MessageManager
-            .getString("label.threshold_feature_above_thereshold"));
-    threshold.addItem(MessageManager
-            .getString("label.threshold_feature_below_thereshold"));
+    thresh.addItem(MessageManager
+            .getString("label.threshold_feature_no_threshold"));
+    thresh.addItem(MessageManager
+            .getString("label.threshold_feature_above_threshold"));
+    thresh.addItem(MessageManager
+            .getString("label.threshold_feature_below_threshold"));
   }
 
-  protected void seqAssociated_actionPerformed(ActionEvent arg0,
-          JComboBox<String> annotations, JCheckBox seqAssociated)
+  /**
+   * Rebuilds the drop-down list of annotations to choose from when the 'per
+   * sequence only' checkbox is checked or unchecked.
+   * 
+   * @param anns
+   */
+  protected void seqAssociated_actionPerformed(JComboBox<String> anns)
   {
     adjusting = true;
-    String cursel = (String) annotations.getSelectedItem();
-    boolean isvalid = false, isseqs = seqAssociated.isSelected();
-    annotations.removeAllItems();
+    String cursel = (String) anns.getSelectedItem();
+    boolean isvalid = false;
+    boolean isseqs = seqAssociated.isSelected();
+    anns.removeAllItems();
     for (String anitem : getAnnotationItems(seqAssociated.isSelected()))
     {
       if (anitem.equals(cursel) || (isseqs && cursel.startsWith(anitem)))
@@ -260,20 +317,22 @@ public abstract class AnnotationRowFilter extends JPanel implements
         isvalid = true;
         cursel = anitem;
       }
-      annotations.addItem(anitem);
+      anns.addItem(anitem);
     }
-    adjusting = false;
     if (isvalid)
     {
-      annotations.setSelectedItem(cursel);
+      anns.setSelectedItem(cursel);
     }
     else
     {
-      if (annotations.getItemCount() > 0)
+      if (anns.getItemCount() > 0)
       {
-        annotations.setSelectedIndex(0);
+        anns.setSelectedIndex(0);
       }
     }
+    adjusting = false;
+
+    updateView();
   }
 
   protected void propagateSeqAssociatedThreshold(boolean allAnnotation,
@@ -304,147 +363,107 @@ public abstract class AnnotationRowFilter extends JPanel implements
     }
   }
 
-  protected boolean colorAlignmContaining(
-          AlignmentAnnotation currentAnnotation, int selectedThresholdItem)
+  public AlignmentAnnotation getCurrentAnnotation()
   {
+    return currentAnnotation;
+  }
 
-    AnnotationColourGradient acg = null;
-    if (currentColours.isSelected())
-    {
-      acg = new AnnotationColourGradient(currentAnnotation,
-              av.getGlobalColourScheme(), selectedThresholdItem);
-    }
-    else
-    {
-      acg = new AnnotationColourGradient(currentAnnotation,
-              minColour.getBackground(), maxColour.getBackground(),
-              selectedThresholdItem);
-    }
-    acg.setSeqAssociated(seqAssociated.isSelected());
+  protected void setCurrentAnnotation(AlignmentAnnotation currentAnnotation)
+  {
+    this.currentAnnotation = currentAnnotation;
+  }
 
-    if (currentAnnotation.graphMin == 0f
-            && currentAnnotation.graphMax == 0f)
-    {
-      acg.setPredefinedColours(true);
-    }
+  protected abstract void valueChanged(boolean updateAllAnnotation);
 
-    acg.thresholdIsMinMax = thresholdIsMin.isSelected();
+  protected abstract void updateView();
 
-    av.setGlobalColourScheme(acg);
+  protected abstract void reset();
 
-    if (av.getAlignment().getGroups() != null)
-    {
+  protected String getAnnotationMenuLabel(AlignmentAnnotation ann)
+  {
+    return annotationLabels.get(ann);
+  }
 
-      for (SequenceGroup sg : ap.av.getAlignment().getGroups())
+  protected void jbInit()
+  {
+    ok.setOpaque(false);
+    ok.setText(MessageManager.getString("action.ok"));
+    ok.addActionListener(new ActionListener()
+    {
+      @Override
+      public void actionPerformed(ActionEvent e)
       {
-        if (sg.cs == null)
-        {
-          continue;
-        }
-
-        if (currentColours.isSelected())
-        {
-          sg.cs = new AnnotationColourGradient(currentAnnotation, sg.cs,
-                  selectedThresholdItem);
-          ((AnnotationColourGradient) sg.cs).setSeqAssociated(seqAssociated
-                  .isSelected());
+        ok_actionPerformed();
+      }
+    });
 
-        }
-        else
-        {
-          sg.cs = new AnnotationColourGradient(currentAnnotation,
-                  minColour.getBackground(), maxColour.getBackground(),
-                  selectedThresholdItem);
-          ((AnnotationColourGradient) sg.cs).setSeqAssociated(seqAssociated
-                  .isSelected());
-        }
+    cancel.setOpaque(false);
+    cancel.setText(MessageManager.getString("action.cancel"));
+    cancel.addActionListener(new ActionListener()
+    {
+      @Override
+      public void actionPerformed(ActionEvent e)
+      {
+        cancel_actionPerformed();
+      }
+    });
 
+    annotations.addItemListener(new ItemListener()
+    {
+      @Override
+      public void itemStateChanged(ItemEvent e)
+      {
+        selectedAnnotationChanged();
       }
-    }
-    return false;
-  }
+    });
+    annotations.setToolTipText(MessageManager
+            .getString("info.select_annotation_row"));
 
-  protected boolean markColumnsContaining(
-          AlignmentAnnotation currentAnnotation, int thresholdComparisonType)
-  {
-    try
+    threshold.addActionListener(new ActionListener()
     {
-      if (currentAnnotation != null)
+      @Override
+      public void actionPerformed(ActionEvent e)
       {
-        Annotation[] annotations = currentAnnotation.annotations;
-        ColumnSelection cs = av.getColumnSelection();
-        cs.clear();
-        if (thresholdComparisonType == AnnotationColourGradient.NO_THRESHOLD)
-        {
-          int count = 0;
-          do
-          {
-            if (annotations[count] != null)
-            {
-              if (currentAnnotation.label.equals("Secondary Structure")
-                      && annotations[count].secondaryStructure != ' ')
-              {
-                cs.addElement(count);
-              }
-              else if (currentAnnotation.label
-                      .equals("Iron Sulphur Contacts"))
-              {
-                cs.addElement(count);
-              }
-              else if (annotations[count].value != 0.0)
-              {
-                cs.addElement(count);
-              }
-
-            }
-            count++;
-          } while (count < annotations.length);
-        }
-        else
-        {
-          int count = 0;
-          do
-          {
-            if (annotations[count] != null)
-            {
-              if (thresholdComparisonType == AnnotationColourGradient.ABOVE_THRESHOLD)
-              {
-                if (annotations[count].value > currentAnnotation.threshold.value)
-                {
-                  cs.addElement(count);
-                }
-              }
-              else if (thresholdComparisonType == AnnotationColourGradient.BELOW_THRESHOLD)
-              {
-                if (annotations[count].value < currentAnnotation.threshold.value)
-                {
-                  cs.addElement(count);
-                }
-              }
-
-            }
-            count++;
-          } while (count < annotations.length);
-        }
+        threshold_actionPerformed();
       }
+    });
 
-      return true;
-    } catch (Exception e)
+    thresholdValue.setEnabled(false);
+    thresholdValue.setColumns(7);
+    thresholdValue.addActionListener(new ActionListener()
     {
-      e.printStackTrace();
-      return false;
-    }
+      @Override
+      public void actionPerformed(ActionEvent e)
+      {
+        thresholdValue_actionPerformed();
+      }
+    });
+
+    slider.setPaintLabels(false);
+    slider.setPaintTicks(true);
+    slider.setBackground(Color.white);
+    slider.setEnabled(false);
+    slider.setOpaque(false);
+    slider.setPreferredSize(new Dimension(100, 32));
   }
 
-  public jalview.datamodel.AlignmentAnnotation getCurrentAnnotation()
+  public JComboBox<String> getThreshold()
   {
-    return currentAnnotation;
+    return threshold;
   }
 
-  public void setCurrentAnnotation(
-          jalview.datamodel.AlignmentAnnotation currentAnnotation)
+  public void setThreshold(JComboBox<String> thresh)
   {
-    this.currentAnnotation = currentAnnotation;
+    this.threshold = thresh;
   }
 
+  public JComboBox<String> getAnnotations()
+  {
+    return annotations;
+  }
+
+  public void setAnnotations(JComboBox<String> anns)
+  {
+    this.annotations = anns;
+  }
 }