import jalview.api.FeatureColourI;
import jalview.datamodel.GraphLine;
+import jalview.datamodel.features.FeatureAttributes;
import jalview.schemes.FeatureColour;
import jalview.util.MessageManager;
+import jalview.util.matcher.Condition;
+import jalview.util.matcher.KeyedMatcher;
+import jalview.util.matcher.KeyedMatcherI;
+import jalview.util.matcher.Matcher;
+import jalview.util.matcher.MatcherI;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
+import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
+import java.util.Iterator;
import javax.swing.BorderFactory;
import javax.swing.JCheckBox;
private ActionListener colourEditor = null;
+ private JComboBox<String> filterAttribute;
+
+ private JComboBox<Condition> filterCondition;
+
+ private JTextField filterValue;
+
+ private JComboBox<String> filterAttribute2;
+
+ private JComboBox<Condition> filterCondition2;
+
+ private JTextField filterValue2;
+
/**
* Constructor
*
threshline.value = cs.getThreshold();
}
+ setInitialFilters(cs.getAttributeFilters());
+
adjusting = false;
changeColour(false);
waitForInput();
}
- private void jbInit() throws Exception
+ /**
+ * Populates the attribute filter fields for the initial display
+ *
+ * @param attributeFilters
+ */
+ void setInitialFilters(KeyedMatcherI attributeFilters)
{
-
- 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)
+ // todo generalise to populate N conditions
+
+ if (attributeFilters != null)
+ {
+ filterAttribute.setSelectedItem(attributeFilters.getKey());
+ filterCondition.setSelectedItem(attributeFilters.getMatcher()
+ .getCondition());
+ filterValue.setText(attributeFilters.getMatcher().getPattern());
+
+ KeyedMatcherI second = attributeFilters.getSecondMatcher();
+ if (second != null)
{
- if (minColour.isEnabled())
- {
- minColour_actionPerformed();
- }
+ // todo add OR/AND condition to gui
+ filterAttribute2.setSelectedItem(second.getKey());
+ filterCondition2
+ .setSelectedItem(second.getMatcher().getCondition());
+ filterValue2.setText(second.getMatcher().getPattern());
}
- });
- 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()
+ }
+ }
+
+ private void jbInit() throws Exception
+ {
+ this.setLayout(new GridLayout(4, 1));
+
+ JPanel colourByPanel = initColoursPanel();
+
+ JPanel thresholdPanel = initThresholdPanel();
+
+ JPanel okCancelPanel = initOkCancelPanel();
+
+ this.add(colourByPanel);
+ this.add(thresholdPanel);
+
+ /*
+ * add filter by attributes options only if we know any attributes
+ */
+ Iterator<String> attributes = FeatureAttributes.getInstance()
+ .getAttributes(type).iterator();
+ if (attributes.hasNext())
{
- @Override
- public void mousePressed(MouseEvent e)
- {
- if (maxColour.isEnabled())
- {
- maxColour_actionPerformed();
- }
- }
- });
- maxColour.setBorder(new LineBorder(Color.black));
- JLabel minText = new JLabel(MessageManager.getString("label.min"));
- minText.setFont(JvSwingUtils.getLabelFont());
- JLabel maxText = new JLabel(MessageManager.getString("label.max"));
- maxText.setFont(JvSwingUtils.getLabelFont());
- this.setLayout(new BorderLayout());
- JPanel jPanel1 = new JPanel();
- jPanel1.setBackground(Color.white);
- JPanel jPanel2 = new JPanel();
- jPanel2.setLayout(new FlowLayout());
- jPanel2.setBackground(Color.white);
+ JPanel filtersPanel = initFiltersPanel(attributes);
+ this.add(filtersPanel);
+ }
+
+ this.add(okCancelPanel);
+ }
+
+ /**
+ * Lay out fields for threshold options
+ *
+ * @return
+ */
+ protected JPanel initThresholdPanel()
+ {
+ JPanel thresholdPanel = new JPanel();
+ thresholdPanel.setLayout(new FlowLayout());
threshold.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
- threshold_actionPerformed();
+ changeColour(true);
}
});
threshold.setToolTipText(MessageManager
threshold.addItem(MessageManager
.getString("label.threshold_feature_below_threshold")); // index 2
- JPanel jPanel3 = new JPanel();
- jPanel3.setLayout(new FlowLayout());
thresholdValue.addActionListener(new ActionListener()
{
@Override
MessageManager.getString("label.adjust_threshold"));
thresholdValue.setEnabled(false);
thresholdValue.setColumns(7);
- jPanel3.setBackground(Color.white);
+ thresholdPanel.setBackground(Color.white);
thresholdIsMin.setBackground(Color.white);
thresholdIsMin
.setText(MessageManager.getString("label.threshold_minmax"));
@Override
public void actionPerformed(ActionEvent actionEvent)
{
- thresholdIsMin_actionPerformed();
+ changeColour(true);
}
});
- colourByLabel.setBackground(Color.white);
- colourByLabel
- .setText(MessageManager.getString("label.colour_by_label"));
- colourByLabel.setToolTipText(MessageManager.getString(
- "label.display_features_same_type_different_label_using_different_colour"));
- colourByLabel.addActionListener(new ActionListener()
+ thresholdPanel.add(threshold);
+ thresholdPanel.add(slider);
+ thresholdPanel.add(thresholdValue);
+ thresholdPanel.add(thresholdIsMin);
+ return thresholdPanel;
+ }
+
+ /**
+ * 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 min/max colour widgets
+ *
+ * @return
+ */
+ protected JPanel initColoursPanel()
+ {
+ JPanel colourByPanel = new JPanel();
+ colourByPanel.setLayout(new FlowLayout());
+ colourByPanel.setBackground(Color.white);
+ 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 actionPerformed(ActionEvent actionEvent)
+ 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)
{
- colourByLabel_actionPerformed();
+ if (maxColour.isEnabled())
+ {
+ maxColour_actionPerformed();
+ }
}
});
+ maxColour.setBorder(new LineBorder(Color.black));
+ JLabel minText = new JLabel(MessageManager.getString("label.min"));
+ minText.setFont(JvSwingUtils.getLabelFont());
+ JLabel maxText = new JLabel(MessageManager.getString("label.max"));
+ maxText.setFont(JvSwingUtils.getLabelFont());
JPanel colourPanel = new JPanel();
colourPanel.setBackground(Color.white);
- jPanel1.add(ok);
- jPanel1.add(cancel);
- jPanel2.add(colourByLabel, BorderLayout.WEST);
- jPanel2.add(colourPanel, BorderLayout.EAST);
colourPanel.add(minText);
colourPanel.add(minColour);
colourPanel.add(maxText);
colourPanel.add(maxColour);
- this.add(jPanel3, BorderLayout.CENTER);
- jPanel3.add(threshold);
- jPanel3.add(slider);
- jPanel3.add(thresholdValue);
- jPanel3.add(thresholdIsMin);
- this.add(jPanel1, BorderLayout.SOUTH);
- this.add(jPanel2, BorderLayout.NORTH);
+ colourByPanel.add(colourByLabel, BorderLayout.WEST);
+ colourByPanel.add(colourPanel, BorderLayout.EAST);
+
+ colourByLabel.setBackground(Color.white);
+ colourByLabel
+ .setText(MessageManager.getString("label.colour_by_label"));
+ colourByLabel
+ .setToolTipText(MessageManager
+ .getString("label.display_features_same_type_different_label_using_different_colour"));
+ colourByLabel.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent actionEvent)
+ {
+ changeColour(true);
+ }
+ });
+
+ return colourByPanel;
}
/**
return;
}
+ if (!validateInputs())
+ {
+ return;
+ }
+
boolean aboveThreshold = false;
boolean belowThreshold = false;
if (threshold.getSelectedIndex() == 1)
maxColour.setForeground(oldmaxColour);
minColour.setForeground(oldminColour);
}
+
+ /*
+ * add attribute filters if entered
+ */
+ if (filterAttribute != null)
+ {
+ setAttributeFilters(acg);
+ }
+
fr.setColour(type, acg);
cs = acg;
ap.paintAlignment(updateStructsAndOverview, updateStructsAndOverview);
}
+ /**
+ * Checks inputs are valid, and answers true if they are, else false. Also
+ * sets the colour of invalid inputs to red.
+ *
+ * @return
+ */
+ boolean validateInputs()
+ {
+ // todo generalise to N filters
+ return isValidFilter(filterValue, filterCondition)
+ || isValidFilter(filterValue2, filterCondition2);
+ }
+
+ /**
+ * Answers true unless a numeric condition has been selected with a
+ * non-numeric value
+ *
+ * @param value
+ * @param condition
+ */
+ protected boolean isValidFilter(JTextField value, JComboBox<Condition> condition)
+ {
+ if (value == null || condition == null)
+ {
+ return true; // fields not populated
+ }
+
+ value.setBackground(Color.white);
+ String v1 = value.getText().trim();
+ if (v1.length() > 0)
+ {
+ Condition c1 = (Condition) condition.getSelectedItem();
+ if (c1.isNumeric())
+ {
+ try
+ {
+ Float.valueOf(v1);
+ } catch (NumberFormatException e)
+ {
+ value.setBackground(Color.red);
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Sets any attribute value filters entered in the dialog as filters on the
+ * colour scheme
+ *
+ * @param acg
+ */
+ protected void setAttributeFilters(FeatureColourI acg)
+ {
+ String attribute = (String) filterAttribute.getSelectedItem();
+ Condition cond = (Condition) filterCondition.getSelectedItem();
+ String pattern = filterValue.getText().trim();
+ if (pattern.length() > 1)
+ {
+ MatcherI filter = new Matcher(cond, pattern);
+ KeyedMatcherI km = new KeyedMatcher(attribute, filter);
+
+ /*
+ * is there a second condition?
+ * todo: generalise to N conditions
+ */
+ pattern = filterValue2.getText().trim();
+ if (pattern.length() > 1)
+ {
+ attribute = (String) filterAttribute2.getSelectedItem();
+ cond = (Condition) filterCondition2.getSelectedItem();
+ filter = new Matcher(cond, pattern);
+ km = km.and(attribute, filter);
+ }
+ acg.setAttributeFilters(km);
+ }
+ }
+
@Override
protected void raiseClosed()
{
}
/**
- * Action on change of choice of No / Above / Below Threshold
- */
- protected void threshold_actionPerformed()
- {
- changeColour(true);
- }
-
- /**
* Action on text entry of a threshold value
*/
protected void thresholdValue_actionPerformed()
changeColour(false);
}
- protected void thresholdIsMin_actionPerformed()
- {
- changeColour(true);
- }
-
- protected void colourByLabel_actionPerformed()
- {
- changeColour(true);
- }
-
void addActionListener(ActionListener graduatedColorEditor)
{
if (colourEditor != null)
return cs;
}
+ /**
+ * Lay out fields for attribute value filters
+ *
+ * @param attNames
+ *
+ * @return
+ */
+ protected JPanel initFiltersPanel(Iterator<String> attNames)
+ {
+ JPanel filtersPanel = new JPanel();
+ filtersPanel.setLayout(new GridLayout(2, 3));
+ filtersPanel.setBackground(Color.white);
+
+ /*
+ * drop-down choice of attribute
+ */
+ filterAttribute = new JComboBox<>();
+ filterAttribute2 = new JComboBox<>();
+ while (attNames.hasNext())
+ {
+ String attName = attNames.next();
+ filterAttribute.addItem(attName);
+ filterAttribute2.addItem(attName);
+ }
+ filterAttribute.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ changeColour(true);
+ }
+ });
+
+ /*
+ * drop-down choice of test condition
+ */
+ filterCondition = new JComboBox<>();
+ for (Condition cond : Condition.values())
+ {
+ filterCondition.addItem(cond);
+ }
+ filterCondition.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ changeColour(true);
+ }
+ });
+
+ filterValue = new JTextField(12);
+ filterValue.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ changeColour(true);
+ }
+ });
+ filterValue.addFocusListener(new FocusAdapter()
+ {
+ @Override
+ public void focusLost(FocusEvent e)
+ {
+ changeColour(true);
+ }
+ });
+
+ /*
+ * repeat for a second filter
+ * todo: generalise to N filters
+ */
+ filterAttribute2.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ changeColour(true);
+ }
+ });
+
+ /*
+ * drop-down choice of test condition
+ */
+ filterCondition2 = new JComboBox<>();
+ for (Condition cond : Condition.values())
+ {
+ filterCondition2.addItem(cond);
+ }
+ filterCondition2.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ changeColour(true);
+ }
+ });
+
+ filterValue2 = new JTextField(12);
+ filterValue2.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ changeColour(true);
+ }
+ });
+ filterValue2.addFocusListener(new FocusAdapter()
+ {
+ @Override
+ public void focusLost(FocusEvent e)
+ {
+ changeColour(true);
+ }
+ });
+
+ filtersPanel.add(filterAttribute);
+ filtersPanel.add(filterCondition);
+ filtersPanel.add(filterValue);
+ filtersPanel.add(filterAttribute2);
+ filtersPanel.add(filterCondition2);
+ filtersPanel.add(filterValue2);
+
+ return filtersPanel;
+ }
+
}