X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fgui%2FFeatureTypeSettings.java;h=512cf0652ee6d9fd28f88ea87c23ecf167d080f5;hb=6b56f0140b759b789da51aa4ed327d43297a3a5d;hp=58bbbe8848f4d73634fdd63a271473a9e3941be5;hpb=403014222ea05e99c1bddeb6aaf3a85078f99756;p=jalview.git diff --git a/src/jalview/gui/FeatureTypeSettings.java b/src/jalview/gui/FeatureTypeSettings.java index 58bbbe8..512cf06 100644 --- a/src/jalview/gui/FeatureTypeSettings.java +++ b/src/jalview/gui/FeatureTypeSettings.java @@ -20,8 +20,10 @@ */ package jalview.gui; +import jalview.api.AlignViewportI; import jalview.api.AlignmentViewPanel; import jalview.api.FeatureColourI; +import jalview.bin.Cache; import jalview.datamodel.GraphLine; import jalview.datamodel.features.FeatureAttributes; import jalview.datamodel.features.FeatureAttributes.Datatype; @@ -47,6 +49,8 @@ import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import java.math.BigDecimal; +import java.math.MathContext; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.List; @@ -61,13 +65,11 @@ 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.SwingConstants; +import javax.swing.border.EmptyBorder; import javax.swing.border.LineBorder; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; -import javax.swing.plaf.basic.BasicArrowButton; /** * A dialog where the user can configure colour scheme, and any filters, for one @@ -78,6 +80,8 @@ import javax.swing.plaf.basic.BasicArrowButton; */ public class FeatureTypeSettings extends JalviewDialog { + private final static MathContext FOUR_SIG_FIG = new MathContext(4); + private final static String LABEL_18N = MessageManager .getString("label.label"); @@ -141,11 +145,6 @@ public class FeatureTypeSettings extends JalviewDialog private float max; /* - * scale factor for conversion between absolute min-max and slider - */ - private float scaleFactor; - - /* * radio button group, to select what to colour by: * simple colour, by category (text), or graduated */ @@ -166,9 +165,9 @@ public class FeatureTypeSettings extends JalviewDialog private JPanel maxColour = new JPanel(); - private JComboBox threshold = new JComboBox<>(); + private JComboBox threshold = new JComboBox<>(); - private JSlider slider = new JSlider(); + private Slider slider; private JTextField thresholdValue = new JTextField(20); @@ -183,17 +182,17 @@ public class FeatureTypeSettings extends JalviewDialog /* * choice of option for 'colour for no value' */ - private JComboBox noValueCombo; + private JComboBox noValueCombo; /* * choice of what to colour by text (Label or attribute) */ - private JComboBox colourByTextCombo; + private JComboBox colourByTextCombo; /* * choice of what to colour by range (Score or attribute) */ - private JComboBox colourByRangeCombo; + private JComboBox colourByRangeCombo; private JRadioButton andFilters; @@ -347,12 +346,11 @@ public class FeatureTypeSettings extends JalviewDialog * update min-max scaling if there is a range to work with, * else disable the widgets (this shouldn't happen if only * valid options are offered in the combo box) + * offset slider to have only non-negative values if necessary (JAL-2983) */ - scaleFactor = (max == min) ? 1f : 100f / (max - min); - float range = (max - min) * scaleFactor; - slider.setMinimum((int) (min * scaleFactor)); - slider.setMaximum((int) (max * scaleFactor)); - slider.setMajorTickSpacing((int) (range / 10f)); + slider.setSliderModel(min, max, min); + slider.setMajorTickSpacing( + (int) ((slider.getMaximum() - slider.getMinimum()) / 10f)); threshline = new GraphLine((max - min) / 2f, "Threshold", Color.black); @@ -364,8 +362,8 @@ public class FeatureTypeSettings extends JalviewDialog fc.isAboveThreshold() ? ABOVE_THRESHOLD_OPTION : BELOW_THRESHOLD_OPTION); slider.setEnabled(true); - slider.setValue((int) (fc.getThreshold() * scaleFactor)); - thresholdValue.setText(String.valueOf(fc.getThreshold())); + slider.setSliderValue(fc.getThreshold()); + setThresholdValueText(fc.getThreshold()); thresholdValue.setEnabled(true); thresholdIsMin.setEnabled(true); } @@ -562,13 +560,20 @@ public class FeatureTypeSettings extends JalviewDialog maxColour.setBorder(new LineBorder(Color.black)); /* - * default max colour to last plain colour; - * make min colour a pale version of max colour + * if not set, default max colour to last plain colour, + * and make min colour a pale version of max colour */ - FeatureColourI fc = fr.getFeatureColours().get(featureType); - Color bg = fc.getColour() == null ? Color.BLACK : fc.getColour(); - maxColour.setBackground(bg); - minColour.setBackground(ColorUtils.bleachColour(bg, 0.9f)); + Color max = originalColour.getMaxColour(); + if (max == null) + { + max = originalColour.getColour(); + minColour.setBackground(ColorUtils.bleachColour(max, 0.9f)); + } + else + { + maxColour.setBackground(max); + minColour.setBackground(originalColour.getMinColour()); + } noValueCombo = new JComboBox<>(); noValueCombo.addItem(MessageManager.getString("label.no_colour")); @@ -633,6 +638,7 @@ public class FeatureTypeSettings extends JalviewDialog thresholdValue_actionPerformed(); } }); + slider = new Slider(0f, 100f, 50f); slider.setPaintLabels(false); slider.setPaintTicks(true); slider.setBackground(Color.white); @@ -649,8 +655,7 @@ public class FeatureTypeSettings extends JalviewDialog { if (!adjusting) { - thresholdValue - .setText(String.valueOf(slider.getValue() / scaleFactor)); + setThresholdValueText(slider.getSliderValue()); thresholdValue.setBackground(Color.white); // to reset red for invalid sliderValueChanged(); } @@ -667,7 +672,7 @@ public class FeatureTypeSettings extends JalviewDialog */ if (ap != null) { - ap.paintAlignment(true, true); + refreshDisplay(true); } } }); @@ -747,16 +752,16 @@ public class FeatureTypeSettings extends JalviewDialog singleColour.setFont(JvSwingUtils.getLabelFont()); singleColour.setBorder(BorderFactory.createLineBorder(Color.black)); singleColour.setPreferredSize(new Dimension(40, 20)); - if (originalColour.isGraduatedColour()) - { - singleColour.setBackground(originalColour.getMaxColour()); - singleColour.setForeground(originalColour.getMaxColour()); - } - else - { + // if (originalColour.isGraduatedColour()) + // { + // singleColour.setBackground(originalColour.getMaxColour()); + // singleColour.setForeground(originalColour.getMaxColour()); + // } + // else + // { singleColour.setBackground(originalColour.getColour()); singleColour.setForeground(originalColour.getColour()); - } + // } singleColour.addMouseListener(new MouseAdapter() { @Override @@ -868,7 +873,7 @@ public class FeatureTypeSettings extends JalviewDialog * save the colour, and repaint stuff */ fr.setColour(featureType, acg); - ap.paintAlignment(updateStructsAndOverview, updateStructsAndOverview); + refreshDisplay(updateStructsAndOverview); updateColoursTab(); } @@ -881,42 +886,9 @@ public class FeatureTypeSettings extends JalviewDialog private FeatureColourI makeColourFromInputs() { /* - * easiest case - a single colour - */ - if (simpleColour.isSelected()) - { - return new FeatureColour(singleColour.getBackground()); - } - - /* - * next easiest case - colour by Label, or attribute text - */ - if (byCategory.isSelected()) - { - Color c = singleColour.getBackground(); - FeatureColourI fc = new FeatureColour(c); - fc.setColourByLabel(true); - String byWhat = (String) colourByTextCombo.getSelectedItem(); - if (!LABEL_18N.equals(byWhat)) - { - fc.setAttributeName( - FeatureMatcher.fromAttributeDisplayName(byWhat)); - } - return fc; - } - - /* - * remaining case - graduated colour by score, or attribute value + * min-max range is to (or from) threshold value if + * 'threshold is min/max' is selected */ - Color noColour = null; - if (noValueCombo.getSelectedIndex() == MIN_COLOUR_OPTION) - { - noColour = minColour.getBackground(); - } - else if (noValueCombo.getSelectedIndex() == MAX_COLOUR_OPTION) - { - noColour = maxColour.getBackground(); - } float thresh = 0f; try @@ -926,11 +898,6 @@ public class FeatureTypeSettings extends JalviewDialog { // invalid inputs are already handled on entry } - - /* - * min-max range is to (or from) threshold value if - * 'threshold is min/max' is selected - */ float minValue = min; float maxValue = max; final int thresholdOption = threshold.getSelectedIndex(); @@ -944,14 +911,50 @@ public class FeatureTypeSettings extends JalviewDialog { maxValue = thresh; } + Color noColour = null; + if (noValueCombo.getSelectedIndex() == MIN_COLOUR_OPTION) + { + noColour = minColour.getBackground(); + } + else if (noValueCombo.getSelectedIndex() == MAX_COLOUR_OPTION) + { + noColour = maxColour.getBackground(); + } + + /* + * construct a colour that 'remembers' all the options, including + * those not currently selected + */ + FeatureColourI fc = new FeatureColour(singleColour.getBackground(), + minColour.getBackground(), maxColour.getBackground(), noColour, + minValue, maxValue); + + /* + * easiest case - a single colour + */ + if (simpleColour.isSelected()) + { + ((FeatureColour) fc).setGraduatedColour(false); + return fc; + } /* - * make the graduated colour + * next easiest case - colour by Label, or attribute text */ - FeatureColourI fc = new FeatureColour(minColour.getBackground(), - maxColour.getBackground(), noColour, minValue, maxValue); + if (byCategory.isSelected()) + { + fc.setColourByLabel(true); + String byWhat = (String) colourByTextCombo.getSelectedItem(); + if (!LABEL_18N.equals(byWhat)) + { + fc.setAttributeName( + FeatureMatcher.fromAttributeDisplayName(byWhat)); + } + return fc; + } /* + * remaining case - graduated colour by score, or attribute value; * set attribute to colour by if selected */ String byWhat = (String) colourByRangeCombo.getSelectedItem(); @@ -1009,7 +1012,7 @@ public class FeatureTypeSettings extends JalviewDialog { fr.setColour(featureType, originalColour); fr.setFeatureFilter(featureType, originalFilter); - ap.paintAlignment(true, true); + refreshDisplay(true); } /** @@ -1027,8 +1030,8 @@ public class FeatureTypeSettings extends JalviewDialog float f = Float.parseFloat(thresholdValue.getText()); f = Float.max(f, this.min); f = Float.min(f, this.max); - thresholdValue.setText(String.valueOf(f)); - slider.setValue((int) (f * scaleFactor)); + setThresholdValueText(f); + slider.setSliderValue(f); threshline.value = f; thresholdValue.setBackground(Color.white); // ok adjusting = false; @@ -1041,13 +1044,25 @@ public class FeatureTypeSettings extends JalviewDialog } /** + * Sets the text field for threshold value, rounded to four significant figures + * + * @param f + */ + void setThresholdValueText(float f) + { + BigDecimal formatted = new BigDecimal(f).round(FOUR_SIG_FIG) + .stripTrailingZeros(); + thresholdValue.setText(formatted.toPlainString()); + } + + /** * 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 = getRoundedSliderValue(); + threshline.value = slider.getSliderValue(); /* * repaint alignment, but not Overview or structure, @@ -1056,21 +1071,6 @@ public class FeatureTypeSettings extends JalviewDialog colourChanged(false); } - /** - * Converts the slider value to its absolute value by dividing by the - * scaleFactor. Rounding errors are squashed by forcing min/max of slider - * range to the actual min/max of feature score range - * - * @return - */ - private float getRoundedSliderValue() - { - int value = slider.getValue(); - float f = value == slider.getMaximum() ? max - : (value == slider.getMinimum() ? min : value / scaleFactor); - return f; - } - void addActionListener(ActionListener listener) { if (featureSettings != null) @@ -1100,7 +1100,7 @@ public class FeatureTypeSettings extends JalviewDialog * @param withRange * @param withText */ - protected JComboBox populateAttributesDropdown( + protected JComboBox populateAttributesDropdown( List attNames, boolean withRange, boolean withText) { List displayAtts = new ArrayList<>(); @@ -1139,9 +1139,11 @@ public class FeatureTypeSettings extends JalviewDialog tooltips.add(desc == null ? "" : desc); } - JComboBox attCombo = JvSwingUtils - .buildComboWithTooltips(displayAtts, tooltips); - + // now convert String List to Object List for buildComboWithTooltips + List displayAttsObjects = new ArrayList<>(displayAtts); + JComboBox attCombo = JvSwingUtils + .buildComboWithTooltips(displayAttsObjects, tooltips); + return attCombo; } @@ -1312,7 +1314,7 @@ public class FeatureTypeSettings extends JalviewDialog * drop-down choice of attribute, with description as a tooltip * if we can obtain it */ - final JComboBox attCombo = populateAttributesDropdown(attNames, + final JComboBox attCombo = populateAttributesDropdown(attNames, true, true); String filterBy = setSelectedAttribute(attCombo, filter); @@ -1414,10 +1416,10 @@ public class FeatureTypeSettings extends JalviewDialog if (!patternField.isEnabled() || (pattern != null && pattern.trim().length() > 0)) { - // todo: gif for button drawing '-' or 'x' - JButton removeCondition = new BasicArrowButton(SwingConstants.WEST); - removeCondition - .setToolTipText(MessageManager.getString("label.delete_row")); + JButton removeCondition = new JButton("\u2717"); // Dingbats cursive x + removeCondition.setToolTipText( + MessageManager.getString("label.delete_condition")); + removeCondition.setBorder(new EmptyBorder(0, 0, 0, 0)); removeCondition.addActionListener(new ActionListener() { @Override @@ -1440,7 +1442,7 @@ public class FeatureTypeSettings extends JalviewDialog * @param attCombo * @param filter */ - private String setSelectedAttribute(JComboBox attCombo, + private String setSelectedAttribute(JComboBox attCombo, FeatureMatcherI filter) { String item = null; @@ -1657,11 +1659,19 @@ public class FeatureTypeSettings extends JalviewDialog * @param valueField * @param filterIndex */ - protected boolean updateFilter(JComboBox attCombo, + protected boolean updateFilter(JComboBox attCombo, JComboBox condCombo, JTextField valueField, int filterIndex) { - String attName = (String) attCombo.getSelectedItem(); + String attName; + try + { + attName = (String) attCombo.getSelectedItem(); + } catch (Exception e) + { + Cache.log.error("Problem casting Combo box entry to String"); + attName = attCombo.getSelectedItem().toString(); + } Condition cond = (Condition) condCombo.getSelectedItem(); String pattern = valueField.getText().trim(); @@ -1738,8 +1748,26 @@ public class FeatureTypeSettings extends JalviewDialog * (note this might now be an empty filter with no conditions) */ fr.setFeatureFilter(featureType, combined.isEmpty() ? null : combined); - ap.paintAlignment(true, true); + refreshDisplay(true); updateFiltersTab(); } + + /** + * Repaints alignment, structure and overview (if shown). If there is a + * complementary view which is showing this view's features, then also + * repaints that. + * + * @param updateStructsAndOverview + */ + void refreshDisplay(boolean updateStructsAndOverview) + { + ap.paintAlignment(true, updateStructsAndOverview); + AlignViewportI complement = ap.getAlignViewport().getCodingComplement(); + if (complement != null && complement.isShowComplementFeatures()) + { + AlignFrame af2 = Desktop.getAlignFrameFor(complement); + af2.alignPanel.paintAlignment(true, updateStructsAndOverview); + } + } }