X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fgui%2FFeatureTypeSettings.java;h=a2a2700ca58ac4e555f64b87858cf1abec06162e;hb=cb8e52fbbc5f725e3f7f48c672cdddb0690bd978;hp=7456e18d83bb55403450b8db7f4bc1f741698f94;hpb=b8683aaaf600239e94d658bdf99012f5e684d9a8;p=jalview.git diff --git a/src/jalview/gui/FeatureTypeSettings.java b/src/jalview/gui/FeatureTypeSettings.java index 7456e18..a2a2700 100644 --- a/src/jalview/gui/FeatureTypeSettings.java +++ b/src/jalview/gui/FeatureTypeSettings.java @@ -20,9 +20,10 @@ */ package jalview.gui; +import jalview.api.AlignViewportI; import jalview.api.AlignmentViewPanel; import jalview.api.FeatureColourI; -import jalview.bin.Cache; +import jalview.bin.Console; import jalview.datamodel.GraphLine; import jalview.datamodel.features.FeatureAttributes; import jalview.datamodel.features.FeatureAttributes.Datatype; @@ -30,6 +31,7 @@ import jalview.datamodel.features.FeatureMatcher; import jalview.datamodel.features.FeatureMatcherI; import jalview.datamodel.features.FeatureMatcherSet; import jalview.datamodel.features.FeatureMatcherSetI; +import jalview.gui.JalviewColourChooser.ColourChooserListener; import jalview.schemes.FeatureColour; import jalview.util.ColorUtils; import jalview.util.MessageManager; @@ -48,6 +50,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; @@ -57,12 +61,10 @@ import javax.swing.BoxLayout; import javax.swing.ButtonGroup; import javax.swing.JButton; 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.EmptyBorder; import javax.swing.border.LineBorder; @@ -78,6 +80,8 @@ import javax.swing.event.ChangeListener; */ 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"); @@ -112,9 +116,9 @@ public class FeatureTypeSettings extends JalviewDialog /* * the view panel to update when settings change */ - private final AlignmentViewPanel ap; + final AlignmentViewPanel ap; - private final String featureType; + final String featureType; /* * the colour and filters to reset to on Cancel @@ -127,7 +131,7 @@ public class FeatureTypeSettings extends JalviewDialog * set flag to true when setting values programmatically, * to avoid invocation of action handlers */ - private boolean adjusting = false; + boolean adjusting = false; /* * minimum of the value range for graduated colour @@ -141,36 +145,30 @@ 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 */ - private JRadioButton simpleColour = new JRadioButton(); + JRadioButton simpleColour = new JRadioButton(); - private JRadioButton byCategory = new JRadioButton(); + JRadioButton byCategory = new JRadioButton(); - private JRadioButton graduatedColour = new JRadioButton(); + JRadioButton graduatedColour = new JRadioButton(); - /** - * colours and filters are shown in tabbed view or single content pane - */ - JPanel coloursPanel, filtersPanel; + JPanel coloursPanel; + + JPanel filtersPanel; JPanel singleColour = new JPanel(); - private JPanel minColour = new JPanel(); + JPanel minColour = new JPanel(); - private JPanel maxColour = new JPanel(); + JPanel maxColour = new JPanel(); private JComboBox threshold = new JComboBox<>(); - private JSlider slider = new JSlider(); + private Slider slider; - private JTextField thresholdValue = new JTextField(20); + JTextField thresholdValue = new JTextField(20); private JCheckBox thresholdIsMin = new JCheckBox(); @@ -202,7 +200,7 @@ public class FeatureTypeSettings extends JalviewDialog /* * filters for the currently selected feature type */ - private List filters; + List filters; private JPanel chooseFiltersPanel; @@ -231,9 +229,9 @@ public class FeatureTypeSettings extends JalviewDialog return; } - updateColoursTab(); + updateColoursPanel(); - updateFiltersTab(); + updateFiltersPanel(); adjusting = false; @@ -247,10 +245,10 @@ public class FeatureTypeSettings extends JalviewDialog } /** - * Configures the widgets on the Colours tab according to the current feature + * Configures the widgets on the Colours panel according to the current feature * colour scheme */ - private void updateColoursTab() + private void updateColoursPanel() { FeatureColourI fc = fr.getFeatureColours().get(featureType); @@ -347,12 +345,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 +361,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); } @@ -402,13 +399,13 @@ public class FeatureTypeSettings extends JalviewDialog }; /* - * first panel/tab: colour options + * first panel: colour options */ JPanel coloursPanel = initialiseColoursPanel(); this.add(coloursPanel, BorderLayout.NORTH); /* - * second panel/tab: filter options + * second panel: filter options */ JPanel filtersPanel = initialiseFiltersPanel(); this.add(filtersPanel, BorderLayout.CENTER); @@ -488,6 +485,7 @@ public class FeatureTypeSettings extends JalviewDialog graduatedColour = new JRadioButton( MessageManager.getString("label.by_range_of") + COLON); graduatedColour.setPreferredSize(new Dimension(RADIO_WIDTH, 20)); + graduatedColour.setOpaque(false); graduatedColour.addItemListener(new ItemListener() { @Override @@ -539,7 +537,8 @@ public class FeatureTypeSettings extends JalviewDialog { if (minColour.isEnabled()) { - showColourChooser(minColour, "label.select_colour_minimum_value"); + String ttl = MessageManager.getString("label.select_colour_minimum_value"); + showColourChooser(minColour, ttl); } } }); @@ -555,7 +554,8 @@ public class FeatureTypeSettings extends JalviewDialog { if (maxColour.isEnabled()) { - showColourChooser(maxColour, "label.select_colour_maximum_value"); + String ttl = MessageManager.getString("label.select_colour_maximum_value"); + showColourChooser(maxColour, ttl); } } }); @@ -640,6 +640,7 @@ public class FeatureTypeSettings extends JalviewDialog thresholdValue_actionPerformed(); } }); + slider = new Slider(0f, 100f, 50f); slider.setPaintLabels(false); slider.setPaintTicks(true); slider.setBackground(Color.white); @@ -656,8 +657,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(); } @@ -674,7 +674,7 @@ public class FeatureTypeSettings extends JalviewDialog */ if (ap != null) { - ap.paintAlignment(true, true); + refreshDisplay(true); } } }); @@ -739,6 +739,7 @@ public class FeatureTypeSettings extends JalviewDialog simpleColour = new JRadioButton( MessageManager.getString("label.simple_colour")); simpleColour.setPreferredSize(new Dimension(RADIO_WIDTH, 20)); + simpleColour.setOpaque(false); simpleColour.addItemListener(new ItemListener() { @Override @@ -771,7 +772,8 @@ public class FeatureTypeSettings extends JalviewDialog { if (simpleColour.isSelected()) { - showColourChooser(singleColour, "label.select_colour"); + String ttl = MessageManager.formatMessage("label.select_colour_for", featureType); + showColourChooser(singleColour, ttl); } } }); @@ -789,6 +791,7 @@ public class FeatureTypeSettings extends JalviewDialog byCategory = new JRadioButton( MessageManager.getString("label.by_text_of") + COLON); byCategory.setPreferredSize(new Dimension(RADIO_WIDTH, 20)); + byCategory.setOpaque(false); byCategory.addItemListener(new ItemListener() { @Override @@ -833,17 +836,29 @@ public class FeatureTypeSettings extends JalviewDialog return colourByPanel; } - private void showColourChooser(JPanel colourPanel, String key) + /** + * Shows a colour chooser dialog, and if a selection is made, updates the + * colour of the given panel + * + * @param colourPanel + * the panel whose background colour is being picked + * @param title + */ + void showColourChooser(JPanel colourPanel, String title) { - Color col = JColorChooser.showDialog(this, - MessageManager.getString(key), colourPanel.getBackground()); - if (col != null) + ColourChooserListener listener = new ColourChooserListener() { - colourPanel.setBackground(col); - colourPanel.setForeground(col); - } - colourPanel.repaint(); - colourChanged(true); + @Override + public void colourSelected(Color col) + { + colourPanel.setBackground(col); + colourPanel.setForeground(col); + colourPanel.repaint(); + colourChanged(true); + } + }; + JalviewColourChooser.showColourChooser(this, title, + colourPanel.getBackground(), listener); } /** @@ -875,9 +890,9 @@ public class FeatureTypeSettings extends JalviewDialog * save the colour, and repaint stuff */ fr.setColour(featureType, acg); - ap.paintAlignment(updateStructsAndOverview, updateStructsAndOverview); + refreshDisplay(updateStructsAndOverview); - updateColoursTab(); + updateColoursPanel(); } /** @@ -902,7 +917,7 @@ public class FeatureTypeSettings extends JalviewDialog } float minValue = min; float maxValue = max; - final int thresholdOption = threshold.getSelectedIndex(); + int thresholdOption = threshold.getSelectedIndex(); if (thresholdIsMin.isSelected() && thresholdOption == ABOVE_THRESHOLD_OPTION) { @@ -1014,7 +1029,7 @@ public class FeatureTypeSettings extends JalviewDialog { fr.setColour(featureType, originalColour); fr.setFeatureFilter(featureType, originalFilter); - ap.paintAlignment(true, true); + refreshDisplay(true); } /** @@ -1032,8 +1047,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; @@ -1046,13 +1061,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, @@ -1061,21 +1088,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) @@ -1190,6 +1202,8 @@ public class FeatureTypeSettings extends JalviewDialog andOrPanel.setBackground(Color.white); andFilters = new JRadioButton(MessageManager.getString("label.and")); orFilters = new JRadioButton(MessageManager.getString("label.or")); + andFilters.setOpaque(false); + orFilters.setOpaque(false); ActionListener actionListener = new ActionListener() { @Override @@ -1217,7 +1231,7 @@ public class FeatureTypeSettings extends JalviewDialog * for adding a condition. This should be called after a filter has been * removed, added or amended. */ - private void updateFiltersTab() + private void updateFiltersPanel() { /* * clear the panel and list of filter conditions @@ -1241,7 +1255,12 @@ public class FeatureTypeSettings extends JalviewDialog { orFilters.setSelected(true); } - featureFilters.getMatchers().forEach(matcher -> filters.add(matcher)); + // avoid use of lambda expression to keep SwingJS happy + // featureFilters.getMatchers().forEach(item -> filters.add(item)); + for (FeatureMatcherI matcher : featureFilters.getMatchers()) + { + filters.add(matcher); + } } /* @@ -1421,10 +1440,13 @@ public class FeatureTypeSettings extends JalviewDialog if (!patternField.isEnabled() || (pattern != null && pattern.trim().length() > 0)) { - JButton removeCondition = new JButton("\u2717"); // Dingbats cursive x + JButton removeCondition = new JButton("\u2717"); + // Dingbats cursive x + removeCondition.setBorder(new EmptyBorder(0, 0, 0, 0)); + removeCondition.setBackground(Color.WHITE); + removeCondition.setPreferredSize(new Dimension(23, 17)); removeCondition.setToolTipText( MessageManager.getString("label.delete_condition")); - removeCondition.setBorder(new EmptyBorder(0, 0, 0, 0)); removeCondition.addActionListener(new ActionListener() { @Override @@ -1526,7 +1548,7 @@ public class FeatureTypeSettings extends JalviewDialog * @param condCombo * @param patternField */ - private void populateConditions(String attName, Condition cond, + void populateConditions(String attName, Condition cond, JComboBox condCombo, JTextField patternField) { Datatype type = FeatureAttributes.getInstance().getDatatype(featureType, @@ -1674,7 +1696,7 @@ public class FeatureTypeSettings extends JalviewDialog attName = (String) attCombo.getSelectedItem(); } catch (Exception e) { - Cache.log.error("Problem casting Combo box entry to String"); + Console.error("Problem casting Combo box entry to String"); attName = attCombo.getSelectedItem().toString(); } Condition cond = (Condition) condCombo.getSelectedItem(); @@ -1753,8 +1775,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); + + updateFiltersPanel(); + } - 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); + } } }