+++ /dev/null
-/*
- * 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);
- }
-
-}