JAL-2808 JAL-2069 FeatureTypeSettings (with new Filters tab) replaces FeatureColourCh...
[jalview.git] / src / jalview / gui / FeatureColourChooser.java
diff --git a/src/jalview/gui/FeatureColourChooser.java b/src/jalview/gui/FeatureColourChooser.java
deleted file mode 100644 (file)
index d3d9e1a..0000000
+++ /dev/null
@@ -1,1016 +0,0 @@
-/*
- * 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.FeatureColourI;
-import jalview.datamodel.GraphLine;
-import jalview.datamodel.features.FeatureAttributes;
-import jalview.schemes.FeatureColour;
-import jalview.util.MessageManager;
-
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.FlowLayout;
-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.ArrayList;
-import java.util.List;
-
-import javax.swing.BorderFactory;
-import javax.swing.BoxLayout;
-import javax.swing.ButtonGroup;
-import javax.swing.JCheckBox;
-import javax.swing.JColorChooser;
-import javax.swing.JComboBox;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.JRadioButton;
-import javax.swing.JSlider;
-import javax.swing.JTextField;
-import javax.swing.border.LineBorder;
-import javax.swing.event.ChangeEvent;
-import javax.swing.event.ChangeListener;
-
-public class FeatureColourChooser extends JalviewDialog
-{
-  private static final String COLON = ":";
-
-  private static final int MAX_TOOLTIP_LENGTH = 50;
-
-  private static int NO_COLOUR_OPTION = 0;
-
-  private static int MIN_COLOUR_OPTION = 1;
-
-  private static int MAX_COLOUR_OPTION = 2;
-
-  private FeatureRenderer fr;
-
-  private FeatureColourI cs;
-
-  private FeatureColourI oldcs;
-
-  private AlignmentPanel ap;
-
-  private boolean adjusting = false;
-
-  private float min;
-
-  private float max;
-
-  private float scaleFactor;
-
-  private String type = null;
-
-  private JPanel minColour = new JPanel();
-
-  private JPanel maxColour = new JPanel();
-
-  private Color noColour;
-
-  private JComboBox<String> threshold = new JComboBox<>();
-
-  private JSlider slider = new JSlider();
-
-  private JTextField thresholdValue = new JTextField(20);
-
-  private JCheckBox thresholdIsMin = new JCheckBox();
-
-  private GraphLine threshline;
-
-  private Color oldmaxColour;
-
-  private Color oldminColour;
-
-  private Color oldNoColour;
-
-  private ActionListener colourEditor = null;
-
-  /*
-   * radio buttons to select what to colour by
-   * label, attribute text, score, attribute value
-   */
-  private JRadioButton byDescription = new JRadioButton();
-
-  private JRadioButton byAttributeText = new JRadioButton();
-
-  private JRadioButton byScore = new JRadioButton();
-
-  private JRadioButton byAttributeValue = new JRadioButton();
-
-  private ActionListener changeColourAction;
-
-  private ActionListener changeMinMaxAction;
-
-  /*
-   * choice of option for 'colour for no value'
-   */
-  private JComboBox<String> noValueCombo;
-
-  /*
-   * choice of attribute (if any) for 'colour by text'
-   */
-  private JComboBox<String> textAttributeCombo;
-
-  /*
-   * choice of attribute (if any) for 'colour by value'
-   */
-  private JComboBox<String> valueAttributeCombo;
-
-  /**
-   * Constructor
-   * 
-   * @param frender
-   * @param theType
-   */
-  public FeatureColourChooser(FeatureRenderer frender, String theType)
-  {
-    this(frender, false, theType);
-  }
-
-  /**
-   * 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 = theType;
-    ap = fr.ap;
-    String title = MessageManager.formatMessage("label.variable_color_for",
-            new String[] { theType });
-    initDialogFrame(this, true, blocking, title, 470, 300);
-
-    slider.addChangeListener(new ChangeListener()
-    {
-      @Override
-      public void stateChanged(ChangeEvent evt)
-      {
-        if (!adjusting)
-        {
-          thresholdValue.setText((slider.getValue() / scaleFactor) + "");
-          sliderValueChanged();
-        }
-      }
-    });
-    slider.addMouseListener(new MouseAdapter()
-    {
-      @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, true);
-        }
-      }
-    });
-
-    // todo move all threshold setup inside a method
-    float mm[] = fr.getMinMax().get(theType)[0];
-    min = mm[0];
-    max = mm[1];
-
-    /*
-     * ensure scale factor allows a scaled range with
-     * 10 integer divisions ('ticks'); if we have got here,
-     * we should expect that max != min
-     */
-    scaleFactor = (max == min) ? 1f : 100f / (max - min);
-
-    oldcs = fr.getFeatureColours().get(theType);
-    if (!oldcs.isSimpleColour())
-    {
-      if (oldcs.isAutoScaled())
-      {
-        // update the scale
-        cs = new FeatureColour((FeatureColour) oldcs, min, max);
-      }
-      else
-      {
-        cs = new FeatureColour((FeatureColour) oldcs);
-      }
-    }
-    else
-    {
-      /*
-       * promote original simple color to a graduated color
-       * - by score if there is a score range, else by label
-       */
-      Color bl = oldcs.getColour();
-      if (bl == null)
-      {
-        bl = Color.BLACK;
-      }
-      // original colour becomes the maximum colour
-      cs = new FeatureColour(Color.white, bl, mm[0], mm[1]);
-      cs.setColourByLabel(mm[0] == mm[1]);
-    }
-    minColour.setBackground(oldminColour = cs.getMinColour());
-    maxColour.setBackground(oldmaxColour = cs.getMaxColour());
-    noColour = cs.getNoColour();
-
-    adjusting = true;
-
-    try
-    {
-      jbInit();
-    } catch (Exception ex)
-    {
-      ex.printStackTrace();
-      return;
-    }
-
-    /*
-     * set the initial state of options on screen
-     */
-    if (cs.isColourByLabel())
-    {
-      if (cs.isColourByAttribute())
-      {
-        byAttributeText.setSelected(true);
-        textAttributeCombo.setEnabled(true);
-        String[] attributeName = cs.getAttributeName();
-        textAttributeCombo
-                .setSelectedItem(toAttributeDisplayName(attributeName));
-      }
-      else
-      {
-        byDescription.setSelected(true);
-        textAttributeCombo.setEnabled(false);
-      }
-    }
-    else
-    {
-      if (cs.isColourByAttribute())
-      {
-        byAttributeValue.setSelected(true);
-        String[] attributeName = cs.getAttributeName();
-        valueAttributeCombo
-                .setSelectedItem(toAttributeDisplayName(attributeName));
-        valueAttributeCombo.setEnabled(true);
-        updateMinMax();
-      }
-      else
-      {
-        byScore.setSelected(true);
-        valueAttributeCombo.setEnabled(false);
-      }
-    }
-
-    if (noColour == null)
-    {
-      noValueCombo.setSelectedIndex(NO_COLOUR_OPTION);
-    }
-    else if (noColour.equals(oldminColour))
-    {
-      noValueCombo.setSelectedIndex(MIN_COLOUR_OPTION);
-    }
-    else if (noColour.equals(oldmaxColour))
-    {
-      noValueCombo.setSelectedIndex(MAX_COLOUR_OPTION);
-    }
-
-    threshline = new GraphLine((max - min) / 2f, "Threshold", Color.black);
-    threshline.value = cs.getThreshold();
-
-    if (cs.hasThreshold())
-    {
-      // initialise threshold slider and selector
-      threshold.setSelectedIndex(cs.isAboveThreshold() ? 1 : 2);
-      slider.setEnabled(true);
-      slider.setValue((int) (cs.getThreshold() * scaleFactor));
-      thresholdValue.setEnabled(true);
-    }
-
-    adjusting = false;
-
-    changeColour(false);
-    waitForInput();
-  }
-
-  /**
-   * Configures the initial layout
-   */
-  private void jbInit()
-  {
-    this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
-    this.setBackground(Color.white);
-
-    changeColourAction = new ActionListener()
-    {
-      @Override
-      public void actionPerformed(ActionEvent e)
-      {
-        changeColour(true);
-      }
-    };
-
-    changeMinMaxAction = new ActionListener()
-    {
-      @Override
-      public void actionPerformed(ActionEvent e)
-      {
-        updateMinMax();
-        changeColour(true);
-      }
-    };
-
-    /*
-     * this panel
-     *     detailsPanel
-     *         colourByTextPanel
-     *         colourByScorePanel
-     *     okCancelPanel
-     */
-    JPanel detailsPanel = new JPanel();
-    detailsPanel.setLayout(new BoxLayout(detailsPanel, BoxLayout.Y_AXIS));
-
-    JPanel colourByTextPanel = initColourByTextPanel();
-    detailsPanel.add(colourByTextPanel);
-
-    JPanel colourByValuePanel = initColourByValuePanel();
-    detailsPanel.add(colourByValuePanel);
-
-    /*
-     * 4 radio buttons select between colour by description, by
-     * attribute text, by score, or by attribute value
-     */
-    ButtonGroup bg = new ButtonGroup();
-    bg.add(byDescription);
-    bg.add(byAttributeText);
-    bg.add(byScore);
-    bg.add(byAttributeValue);
-
-    JPanel okCancelPanel = initOkCancelPanel();
-
-    this.add(detailsPanel);
-    this.add(okCancelPanel);
-  }
-
-  /**
-   * Updates the min-max range for a change in choice of Colour by Score, or
-   * Colour by Attribute (value)
-   */
-  protected void updateMinMax()
-  {
-    float[] minMax = null;
-    if (byScore.isSelected())
-    {
-      minMax = fr.getMinMax().get(type)[0];
-    }
-    else if (byAttributeValue.isSelected())
-    {
-      String attName = (String) valueAttributeCombo.getSelectedItem();
-      String[] attNames = fromAttributeDisplayName(attName);
-      minMax = FeatureAttributes.getInstance().getMinMax(type, attNames);
-    }
-    if (minMax != null)
-    {
-      min = minMax[0];
-      max = minMax[1];
-      scaleFactor = (max == min) ? 1f : 100f / (max - min);
-      slider.setValue((int) (min * scaleFactor));
-    }
-  }
-
-  /**
-   * Lay out fields for graduated colour by value
-   * 
-   * @return
-   */
-  protected JPanel initColourByValuePanel()
-  {
-    JPanel byValuePanel = new JPanel();
-    byValuePanel.setLayout(new BoxLayout(byValuePanel, BoxLayout.Y_AXIS));
-    JvSwingUtils.createItalicTitledBorder(byValuePanel,
-            MessageManager.getString("label.colour_by_value"), true);
-    byValuePanel.setBackground(Color.white);
-
-    /*
-     * first row - choose colour by score or by attribute, choose attribute
-     */
-    JPanel byWhatPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
-    byWhatPanel.setBackground(Color.white);
-    byValuePanel.add(byWhatPanel);
-
-    byScore.setText(MessageManager.getString("label.score"));
-    byWhatPanel.add(byScore);
-    byScore.addActionListener(changeMinMaxAction);
-
-    byAttributeValue.setText(MessageManager.getString("label.attribute"));
-    byAttributeValue.addActionListener(changeMinMaxAction);
-    byWhatPanel.add(byAttributeValue);
-
-    List<String[]> attNames = FeatureAttributes.getInstance()
-            .getAttributes(type);
-    valueAttributeCombo = populateAttributesDropdown(type, attNames, true);
-
-    /*
-     * if no numeric atttibutes found, disable colour by attribute value
-     */
-    if (valueAttributeCombo.getItemCount() == 0)
-    {
-      byAttributeValue.setEnabled(false);
-    }
-
-    byWhatPanel.add(valueAttributeCombo);
-
-    /*
-     * second row - min/max/no colours
-     */
-    JPanel colourRangePanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
-    colourRangePanel.setBackground(Color.white);
-    byValuePanel.add(colourRangePanel);
-
-    minColour.setFont(JvSwingUtils.getLabelFont());
-    minColour.setBorder(BorderFactory.createLineBorder(Color.black));
-    minColour.setPreferredSize(new Dimension(40, 20));
-    minColour.setToolTipText(MessageManager.getString("label.min_colour"));
-    minColour.addMouseListener(new MouseAdapter()
-    {
-      @Override
-      public void mousePressed(MouseEvent e)
-      {
-        if (minColour.isEnabled())
-        {
-          minColour_actionPerformed();
-        }
-      }
-    });
-
-    maxColour.setFont(JvSwingUtils.getLabelFont());
-    maxColour.setBorder(BorderFactory.createLineBorder(Color.black));
-    maxColour.setPreferredSize(new Dimension(40, 20));
-    maxColour.setToolTipText(MessageManager.getString("label.max_colour"));
-    maxColour.addMouseListener(new MouseAdapter()
-    {
-      @Override
-      public void mousePressed(MouseEvent e)
-      {
-        if (maxColour.isEnabled())
-        {
-          maxColour_actionPerformed();
-        }
-      }
-    });
-    maxColour.setBorder(new LineBorder(Color.black));
-
-    noValueCombo = new JComboBox<>();
-    noValueCombo.addItem(MessageManager.getString("label.no_colour"));
-    noValueCombo.addItem(MessageManager.getString("label.min_colour"));
-    noValueCombo.addItem(MessageManager.getString("label.max_colour"));
-    noValueCombo.addItemListener(new ItemListener()
-    {
-      @Override
-      public void itemStateChanged(ItemEvent e)
-      {
-        setNoValueColour();
-      }
-    });
-
-    JLabel minText = new JLabel(MessageManager.getString("label.min_value"));
-    minText.setFont(JvSwingUtils.getLabelFont());
-    JLabel maxText = new JLabel(MessageManager.getString("label.max_value"));
-    maxText.setFont(JvSwingUtils.getLabelFont());
-    JLabel noText = new JLabel(MessageManager.getString("label.no_value"));
-    noText.setFont(JvSwingUtils.getLabelFont());
-
-    colourRangePanel.add(minText);
-    colourRangePanel.add(minColour);
-    colourRangePanel.add(maxText);
-    colourRangePanel.add(maxColour);
-    colourRangePanel.add(noText);
-    colourRangePanel.add(noValueCombo);
-
-    /*
-     * third row - threshold options and value
-     */
-    JPanel thresholdPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
-    thresholdPanel.setBackground(Color.white);
-    byValuePanel.add(thresholdPanel);
-
-    threshold.addActionListener(changeColourAction);
-    threshold.setToolTipText(MessageManager
-            .getString("label.threshold_feature_display_by_score"));
-    threshold.addItem(MessageManager
-            .getString("label.threshold_feature_no_threshold")); // index 0
-    threshold.addItem(MessageManager
-            .getString("label.threshold_feature_above_threshold")); // index 1
-    threshold.addItem(MessageManager
-            .getString("label.threshold_feature_below_threshold")); // index 2
-
-    thresholdValue.addActionListener(new ActionListener()
-    {
-      @Override
-      public void actionPerformed(ActionEvent e)
-      {
-        thresholdValue_actionPerformed();
-      }
-    });
-    thresholdValue.addFocusListener(new FocusAdapter()
-    {
-      @Override
-      public void focusLost(FocusEvent 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));
-    slider.setToolTipText(MessageManager
-            .getString("label.adjust_threshold"));
-    thresholdValue.setEnabled(false);
-    thresholdValue.setColumns(7);
-
-    thresholdPanel.add(threshold);
-    thresholdPanel.add(slider);
-    thresholdPanel.add(thresholdValue);
-
-    /*
-     * 4th row - threshold is min / max
-     */
-    JPanel isMinMaxPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
-    isMinMaxPanel.setBackground(Color.white);
-    byValuePanel.add(isMinMaxPanel);
-    thresholdIsMin.setBackground(Color.white);
-    thresholdIsMin.setText(MessageManager
-            .getString("label.threshold_minmax"));
-    thresholdIsMin.setToolTipText(MessageManager
-            .getString("label.toggle_absolute_relative_display_threshold"));
-    thresholdIsMin.addActionListener(changeColourAction);
-    isMinMaxPanel.add(thresholdIsMin);
-
-    return byValuePanel;
-  }
-
-  /**
-   * Action on user choice of no / min / max colour to use when there is no
-   * value to colour by
-   */
-  protected void setNoValueColour()
-  {
-    int i = noValueCombo.getSelectedIndex();
-    if (i == NO_COLOUR_OPTION)
-    {
-      noColour = null;
-    }
-    else if (i == MIN_COLOUR_OPTION)
-    {
-      noColour = minColour.getBackground();
-    }
-    else if (i == MAX_COLOUR_OPTION)
-    {
-      noColour = maxColour.getBackground();
-    }
-    changeColour(true);
-  }
-
-  /**
-   * Lay out OK and Cancel buttons
-   * 
-   * @return
-   */
-  protected JPanel initOkCancelPanel()
-  {
-    JPanel okCancelPanel = new JPanel();
-    okCancelPanel.setBackground(Color.white);
-    okCancelPanel.add(ok);
-    okCancelPanel.add(cancel);
-    return okCancelPanel;
-  }
-
-  /**
-   * Lay out Colour by Label and attribute choice elements
-   * 
-   * @return
-   */
-  protected JPanel initColourByTextPanel()
-  {
-    JPanel byTextPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
-    byTextPanel.setBackground(Color.white);
-    JvSwingUtils.createItalicTitledBorder(byTextPanel,
-            MessageManager.getString("label.colour_by_text"), true);
-
-    byDescription.setText(MessageManager.getString("label.label"));
-    byDescription.setToolTipText(MessageManager
-            .getString("label.colour_by_label_tip"));
-    byDescription.addActionListener(changeColourAction);
-    byTextPanel.add(byDescription);
-
-    byAttributeText.setText(MessageManager.getString("label.attribute"));
-    byAttributeText.addActionListener(changeColourAction);
-    byTextPanel.add(byAttributeText);
-
-    List<String[]> attNames = FeatureAttributes.getInstance()
-            .getAttributes(type);
-    textAttributeCombo = populateAttributesDropdown(type, attNames, false);
-    byTextPanel.add(textAttributeCombo);
-
-    /*
-     * disable colour by attribute if no attributes
-     */
-    if (attNames.isEmpty())
-    {
-      byAttributeText.setEnabled(false);
-    }
-
-    return byTextPanel;
-  }
-
-  /**
-   * 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"),
-            minColour.getBackground());
-    if (col != null)
-    {
-      minColour.setBackground(col);
-      minColour.setForeground(col);
-    }
-    minColour.repaint();
-    changeColour(true);
-  }
-
-  /**
-   * 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"),
-            maxColour.getBackground());
-    if (col != null)
-    {
-      maxColour.setBackground(col);
-      maxColour.setForeground(col);
-    }
-    maxColour.repaint();
-    changeColour(true);
-  }
-
-  /**
-   * 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 updateStructsAndOverview
-   */
-  void changeColour(boolean updateStructsAndOverview)
-  {
-    // Check if combobox is still adjusting
-    if (adjusting)
-    {
-      return;
-    }
-
-    boolean aboveThreshold = false;
-    boolean belowThreshold = false;
-    if (threshold.getSelectedIndex() == 1)
-    {
-      aboveThreshold = true;
-    }
-    else if (threshold.getSelectedIndex() == 2)
-    {
-      belowThreshold = true;
-    }
-    boolean hasThreshold = aboveThreshold || belowThreshold;
-
-    slider.setEnabled(true);
-    thresholdValue.setEnabled(true);
-
-    /*
-     * make the feature colour
-     */
-    FeatureColourI acg;
-    if (cs.isColourByLabel())
-    {
-      acg = new FeatureColour(oldminColour, oldmaxColour, min, max);
-    }
-    else
-    {
-      acg = new FeatureColour(oldminColour = minColour.getBackground(),
-              oldmaxColour = maxColour.getBackground(),
-              oldNoColour = noColour, min, max);
-    }
-    String attribute = null;
-    textAttributeCombo.setEnabled(false);
-    valueAttributeCombo.setEnabled(false);
-    if (byAttributeText.isSelected())
-    {
-      attribute = (String) textAttributeCombo.getSelectedItem();
-      textAttributeCombo.setEnabled(true);
-      acg.setAttributeName(fromAttributeDisplayName(attribute));
-    }
-    else if (byAttributeValue.isSelected())
-    {
-      attribute = (String) valueAttributeCombo.getSelectedItem();
-      valueAttributeCombo.setEnabled(true);
-      acg.setAttributeName(fromAttributeDisplayName(attribute));
-    }
-    else
-    {
-      acg.setAttributeName((String[]) null);
-    }
-
-    if (!hasThreshold)
-    {
-      slider.setEnabled(false);
-      thresholdValue.setEnabled(false);
-      thresholdValue.setText("");
-      thresholdIsMin.setEnabled(false);
-    }
-    else if (threshline == null)
-    {
-      /*
-       * todo not yet implemented: visual indication of feature threshold
-       */
-      threshline = new GraphLine((max - min) / 2f, "Threshold",
-              Color.black);
-    }
-
-    if (hasThreshold)
-    {
-      adjusting = true;
-      acg.setThreshold(threshline.value);
-
-      float range = (max - min) * scaleFactor;
-
-      slider.setMinimum((int) (min * scaleFactor));
-      slider.setMaximum((int) (max * 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);
-      thresholdValue.setEnabled(true);
-      thresholdIsMin.setEnabled(!byDescription.isSelected());
-      adjusting = false;
-    }
-
-    acg.setAboveThreshold(aboveThreshold);
-    acg.setBelowThreshold(belowThreshold);
-    if (thresholdIsMin.isSelected() && hasThreshold)
-    {
-      acg.setAutoScaled(false);
-      if (aboveThreshold)
-      {
-        acg = new FeatureColour((FeatureColour) acg, threshline.value, max);
-      }
-      else
-      {
-        acg = new FeatureColour((FeatureColour) acg, min, threshline.value);
-      }
-    }
-    else
-    {
-      acg.setAutoScaled(true);
-    }
-    acg.setColourByLabel(byDescription.isSelected()
-            || byAttributeText.isSelected());
-
-    if (acg.isColourByLabel())
-    {
-      maxColour.setEnabled(false);
-      minColour.setEnabled(false);
-      noValueCombo.setEnabled(false);
-      maxColour.setBackground(this.getBackground());
-      maxColour.setForeground(this.getBackground());
-      minColour.setBackground(this.getBackground());
-      minColour.setForeground(this.getBackground());
-    }
-    else
-    {
-      maxColour.setEnabled(true);
-      minColour.setEnabled(true);
-      noValueCombo.setEnabled(true);
-      maxColour.setBackground(oldmaxColour);
-      maxColour.setForeground(oldmaxColour);
-      minColour.setBackground(oldminColour);
-      minColour.setForeground(oldminColour);
-      noColour = oldNoColour;
-    }
-
-    /*
-     * save the colour, and repaint stuff
-     */
-    fr.setColour(type, acg);
-    cs = acg;
-    ap.paintAlignment(updateStructsAndOverview, updateStructsAndOverview);
-  }
-
-  private String[] fromAttributeDisplayName(String attribute)
-  {
-    return attribute == null ? null : attribute.split(COLON);
-  }
-
-  @Override
-  protected void raiseClosed()
-  {
-    if (this.colourEditor != null)
-    {
-      colourEditor.actionPerformed(new ActionEvent(this, 0, "CLOSED"));
-    }
-  }
-
-  @Override
-  public void okPressed()
-  {
-    changeColour(false);
-  }
-
-  @Override
-  public void cancelPressed()
-  {
-    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(true, true);
-    cs = null;
-  }
-
-  /**
-   * 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, true);
-    } catch (NumberFormatException ex)
-    {
-    }
-  }
-
-  /**
-   * 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()
-  {
-    /*
-     * 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);
-
-    /*
-     * repaint alignment, but not Overview or structure,
-     * to avoid overload while dragging the slider
-     */
-    changeColour(false);
-  }
-
-  void addActionListener(ActionListener graduatedColorEditor)
-  {
-    if (colourEditor != null)
-    {
-      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;
-  }
-
-  /**
-   * A helper method to build the drop-down choice of attributes for a feature.
-   * Where metadata is available with a description for an attribute, that is
-   * added as a tooltip. The list may optionally be restricted to attributes for
-   * which we hold a range of numerical values (so suitable candidates for a
-   * graduated colour scheme).
-   * <p>
-   * Attribute names may be 'simple' e.g. "AC" or 'compound' e.g. {"CSQ",
-   * "Allele"}. Compound names are rendered for display as (e.g.) CSQ:Allele.
-   * 
-   * @param featureType
-   * @param attNames
-   * @param withNumericRange
-   */
-  protected JComboBox<String> populateAttributesDropdown(
-          String featureType, List<String[]> attNames,
-          boolean withNumericRange)
-  {
-    List<String> validAtts = new ArrayList<>();
-    List<String> tooltips = new ArrayList<>();
-
-    FeatureAttributes fa = FeatureAttributes.getInstance();
-    for (String[] attName : attNames)
-    {
-      if (withNumericRange)
-      {
-        float[] minMax = fa.getMinMax(featureType, attName);
-        if (minMax == null)
-        {
-          continue;
-        }
-      }
-      validAtts.add(toAttributeDisplayName(attName));
-      String desc = fa.getDescription(featureType, attName);
-      if (desc != null && desc.length() > MAX_TOOLTIP_LENGTH)
-      {
-        desc = desc.substring(0, MAX_TOOLTIP_LENGTH) + "...";
-      }
-      tooltips.add(desc == null ? "" : desc);
-    }
-
-    JComboBox<String> attCombo = JvSwingUtils.buildComboWithTooltips(
-            validAtts, tooltips);
-
-    attCombo.addItemListener(new ItemListener()
-    {
-      @Override
-      public void itemStateChanged(ItemEvent e)
-      {
-        changeMinMaxAction.actionPerformed(null);
-      }
-    });
-
-    if (validAtts.isEmpty())
-    {
-      attCombo.setToolTipText(MessageManager
-              .getString(withNumericRange ? "label.no_numeric_attributes"
-                      : "label.no_attributes"));
-    }
-
-    return attCombo;
-  }
-
-  private String toAttributeDisplayName(String[] attName)
-  {
-    return attName == null ? "" : String.join(COLON, attName);
-  }
-
-}