import javax.swing.JColorChooser;
import javax.swing.JComboBox;
import javax.swing.JLabel;
-import javax.swing.JMenuItem;
import javax.swing.JPanel;
-import javax.swing.JPopupMenu;
import javax.swing.JRadioButton;
import javax.swing.JSlider;
import javax.swing.JTextField;
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 JPanel maxColour = new JPanel();
- private JPanel noColour = new JPanel();
+ private Color noColour;
private JComboBox<String> threshold = new JComboBox<>();
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'
*/
this.fr = frender;
this.type = theType;
ap = fr.ap;
- String title = MessageManager
- .formatMessage("label.graduated_color_for_params", new String[]
- { theType });
- initDialogFrame(this, true, blocking, title, 450, 300);
+ String title = MessageManager.formatMessage("label.variable_color_for",
+ new String[] { theType });
+ initDialogFrame(this, true, blocking, title, 470, 300);
slider.addChangeListener(new ChangeListener()
{
}
});
+ // todo move all threshold setup inside a method
float mm[] = fr.getMinMax().get(theType)[0];
min = mm[0];
max = mm[1];
}
minColour.setBackground(oldminColour = cs.getMinColour());
maxColour.setBackground(oldmaxColour = cs.getMaxColour());
- noColour.setBackground(oldNoColour = cs.getNoColour());
+ noColour = cs.getNoColour();
+
adjusting = true;
try
/*
* set the initial state of options on screen
*/
- thresholdIsMin.setSelected(!cs.isAutoScaled());
-
if (cs.isColourByLabel())
{
if (cs.isColourByAttribute())
{
byAttributeText.setSelected(true);
textAttributeCombo.setEnabled(true);
- textAttributeCombo.setSelectedItem(cs.getAttributeName());
+ String[] attributeName = cs.getAttributeName();
+ textAttributeCombo
+ .setSelectedItem(String.join(COLON, attributeName));
}
else
{
if (cs.isColourByAttribute())
{
byAttributeValue.setSelected(true);
- String attributeName = cs.getAttributeName();
- valueAttributeCombo.setSelectedItem(attributeName);
+ String[] attributeName = cs.getAttributeName();
+ valueAttributeCombo
+ .setSelectedItem(String.join(COLON, attributeName));
valueAttributeCombo.setEnabled(true);
- setAttributeMinMax(attributeName);
+ updateMinMax();
}
else
{
}
}
+ 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
slider.setEnabled(true);
slider.setValue((int) (cs.getThreshold() * scaleFactor));
thresholdValue.setEnabled(true);
- threshline = new GraphLine((max - min) / 2f, "Threshold",
- Color.black);
- threshline.value = cs.getThreshold();
}
adjusting = false;
this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
this.setBackground(Color.white);
- changeColourAction = new ActionListener() {
+ changeColourAction = new ActionListener()
+ {
@Override
public void actionPerformed(ActionEvent e)
{
}
};
+ changeMinMaxAction = new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ updateMinMax();
+ changeColour(true);
+ }
+ };
+
/*
* this panel
* detailsPanel
}
/**
+ * 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 = attName.split(COLON);
+ 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
{
JPanel byValuePanel = new JPanel();
byValuePanel.setLayout(new BoxLayout(byValuePanel, BoxLayout.Y_AXIS));
- byValuePanel.setBorder(BorderFactory.createTitledBorder(MessageManager
- .getString("label.colour_by_value")));
+ JvSwingUtils.createItalicTitledBorder(byValuePanel,
+ MessageManager.getString("label.colour_by_value"), true);
byValuePanel.setBackground(Color.white);
/*
byScore.setText(MessageManager.getString("label.score"));
byWhatPanel.add(byScore);
- byScore.addActionListener(changeColourAction);
+ byScore.addActionListener(changeMinMaxAction);
- byAttributeValue.setText(MessageManager
-.getString("label.attribute"));
- byAttributeValue.addActionListener(changeColourAction);
+ byAttributeValue.setText(MessageManager.getString("label.attribute"));
+ byAttributeValue.addActionListener(changeMinMaxAction);
byWhatPanel.add(byAttributeValue);
- List<String> attNames = FeatureAttributes.getInstance().getAttributes(
- type);
- valueAttributeCombo = populateAttributesDropdown(type, attNames,
- true);
+ List<String[]> attNames = FeatureAttributes.getInstance()
+ .getAttributes(type);
+ valueAttributeCombo = populateAttributesDropdown(type, attNames, true);
/*
* if no numeric atttibutes found, disable colour by attribute value
});
maxColour.setBorder(new LineBorder(Color.black));
- noColour.setFont(JvSwingUtils.getLabelFont());
- noColour.setBorder(BorderFactory.createLineBorder(Color.black));
- noColour.setPreferredSize(new Dimension(40, 20));
- noColour.setToolTipText("Colour if feature has no attribute value");
- noColour.addMouseListener(new MouseAdapter()
+ 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 mousePressed(MouseEvent e)
- {
- if (e.isPopupTrigger()) // Mac: mouseReleased
- {
- showNoColourPopup(e);
- return;
- }
- if (noColour.isEnabled())
- {
- noColour_actionPerformed();
- }
- }
-
- @Override
- public void mouseReleased(MouseEvent e)
+ public void itemStateChanged(ItemEvent e)
{
- if (e.isPopupTrigger()) // Windows: mouseReleased
- {
- showNoColourPopup(e);
- e.consume();
- return;
- }
+ setNoValueColour();
}
});
- noColour.setBorder(new LineBorder(Color.black));
- JLabel minText = new JLabel(MessageManager.getString("label.min"));
+ JLabel minText = new JLabel(MessageManager.getString("label.min_value"));
minText.setFont(JvSwingUtils.getLabelFont());
- JLabel maxText = new JLabel(MessageManager.getString("label.max"));
+ JLabel maxText = new JLabel(MessageManager.getString("label.max_value"));
maxText.setFont(JvSwingUtils.getLabelFont());
- JLabel noText = new JLabel(MessageManager.getString("label.no_colour"));
+ JLabel noText = new JLabel(MessageManager.getString("label.no_value"));
noText.setFont(JvSwingUtils.getLabelFont());
colourRangePanel.add(minText);
colourRangePanel.add(maxText);
colourRangePanel.add(maxColour);
colourRangePanel.add(noText);
- colourRangePanel.add(noColour);
+ colourRangePanel.add(noValueCombo);
/*
* third row - threshold options and value
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);
isMinMaxPanel.setBackground(Color.white);
byValuePanel.add(isMinMaxPanel);
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(changeColourAction);
}
/**
- * Show a popup menu with options to make 'no value colour' the same as Min
- * Colour or Max Colour
- *
- * @param evt
+ * Action on user choice of no / min / max colour to use when there is no
+ * value to colour by
*/
- protected void showNoColourPopup(MouseEvent evt)
+ protected void setNoValueColour()
{
- JPopupMenu pop = new JPopupMenu();
-
- JMenuItem copyMin = new JMenuItem(
- MessageManager.getString("label.min_colour"));
- copyMin.addActionListener((new ActionListener()
+ int i = noValueCombo.getSelectedIndex();
+ if (i == NO_COLOUR_OPTION)
{
- @Override
- public void actionPerformed(ActionEvent e)
- {
- noColour.setBackground(minColour.getBackground());
- changeColour(true);
- }
- }));
- pop.add(copyMin);
-
- JMenuItem copyMax = new JMenuItem(
- MessageManager.getString("label.max_colour"));
- copyMax.addActionListener((new ActionListener()
+ noColour = null;
+ }
+ else if (i == MIN_COLOUR_OPTION)
{
- @Override
- public void actionPerformed(ActionEvent e)
- {
- noColour.setBackground(maxColour.getBackground());
- changeColour(true);
- }
- }));
- pop.add(copyMax);
-
- pop.show(noColour, evt.getX(), evt.getY());
+ noColour = minColour.getBackground();
+ }
+ else if (i == MAX_COLOUR_OPTION)
+ {
+ noColour = maxColour.getBackground();
+ }
+ changeColour(true);
}
/**
{
JPanel byTextPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
byTextPanel.setBackground(Color.white);
- byTextPanel.setBorder(BorderFactory.createTitledBorder(MessageManager
- .getString("label.colour_by_text")));
+ JvSwingUtils.createItalicTitledBorder(byTextPanel,
+ MessageManager.getString("label.colour_by_text"), true);
byDescription.setText(MessageManager.getString("label.label"));
byDescription.setToolTipText(MessageManager
byAttributeText.addActionListener(changeColourAction);
byTextPanel.add(byAttributeText);
- List<String> attNames = FeatureAttributes.getInstance().getAttributes(
- type);
+ List<String[]> attNames = FeatureAttributes.getInstance()
+ .getAttributes(type);
textAttributeCombo = populateAttributesDropdown(type, attNames, false);
byTextPanel.add(textAttributeCombo);
}
/**
- * Action on clicking the 'no colour' - open a colour chooser dialog, and set
- * the selected colour (if the user does not cancel out of the dialog)
- */
- protected void noColour_actionPerformed()
- {
- Color col = JColorChooser.showDialog(this,
- MessageManager.getString("label.select_no_value_colour"),
- noColour.getBackground());
- if (col != null)
- {
- noColour.setBackground(col);
- noColour.setForeground(col);
- }
- noColour.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
{
acg = new FeatureColour(oldminColour = minColour.getBackground(),
oldmaxColour = maxColour.getBackground(),
- oldNoColour = noColour.getBackground(), min, max);
+ oldNoColour = noColour, min, max);
}
String attribute = null;
textAttributeCombo.setEnabled(false);
{
attribute = (String) textAttributeCombo.getSelectedItem();
textAttributeCombo.setEnabled(true);
+ acg.setAttributeName(attribute.split(COLON));
}
else if (byAttributeValue.isSelected())
{
attribute = (String) valueAttributeCombo.getSelectedItem();
valueAttributeCombo.setEnabled(true);
+ acg.setAttributeName(attribute.split(COLON));
+ }
+ else
+ {
+ acg.setAttributeName((String) null);
}
- acg.setAttributeName(attribute);
if (!hasThreshold)
{
{
maxColour.setEnabled(false);
minColour.setEnabled(false);
- noColour.setEnabled(false);
+ noValueCombo.setEnabled(false);
maxColour.setBackground(this.getBackground());
maxColour.setForeground(this.getBackground());
minColour.setBackground(this.getBackground());
minColour.setForeground(this.getBackground());
- noColour.setBackground(this.getBackground());
- noColour.setForeground(this.getBackground());
}
else
{
maxColour.setEnabled(true);
minColour.setEnabled(true);
- noColour.setEnabled(true);
+ noValueCombo.setEnabled(true);
maxColour.setBackground(oldmaxColour);
maxColour.setForeground(oldmaxColour);
minColour.setBackground(oldminColour);
minColour.setForeground(oldminColour);
- noColour.setBackground(oldNoColour);
- noColour.setForeground(oldNoColour);
+ noColour = oldNoColour;
}
/*
/**
* 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 be restricted to attributes for which we
- * hold a range of numerical values (so suitable candidates for a graduated
- * colour scheme).
+ * 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,
+ 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)
+ for (String[] attName : attNames)
{
if (withNumericRange)
{
continue;
}
}
- validAtts.add(attName);
+ validAtts.add(String.join(COLON, attName));
String desc = fa.getDescription(featureType, attName);
if (desc != null && desc.length() > MAX_TOOLTIP_LENGTH)
{
@Override
public void itemStateChanged(ItemEvent e)
{
- setAttributeMinMax(attCombo.getSelectedItem().toString());
- changeColour(true);
+ changeMinMaxAction.actionPerformed(null);
}
});
return attCombo;
}
- /**
- * Updates the min-max range and scale to be that for the given attribute name
- *
- * @param attributeName
- */
- protected void setAttributeMinMax(String attributeName)
- {
- float[] minMax = FeatureAttributes.getInstance().getMinMax(type,
- attributeName);
- if (minMax != null)
- {
- min = minMax[0];
- max = minMax[1];
- scaleFactor = (max == min) ? 1f : 100f / (max - min);
- }
- }
-
}