Merge branch 'documentation/JAL-2675_release2102b1' into feature/JAL-2611
[jalview.git] / src / jalview / gui / FeatureColourChooser.java
index 5594e1a..396df04 100644 (file)
@@ -49,29 +49,15 @@ import javax.swing.event.ChangeListener;
 public class FeatureColourChooser extends JalviewDialog
 {
   // FeatureSettings fs;
-  FeatureRenderer fr;
+  private FeatureRenderer fr;
 
   private FeatureColourI cs;
 
   private FeatureColourI oldcs;
 
-  /**
-   * 
-   * @return the last colour setting selected by user - either oldcs (which may
-   *         be a java.awt.Color) or the new GraduatedColor
-   */
-  public FeatureColourI getLastColour()
-  {
-    if (cs == null)
-    {
-      return oldcs;
-    }
-    return cs;
-  }
+  private AlignmentPanel ap;
 
-  AlignmentPanel ap;
-
-  boolean adjusting = false;
+  private boolean adjusting = false;
 
   final private float min;
 
@@ -79,25 +65,62 @@ public class FeatureColourChooser extends JalviewDialog
 
   final private float scaleFactor;
 
-  String type = null;
+  private String type = null;
+
+  private JPanel minColour = new JPanel();
+
+  private JPanel maxColour = new JPanel();
+
+  private JComboBox<String> threshold = new JComboBox<>();
+
+  private JSlider slider = new JSlider();
+
+  private JTextField thresholdValue = new JTextField(20);
+
+  // TODO implement GUI for tolower flag
+  // JCheckBox toLower = new JCheckBox();
+
+  private JCheckBox thresholdIsMin = new JCheckBox();
+
+  private JCheckBox colourByLabel = new JCheckBox();
+
+  private GraphLine threshline;
+
+  private Color oldmaxColour;
+
+  private Color oldminColour;
+
+  private ActionListener colourEditor = null;
 
-  public FeatureColourChooser(FeatureRenderer frender, String type)
+  /**
+   * Constructor
+   * 
+   * @param frender
+   * @param theType
+   */
+  public FeatureColourChooser(FeatureRenderer frender, String theType)
   {
-    this(frender, false, type);
+    this(frender, false, theType);
   }
 
-  public FeatureColourChooser(FeatureRenderer frender, boolean block,
-          String type)
+  /**
+   * Constructor, with option to make a blocking dialog (has to complete in the
+   * AWT event queue thread). Currently this option is always set to false.
+   * 
+   * @param frender
+   * @param blocking
+   * @param theType
+   */
+  FeatureColourChooser(FeatureRenderer frender, boolean blocking,
+          String theType)
   {
     this.fr = frender;
-    this.type = type;
+    this.type = theType;
     ap = fr.ap;
-    String title = MessageManager.formatMessage(
-            "label.graduated_color_for_params", new String[] { type });
-    initDialogFrame(this, true, block, title, 480, 185);
-    // frame.setLayer(JLayeredPane.PALETTE_LAYER);
-    // Desktop.addInternalFrame(frame, "Graduated Feature Colour for "+type,
-    // 480, 145);
+    String title = MessageManager
+            .formatMessage("label.graduated_color_for_params", new String[]
+            { theType });
+    initDialogFrame(this, true, blocking, title, 480, 185);
 
     slider.addChangeListener(new ChangeListener()
     {
@@ -107,7 +130,7 @@ public class FeatureColourChooser extends JalviewDialog
         if (!adjusting)
         {
           thresholdValue.setText((slider.getValue() / scaleFactor) + "");
-          valueChanged();
+          sliderValueChanged();
         }
       }
     });
@@ -116,15 +139,18 @@ public class FeatureColourChooser extends JalviewDialog
       @Override
       public void mouseReleased(MouseEvent evt)
       {
+        /*
+         * only update Overview and/or structure colouring
+         * when threshold slider drag ends (mouse up)
+         */
         if (ap != null)
         {
           ap.paintAlignment(true);
         }
-        ;
       }
     });
 
-    float mm[] = fr.getMinMax().get(type)[0];
+    float mm[] = fr.getMinMax().get(theType)[0];
     min = mm[0];
     max = mm[1];
 
@@ -135,7 +161,7 @@ public class FeatureColourChooser extends JalviewDialog
      */
     scaleFactor = (max == min) ? 1f : 100f / (max - min);
 
-    oldcs = fr.getFeatureColours().get(type);
+    oldcs = fr.getFeatureColours().get(theType);
     if (!oldcs.isSimpleColour())
     {
       if (oldcs.isAutoScaled())
@@ -178,14 +204,16 @@ public class FeatureColourChooser extends JalviewDialog
       // initialise threshold slider and selector
       threshold.setSelectedIndex(cs.isAboveThreshold() ? 1 : 2);
       slider.setEnabled(true);
+      slider.setValue((int) (cs.getThreshold() * scaleFactor));
       thresholdValue.setEnabled(true);
-      threshline = new GraphLine((max - min) / 2f, "Threshold", Color.black);
-
+      threshline = new GraphLine((max - min) / 2f, "Threshold",
+              Color.black);
+      threshline.value = cs.getThreshold();
     }
 
     adjusting = false;
 
-    changeColour();
+    changeColour(false);
     waitForInput();
   }
 
@@ -223,20 +251,22 @@ public class FeatureColourChooser extends JalviewDialog
       }
     });
     maxColour.setBorder(new LineBorder(Color.black));
-    minText.setText(MessageManager.getString("label.min"));
+    JLabel minText = new JLabel(MessageManager.getString("label.min"));
     minText.setFont(JvSwingUtils.getLabelFont());
-    maxText.setText(MessageManager.getString("label.max"));
+    JLabel maxText = new JLabel(MessageManager.getString("label.max"));
     maxText.setFont(JvSwingUtils.getLabelFont());
-    this.setLayout(borderLayout1);
-    jPanel2.setLayout(flowLayout1);
+    this.setLayout(new BorderLayout());
+    JPanel jPanel1 = new JPanel();
     jPanel1.setBackground(Color.white);
+    JPanel jPanel2 = new JPanel();
+    jPanel2.setLayout(new FlowLayout());
     jPanel2.setBackground(Color.white);
     threshold.addActionListener(new ActionListener()
     {
       @Override
       public void actionPerformed(ActionEvent e)
       {
-        threshold_actionPerformed(e);
+        threshold_actionPerformed();
       }
     });
     threshold.setToolTipText(MessageManager
@@ -247,13 +277,15 @@ public class FeatureColourChooser extends JalviewDialog
             .getString("label.threshold_feature_above_threshold")); // index 1
     threshold.addItem(MessageManager
             .getString("label.threshold_feature_below_threshold")); // index 2
-    jPanel3.setLayout(flowLayout2);
+
+    JPanel jPanel3 = new JPanel();
+    jPanel3.setLayout(new FlowLayout());
     thresholdValue.addActionListener(new ActionListener()
     {
       @Override
       public void actionPerformed(ActionEvent e)
       {
-        thresholdValue_actionPerformed(e);
+        thresholdValue_actionPerformed();
       }
     });
     slider.setPaintLabels(false);
@@ -262,14 +294,14 @@ public class FeatureColourChooser extends JalviewDialog
     slider.setEnabled(false);
     slider.setOpaque(false);
     slider.setPreferredSize(new Dimension(100, 32));
-    slider.setToolTipText(MessageManager
-            .getString("label.adjust_threshold"));
+    slider.setToolTipText(
+            MessageManager.getString("label.adjust_threshold"));
     thresholdValue.setEnabled(false);
     thresholdValue.setColumns(7);
     jPanel3.setBackground(Color.white);
     thresholdIsMin.setBackground(Color.white);
-    thresholdIsMin.setText(MessageManager
-            .getString("label.threshold_minmax"));
+    thresholdIsMin
+            .setText(MessageManager.getString("label.threshold_minmax"));
     thresholdIsMin.setToolTipText(MessageManager
             .getString("label.toggle_absolute_relative_display_threshold"));
     thresholdIsMin.addActionListener(new ActionListener()
@@ -277,83 +309,47 @@ public class FeatureColourChooser extends JalviewDialog
       @Override
       public void actionPerformed(ActionEvent actionEvent)
       {
-        thresholdIsMin_actionPerformed(actionEvent);
+        thresholdIsMin_actionPerformed();
       }
     });
     colourByLabel.setBackground(Color.white);
     colourByLabel
             .setText(MessageManager.getString("label.colour_by_label"));
-    colourByLabel
-            .setToolTipText(MessageManager
-                    .getString("label.display_features_same_type_different_label_using_different_colour"));
+    colourByLabel.setToolTipText(MessageManager.getString(
+            "label.display_features_same_type_different_label_using_different_colour"));
     colourByLabel.addActionListener(new ActionListener()
     {
       @Override
       public void actionPerformed(ActionEvent actionEvent)
       {
-        colourByLabel_actionPerformed(actionEvent);
+        colourByLabel_actionPerformed();
       }
     });
+
+    JPanel colourPanel = new JPanel();
     colourPanel.setBackground(Color.white);
     jPanel1.add(ok);
     jPanel1.add(cancel);
-    jPanel2.add(colourByLabel, java.awt.BorderLayout.WEST);
-    jPanel2.add(colourPanel, java.awt.BorderLayout.EAST);
+    jPanel2.add(colourByLabel, BorderLayout.WEST);
+    jPanel2.add(colourPanel, BorderLayout.EAST);
     colourPanel.add(minText);
     colourPanel.add(minColour);
     colourPanel.add(maxText);
     colourPanel.add(maxColour);
-    this.add(jPanel3, java.awt.BorderLayout.CENTER);
+    this.add(jPanel3, BorderLayout.CENTER);
     jPanel3.add(threshold);
     jPanel3.add(slider);
     jPanel3.add(thresholdValue);
     jPanel3.add(thresholdIsMin);
-    this.add(jPanel1, java.awt.BorderLayout.SOUTH);
-    this.add(jPanel2, java.awt.BorderLayout.NORTH);
+    this.add(jPanel1, BorderLayout.SOUTH);
+    this.add(jPanel2, BorderLayout.NORTH);
   }
 
-  JLabel minText = new JLabel();
-
-  JLabel maxText = new JLabel();
-
-  JPanel minColour = new JPanel();
-
-  JPanel maxColour = new JPanel();
-
-  JPanel colourPanel = new JPanel();
-
-  JPanel jPanel1 = new JPanel();
-
-  JPanel jPanel2 = new JPanel();
-
-  BorderLayout borderLayout1 = new BorderLayout();
-
-  JComboBox threshold = new JComboBox();
-
-  FlowLayout flowLayout1 = new FlowLayout();
-
-  JPanel jPanel3 = new JPanel();
-
-  FlowLayout flowLayout2 = new FlowLayout();
-
-  JSlider slider = new JSlider();
-
-  JTextField thresholdValue = new JTextField(20);
-
-  // TODO implement GUI for tolower flag
-  // JCheckBox toLower = new JCheckBox();
-
-  JCheckBox thresholdIsMin = new JCheckBox();
-
-  JCheckBox colourByLabel = new JCheckBox();
-
-  private GraphLine threshline;
-
-  private Color oldmaxColour;
-
-  private Color oldminColour;
-
-  public void minColour_actionPerformed()
+  /**
+   * Action on clicking the 'minimum colour' - open a colour chooser dialog, and
+   * set the selected colour (if the user does not cancel out of the dialog)
+   */
+  protected void minColour_actionPerformed()
   {
     Color col = JColorChooser.showDialog(this,
             MessageManager.getString("label.select_colour_minimum_value"),
@@ -364,10 +360,14 @@ public class FeatureColourChooser extends JalviewDialog
       minColour.setForeground(col);
     }
     minColour.repaint();
-    changeColour();
+    changeColour(true);
   }
 
-  public void maxColour_actionPerformed()
+  /**
+   * Action on clicking the 'maximum colour' - open a colour chooser dialog, and
+   * set the selected colour (if the user does not cancel out of the dialog)
+   */
+  protected void maxColour_actionPerformed()
   {
     Color col = JColorChooser.showDialog(this,
             MessageManager.getString("label.select_colour_maximum_value"),
@@ -378,10 +378,17 @@ public class FeatureColourChooser extends JalviewDialog
       maxColour.setForeground(col);
     }
     maxColour.repaint();
-    changeColour();
+    changeColour(true);
   }
 
-  void changeColour()
+  /**
+   * Constructs and sets the selected colour options as the colour for the
+   * feature type, and repaints the alignment, and optionally the Overview
+   * and/or structure viewer if open
+   * 
+   * @param updateOverview
+   */
+  void changeColour(boolean updateOverview)
   {
     // Check if combobox is still adjusting
     if (adjusting)
@@ -413,7 +420,6 @@ public class FeatureColourChooser extends JalviewDialog
     {
       acg = new FeatureColour(oldminColour = minColour.getBackground(),
               oldmaxColour = maxColour.getBackground(), min, max);
-
     }
 
     if (!hasThreshold)
@@ -425,8 +431,11 @@ public class FeatureColourChooser extends JalviewDialog
     }
     else if (threshline == null)
     {
-      // todo visual indication of feature threshold
-      threshline = new GraphLine((max - min) / 2f, "Threshold", Color.black);
+      /*
+       * todo not yet implemented: visual indication of feature threshold
+       */
+      threshline = new GraphLine((max - min) / 2f, "Threshold",
+              Color.black);
     }
 
     if (hasThreshold)
@@ -438,7 +447,8 @@ public class FeatureColourChooser extends JalviewDialog
 
       slider.setMinimum((int) (min * scaleFactor));
       slider.setMaximum((int) (max * scaleFactor));
-      slider.setValue((int) (threshline.value * scaleFactor));
+      // slider.setValue((int) (threshline.value * scaleFactor));
+      slider.setValue(Math.round(threshline.value * scaleFactor));
       thresholdValue.setText(threshline.value + "");
       slider.setMajorTickSpacing((int) (range / 10f));
       slider.setEnabled(true);
@@ -487,7 +497,7 @@ public class FeatureColourChooser extends JalviewDialog
     }
     fr.setColour(type, acg);
     cs = acg;
-    ap.paintAlignment(false);
+    ap.paintAlignment(updateOverview);
   }
 
   @Override
@@ -502,7 +512,7 @@ public class FeatureColourChooser extends JalviewDialog
   @Override
   public void okPressed()
   {
-    changeColour();
+    changeColour(false);
   }
 
   @Override
@@ -511,68 +521,102 @@ public class FeatureColourChooser extends JalviewDialog
     reset();
   }
 
+  /**
+   * Action when the user cancels the dialog. All previous settings should be
+   * restored and rendered on the alignment, and any linked Overview window or
+   * structure.
+   */
   void reset()
   {
     fr.setColour(type, oldcs);
-    ap.paintAlignment(false);
+    ap.paintAlignment(true);
     cs = null;
   }
 
-  public void thresholdCheck_actionPerformed(ActionEvent e)
-  {
-    changeColour();
-  }
-
-  public void annotations_actionPerformed(ActionEvent e)
-  {
-    changeColour();
-  }
-
-  public void threshold_actionPerformed(ActionEvent e)
+  /**
+   * Action on change of choice of No / Above / Below Threshold
+   */
+  protected void threshold_actionPerformed()
   {
-    changeColour();
+    changeColour(true);
   }
 
-  public void thresholdValue_actionPerformed(ActionEvent e)
+  /**
+   * Action on text entry of a threshold value
+   */
+  protected void thresholdValue_actionPerformed()
   {
     try
     {
       float f = Float.parseFloat(thresholdValue.getText());
       slider.setValue((int) (f * scaleFactor));
       threshline.value = f;
+
+      /*
+       * force repaint of any Overview window or structure
+       */
+      ap.paintAlignment(true);
     } catch (NumberFormatException ex)
     {
     }
   }
 
-  public void valueChanged()
+  /**
+   * Action on change of threshold slider value. This may be done interactively
+   * (by moving the slider), or programmatically (to update the slider after
+   * manual input of a threshold value).
+   */
+  protected void sliderValueChanged()
   {
-    threshline.value = slider.getValue() / scaleFactor;
+    /*
+     * squash rounding errors by forcing min/max of slider to 
+     * actual min/max of feature score range
+     */
+    int value = slider.getValue();
+    threshline.value = value == slider.getMaximum() ? max
+            : (value == slider.getMinimum() ? min : value / scaleFactor);
     cs.setThreshold(threshline.value);
-    changeColour();
-    ap.paintAlignment(false);
+
+    /*
+     * repaint alignment, but not Overview or structure,
+     * to avoid overload while dragging the slider
+     */
+    changeColour(false);
   }
 
-  public void thresholdIsMin_actionPerformed(ActionEvent actionEvent)
+  protected void thresholdIsMin_actionPerformed()
   {
-    changeColour();
+    changeColour(true);
   }
 
-  public void colourByLabel_actionPerformed(ActionEvent actionEvent)
+  protected void colourByLabel_actionPerformed()
   {
-    changeColour();
+    changeColour(true);
   }
 
-  ActionListener colourEditor = null;
-
-  public void addActionListener(ActionListener graduatedColorEditor)
+  void addActionListener(ActionListener graduatedColorEditor)
   {
     if (colourEditor != null)
     {
-      System.err
-              .println("IMPLEMENTATION ISSUE: overwriting action listener for FeatureColourChooser");
+      System.err.println(
+              "IMPLEMENTATION ISSUE: overwriting action listener for FeatureColourChooser");
     }
     colourEditor = graduatedColorEditor;
   }
 
+  /**
+   * Answers the last colour setting selected by user - either oldcs (which may
+   * be a java.awt.Color) or the new GraduatedColor
+   * 
+   * @return
+   */
+  FeatureColourI getLastColour()
+  {
+    if (cs == null)
+    {
+      return oldcs;
+    }
+    return cs;
+  }
+
 }