import jalview.bin.Cache;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.SequenceI;
+import jalview.datamodel.features.FeatureAttributes;
import jalview.gui.Help.HelpId;
import jalview.io.JalviewFileChooser;
import jalview.io.JalviewFileView;
import jalview.util.MessageManager;
import jalview.util.Platform;
import jalview.util.QuickSort;
+import jalview.util.ReverseListIterator;
+import jalview.util.matcher.Condition;
+import jalview.util.matcher.KeyedMatcher;
+import jalview.util.matcher.KeyedMatcherI;
+import jalview.util.matcher.KeyedMatcherSet;
+import jalview.util.matcher.KeyedMatcherSetI;
import jalview.viewmodel.AlignmentViewport;
+import jalview.ws.DasSequenceFeatureFetcher;
import jalview.ws.dbsources.das.api.jalviewSourceI;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
+import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Rectangle;
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.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Hashtable;
import javax.help.HelpSetException;
import javax.swing.AbstractCellEditor;
import javax.swing.BorderFactory;
+import javax.swing.ButtonGroup;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JColorChooser;
+import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
+import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
+import javax.swing.JTextArea;
+import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
+import javax.swing.plaf.basic.BasicArrowButton;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
public class FeatureSettings extends JPanel
implements FeatureSettingsControllerI
{
- DasSourceBrowser dassourceBrowser;
+ private static final int MIN_WIDTH = 400;
- jalview.ws.DasSequenceFeatureFetcher dasFeatureFetcher;
+ private static final int MIN_HEIGHT = 400;
+
+ DasSourceBrowser dassourceBrowser;
- JPanel settingsPane = new JPanel();
+ DasSequenceFeatureFetcher dasFeatureFetcher;
JPanel dasSettingsPane = new JPanel();
public final AlignFrame af;
+ /*
+ * 'original' fields hold settings to restore on Cancel
+ */
Object[][] originalData;
private float originalTransparency;
+ private Map<String, KeyedMatcherSetI> originalFilters;
+
final JInternalFrame frame;
JScrollPane scrollPane = new JScrollPane();
JPanel groupPanel;
JSlider transparency = new JSlider();
-
- JPanel transPanel = new JPanel(new GridLayout(1, 2));
-
- private static final int MIN_WIDTH = 400;
-
- private static final int MIN_HEIGHT = 400;
- /**
+ /*
* when true, constructor is still executing - so ignore UI events
*/
protected volatile boolean inConstruction = true;
+ int selectedRow = -1;
+
+ JButton fetchDAS = new JButton();
+
+ JButton saveDAS = new JButton();
+
+ JButton cancelDAS = new JButton();
+
+ boolean resettingTable = false;
+
+ /*
+ * true when Feature Settings are updating from feature renderer
+ */
+ private boolean handlingUpdate = false;
+
+ /*
+ * holds {featureCount, totalExtent} for each feature type
+ */
+ Map<String, float[]> typeWidth = null;
+
+ /*
+ * fields of the feature filters tab
+ */
+ private JPanel filtersPane;
+
+ private JPanel chooseFiltersPanel;
+
+ private JComboBox<String> filteredFeatureChoice;
+
+ private JRadioButton andFilters;
+
+ private JRadioButton orFilters;
+
+ /*
+ * filters for the currently selected feature type
+ */
+ private List<KeyedMatcherI> filters;
+
+ private JTextArea filtersAsText;
+
/**
* Constructor
*
* @param af
*/
- public FeatureSettings(AlignFrame af)
+ public FeatureSettings(AlignFrame alignFrame)
{
- this.af = af;
+ this.af = alignFrame;
fr = af.getFeatureRenderer();
- // allow transparency to be recovered
- transparency.setMaximum(100
- - (int) ((originalTransparency = fr.getTransparency()) * 100));
+
+ // save transparency for restore on Cancel
+ originalTransparency = fr.getTransparency();
+ int originalTransparencyAsPercent = (int) (originalTransparency * 100);
+ transparency.setMaximum(100 - originalTransparencyAsPercent);
+
+ originalFilters = fr.getFeatureFilters();
try
{
{
Desktop.addInternalFrame(frame,
MessageManager.getString("label.sequence_feature_settings"),
- 475, 480);
+ 600, 480);
}
else
{
Desktop.addInternalFrame(frame,
MessageManager.getString("label.sequence_feature_settings"),
- 400, 450);
+ 600, 450);
}
frame.setMinimumSize(new Dimension(MIN_WIDTH, MIN_HEIGHT));
men.show(table, x, y);
}
- /**
- * true when Feature Settings are updating from feature renderer
- */
- private boolean handlingUpdate = false;
-
- /**
- * holds {featureCount, totalExtent} for each feature type
- */
- Map<String, float[]> typeWidth = null;
-
@Override
synchronized public void discoverAllFeatureData()
{
}
}
+ populateFilterableFeatures();
+
resetTable(null);
validate();
return visible;
}
- boolean resettingTable = false;
-
synchronized void resetTable(String[] groupChanged)
{
if (resettingTable)
}
}
- int selectedRow = -1;
-
- JTabbedPane tabbedPane = new JTabbedPane();
-
- BorderLayout borderLayout1 = new BorderLayout();
-
- BorderLayout borderLayout2 = new BorderLayout();
-
- BorderLayout borderLayout3 = new BorderLayout();
-
- JPanel bigPanel = new JPanel();
-
- BorderLayout borderLayout4 = new BorderLayout();
-
- JButton invert = new JButton();
-
- JPanel buttonPanel = new JPanel();
-
- JButton cancel = new JButton();
-
- JButton ok = new JButton();
-
- JButton loadColours = new JButton();
-
- JButton saveColours = new JButton();
-
- JPanel dasButtonPanel = new JPanel();
-
- JButton fetchDAS = new JButton();
-
- JButton saveDAS = new JButton();
-
- JButton cancelDAS = new JButton();
-
- JButton optimizeOrder = new JButton();
-
- JButton sortByScore = new JButton();
+ private void jbInit() throws Exception
+ {
+ this.setLayout(new BorderLayout());
- JButton sortByDens = new JButton();
+ JPanel settingsPane = new JPanel();
+ settingsPane.setLayout(new BorderLayout());
- JButton help = new JButton();
+ filtersPane = new JPanel();
- JPanel transbuttons = new JPanel(new GridLayout(5, 1));
+ dasSettingsPane.setLayout(new BorderLayout());
- private void jbInit() throws Exception
- {
- this.setLayout(borderLayout1);
- settingsPane.setLayout(borderLayout2);
- dasSettingsPane.setLayout(borderLayout3);
- bigPanel.setLayout(borderLayout4);
+ JPanel bigPanel = new JPanel();
+ bigPanel.setLayout(new BorderLayout());
groupPanel = new JPanel();
bigPanel.add(groupPanel, BorderLayout.NORTH);
+ JButton invert = new JButton(
+ MessageManager.getString("label.invert_selection"));
invert.setFont(JvSwingUtils.getLabelFont());
- invert.setText(MessageManager.getString("label.invert_selection"));
invert.addActionListener(new ActionListener()
{
@Override
invertSelection();
}
});
+
+ JButton optimizeOrder = new JButton(
+ MessageManager.getString("label.optimise_order"));
optimizeOrder.setFont(JvSwingUtils.getLabelFont());
- optimizeOrder.setText(MessageManager.getString("label.optimise_order"));
optimizeOrder.addActionListener(new ActionListener()
{
@Override
orderByAvWidth();
}
});
+
+ JButton sortByScore = new JButton(
+ MessageManager.getString("label.seq_sort_by_score"));
sortByScore.setFont(JvSwingUtils.getLabelFont());
- sortByScore
- .setText(MessageManager.getString("label.seq_sort_by_score"));
sortByScore.addActionListener(new ActionListener()
{
@Override
af.avc.sortAlignmentByFeatureScore(null);
}
});
- sortByDens.setFont(JvSwingUtils.getLabelFont());
- sortByDens.setText(
+ JButton sortByDens = new JButton(
MessageManager.getString("label.sequence_sort_by_density"));
+ sortByDens.setFont(JvSwingUtils.getLabelFont());
sortByDens.addActionListener(new ActionListener()
{
@Override
af.avc.sortAlignmentByFeatureDensity(null);
}
});
+
+ JButton help = new JButton(MessageManager.getString("action.help"));
help.setFont(JvSwingUtils.getLabelFont());
- help.setText(MessageManager.getString("action.help"));
help.addActionListener(new ActionListener()
{
@Override
}
}
});
+
+ JButton cancel = new JButton(MessageManager.getString("action.cancel"));
cancel.setFont(JvSwingUtils.getLabelFont());
- cancel.setText(MessageManager.getString("action.cancel"));
cancel.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
fr.setTransparency(originalTransparency);
+ fr.setFeatureFilters(originalFilters);
updateFeatureRenderer(originalData);
close();
}
});
+
+ JButton ok = new JButton(MessageManager.getString("action.ok"));
ok.setFont(JvSwingUtils.getLabelFont());
- ok.setText(MessageManager.getString("action.ok"));
ok.addActionListener(new ActionListener()
{
@Override
close();
}
});
+
+ JButton loadColours = new JButton(
+ MessageManager.getString("label.load_colours"));
loadColours.setFont(JvSwingUtils.getLabelFont());
- loadColours.setText(MessageManager.getString("label.load_colours"));
loadColours.addActionListener(new ActionListener()
{
@Override
load();
}
});
+
+ JButton saveColours = new JButton(
+ MessageManager.getString("label.save_colours"));
saveColours.setFont(JvSwingUtils.getLabelFont());
- saveColours.setText(MessageManager.getString("label.save_colours"));
saveColours.addActionListener(new ActionListener()
{
@Override
saveDAS_actionPerformed(e);
}
});
+
+ JPanel dasButtonPanel = new JPanel();
dasButtonPanel.setBorder(BorderFactory.createEtchedBorder());
dasSettingsPane.setBorder(null);
cancelDAS.setEnabled(false);
cancelDAS_actionPerformed(e);
}
});
- this.add(tabbedPane, java.awt.BorderLayout.CENTER);
+
+ JTabbedPane tabbedPane = new JTabbedPane();
+ this.add(tabbedPane, BorderLayout.CENTER);
tabbedPane.addTab(MessageManager.getString("label.feature_settings"),
settingsPane);
- tabbedPane.addTab(MessageManager.getString("label.das_settings"),
- dasSettingsPane);
- bigPanel.add(transPanel, java.awt.BorderLayout.SOUTH);
+ tabbedPane.addTab(MessageManager.getString("label.filters"),
+ filtersPane);
+ // tabbedPane.addTab(MessageManager.getString("label.das_settings"),
+ // dasSettingsPane);
+
+ JPanel transPanel = new JPanel(new GridLayout(1, 2));
+ bigPanel.add(transPanel, BorderLayout.SOUTH);
+
+ JPanel transbuttons = new JPanel(new GridLayout(5, 1));
transbuttons.add(optimizeOrder);
transbuttons.add(invert);
transbuttons.add(sortByScore);
transbuttons.add(sortByDens);
transbuttons.add(help);
- JPanel sliderPanel = new JPanel();
- sliderPanel.add(transparency);
transPanel.add(transparency);
transPanel.add(transbuttons);
+
+ JPanel buttonPanel = new JPanel();
buttonPanel.add(ok);
buttonPanel.add(cancel);
buttonPanel.add(loadColours);
buttonPanel.add(saveColours);
- bigPanel.add(scrollPane, java.awt.BorderLayout.CENTER);
- dasSettingsPane.add(dasButtonPanel, java.awt.BorderLayout.SOUTH);
+ bigPanel.add(scrollPane, BorderLayout.CENTER);
+ dasSettingsPane.add(dasButtonPanel, BorderLayout.SOUTH);
dasButtonPanel.add(fetchDAS);
dasButtonPanel.add(cancelDAS);
dasButtonPanel.add(saveDAS);
- settingsPane.add(bigPanel, java.awt.BorderLayout.CENTER);
- settingsPane.add(buttonPanel, java.awt.BorderLayout.SOUTH);
+ settingsPane.add(bigPanel, BorderLayout.CENTER);
+ settingsPane.add(buttonPanel, BorderLayout.SOUTH);
+
+ initFiltersTab();
+ }
+
+ /**
+ * Populates initial layout of the feature attribute filters panel
+ */
+ protected void initFiltersTab()
+ {
+ filters = new ArrayList<>();
+
+ /*
+ * choose feature type
+ */
+ JPanel chooseTypePanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
+ chooseTypePanel.setBackground(Color.white);
+ chooseTypePanel.setBorder(BorderFactory
+ .createTitledBorder(MessageManager
+ .getString("label.feature_type")));
+ filteredFeatureChoice = new JComboBox<>();
+ filteredFeatureChoice.addItemListener(new ItemListener()
+ {
+ @Override
+ public void itemStateChanged(ItemEvent e)
+ {
+ refreshFiltersDisplay();
+ }
+ });
+ chooseTypePanel.add(new JLabel(MessageManager
+ .getString("label.feature_to_filter")));
+ chooseTypePanel.add(filteredFeatureChoice);
+ populateFilterableFeatures();
+
+ /*
+ * the panel with the filters for the selected feature type
+ */
+ chooseFiltersPanel = new JPanel(new GridLayout(0, 1));
+ chooseFiltersPanel.setBackground(Color.white);
+ chooseFiltersPanel.setBorder(BorderFactory
+ .createTitledBorder(MessageManager.getString("label.filters")));
+
+ /*
+ * a read-only text view of the current filters
+ */
+ JPanel showFiltersPanel = new JPanel(new BorderLayout(5, 5));
+ showFiltersPanel.setBackground(Color.white);
+ showFiltersPanel.setBorder(BorderFactory
+ .createTitledBorder(MessageManager
+ .getString("label.match_condition")));
+ filtersAsText = new JTextArea();
+ filtersAsText.setLineWrap(true);
+ filtersAsText.setWrapStyleWord(true);
+ showFiltersPanel.add(filtersAsText);
+
+ filtersPane.setLayout(new BorderLayout());
+ filtersPane.add(chooseTypePanel, BorderLayout.NORTH);
+ filtersPane.add(chooseFiltersPanel, BorderLayout.CENTER);
+ filtersPane.add(showFiltersPanel, BorderLayout.SOUTH);
+
+ /*
+ * update display for initial feature type selection
+ */
+ refreshFiltersDisplay();
+ }
+
+ /**
+ * Adds entries to the 'choose feature to filter' drop-down choice. Only
+ * feature types which have known attributes (so can be filtered) are
+ * included, so recall this method to update the list (check for newly added
+ * attributes).
+ */
+ protected void populateFilterableFeatures()
+ {
+ /*
+ * suppress action handler while updating the list
+ */
+ ItemListener listener = filteredFeatureChoice.getItemListeners()[0];
+ filteredFeatureChoice.removeItemListener(listener);
+
+ filteredFeatureChoice.removeAllItems();
+ ReverseListIterator<String> types = new ReverseListIterator<>(
+ fr.getRenderOrder());
+
+ boolean found = false;
+ while (types.hasNext())
+ {
+ String type = types.next();
+ if (FeatureAttributes.getInstance().hasAttributes(type))
+ {
+ filteredFeatureChoice.addItem(type);
+ found = true;
+ }
+ }
+ if (!found)
+ {
+ filteredFeatureChoice
+ .addItem("No filterable feature attributes known");
+ }
+
+ filteredFeatureChoice.addItemListener(listener);
+
+ }
+
+ /**
+ * Refreshes the display to show any filters currently configured for the
+ * selected feature type (editable, with 'remove' option), plus one extra row
+ * for adding a condition. This should be called on change of selected feature
+ * type, or after a filter has been removed, added or amended.
+ */
+ protected void refreshFiltersDisplay()
+ {
+ /*
+ * clear the panel and list of filter conditions
+ */
+ chooseFiltersPanel.removeAll();
+
+ String selectedType = (String) filteredFeatureChoice.getSelectedItem();
+
+ filters.clear();
+
+ /*
+ * add AND or OR radio buttons
+ */
+ JPanel andOrPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
+ andOrPanel.setBackground(Color.white);
+ andFilters = new JRadioButton("And");
+ orFilters = new JRadioButton("Or");
+ ActionListener actionListener = new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ filtersChanged();
+ }
+ };
+ andFilters.addActionListener(actionListener);
+ orFilters.addActionListener(actionListener);
+ ButtonGroup andOr = new ButtonGroup();
+ andOr.add(andFilters);
+ andOr.add(orFilters);
+ andFilters.setSelected(true);
+ andOrPanel.add(new JLabel(MessageManager
+ .getString("label.join_conditions")));
+ andOrPanel.add(andFilters);
+ andOrPanel.add(orFilters);
+ chooseFiltersPanel.add(andOrPanel);
+
+ /*
+ * look up attributes known for feature type
+ */
+ List<String> attNames = FeatureAttributes.getInstance().getAttributes(
+ selectedType);
+
+ /*
+ * if this feature type has filters set, load them first
+ */
+ KeyedMatcherSetI featureFilters = fr.getFeatureFilter(selectedType);
+ andFilters.setSelected(true);
+ filtersAsText.setText("");
+ if (featureFilters != null)
+ {
+ filtersAsText.setText(featureFilters.toString());
+ if (!featureFilters.isAnded())
+ {
+ orFilters.setSelected(true);
+ }
+ Iterator<KeyedMatcherI> matchers = featureFilters.getMatchers();
+ while (matchers.hasNext())
+ {
+ filters.add(matchers.next());
+ }
+ }
+
+ /*
+ * and an empty filter for the user to populate (add)
+ */
+ KeyedMatcherI noFilter = new KeyedMatcher("", Condition.values()[0], "");
+ filters.add(noFilter);
+
+ /*
+ * render the conditions in rows, each in its own JPanel
+ */
+ int i = 0;
+ for (KeyedMatcherI filter : filters)
+ {
+ String key = filter.getKey();
+ Condition condition = filter.getMatcher()
+ .getCondition();
+ String pattern = filter.getMatcher().getPattern();
+ JPanel row = addFilter(key, attNames, condition, pattern, i);
+ chooseFiltersPanel.add(row);
+ i++;
+ }
+
+ filtersPane.validate();
+ filtersPane.repaint();
+ }
+
+ /**
+ * A helper method that constructs a panel with one filter condition:
+ * <ul>
+ * <li>a drop-down list of attribute names to choose from</li>
+ * <li>a drop-down list of conditions to choose from</li>
+ * <li>a text field for input of a match pattern</li>
+ * <li>optionally, a 'remove' button</li>
+ * </ul>
+ * If attribute, condition or pattern are not null, they are set as defaults
+ * for the input fields. The 'remove' button is added unless the pattern is
+ * null or empty (incomplete filter condition).
+ *
+ * @param attribute
+ * @param attNames
+ * @param cond
+ * @param pattern
+ * @param i
+ * @return
+ */
+ protected JPanel addFilter(String attribute, List<String> attNames,
+ Condition cond, String pattern, int i)
+ {
+ JPanel filterRow = new JPanel(new FlowLayout(FlowLayout.LEFT));
+ filterRow.setBackground(Color.white);
+
+ /*
+ * inputs for attribute, condition, pattern
+ */
+ JComboBox<String> attCombo = new JComboBox<>();
+ JComboBox<Condition> condCombo = new JComboBox<>();
+ JTextField patternField = new JTextField(8);
+
+ /*
+ * action handlers that validate and (if valid) apply changes
+ */
+ ActionListener actionListener = new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ if (attCombo.getSelectedItem() != null)
+ {
+ if (validateFilter(patternField, condCombo))
+ {
+ updateFilter(attCombo, condCombo, patternField, i);
+ filtersChanged();
+ }
+ }
+ }
+ };
+ ItemListener itemListener = new ItemListener()
+ {
+ @Override
+ public void itemStateChanged(ItemEvent e)
+ {
+ actionListener.actionPerformed(null);
+ }
+ };
+
+ /*
+ * drop-down choice of attribute
+ */
+ if (attNames.isEmpty())
+ {
+ attCombo.addItem("---");
+ attCombo.setToolTipText(MessageManager
+ .getString("label.no_attributes_known"));
+ }
+ else
+ {
+ attCombo.setToolTipText("");
+ for (String attName : attNames)
+ {
+ attCombo.addItem(attName);
+ }
+ if ("".equals(attribute))
+ {
+ attCombo.setSelectedItem(null);
+ }
+ else
+ {
+ attCombo.setSelectedItem(attribute);
+ }
+ attCombo.addItemListener(itemListener);
+ }
+ filterRow.add(attCombo);
+
+ /*
+ * drop-down choice of test condition
+ */
+ for (Condition c : Condition.values())
+ {
+ condCombo.addItem(c);
+ }
+ if (cond != null)
+ {
+ condCombo.setSelectedItem(cond);
+ }
+ condCombo.addItemListener(itemListener);
+ filterRow.add(condCombo);
+
+ /*
+ * pattern to match against
+ */
+ patternField.setText(pattern);
+ patternField.addActionListener(actionListener);
+ patternField.addFocusListener(new FocusAdapter()
+ {
+ @Override
+ public void focusLost(FocusEvent e)
+ {
+ actionListener.actionPerformed(null);
+ }
+ });
+ filterRow.add(patternField);
+
+ /*
+ * add remove button if filter is populated (non-empty pattern)
+ */
+ if (pattern != null && pattern.trim().length() > 0)
+ {
+ // todo: gif for - button
+ JButton removeCondition = new BasicArrowButton(SwingConstants.WEST);
+ removeCondition.setToolTipText(MessageManager
+ .getString("label.delete_row"));
+ removeCondition.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ filters.remove(i);
+ filtersChanged();
+ }
+ });
+ filterRow.add(removeCondition);
+ }
+
+ return filterRow;
+ }
+
+ /**
+ * Action on any change to feature filtering, namely
+ * <ul>
+ * <li>change of selected attribute</li>
+ * <li>change of selected condition</li>
+ * <li>change of match pattern</li>
+ * <li>removal of a condition</li>
+ * </ul>
+ * The action should be to
+ * <ul>
+ * <li>parse and validate the filters</li>
+ * <li>if valid, update the filter text box</li>
+ * <li>and apply the filters to the viewport</li>
+ * </ul>
+ */
+ protected void filtersChanged()
+ {
+ /*
+ * update the filter conditions for the feature type
+ */
+ String featureType = (String) filteredFeatureChoice.getSelectedItem();
+ boolean anded = andFilters.isSelected();
+ KeyedMatcherSetI combined = new KeyedMatcherSet();
+
+ for (KeyedMatcherI filter : filters)
+ {
+ String pattern = filter.getMatcher().getPattern();
+ if (pattern.trim().length() > 0)
+ {
+ if (anded)
+ {
+ combined.and(filter);
+ }
+ else
+ {
+ combined.or(filter);
+ }
+ }
+ }
+
+ /*
+ * save the filter conditions in the FeatureRenderer
+ * (note this might now be an empty filter with no conditions)
+ */
+ fr.setFeatureFilter(featureType, combined);
+
+ filtersAsText.setText(combined.toString());
+
+ refreshFiltersDisplay();
+
+ af.alignPanel.paintAlignment(true, true);
+ }
+
+ /**
+ * Constructs a filter condition from the given input fields, and replaces the
+ * condition at filterIndex with the new one
+ *
+ * @param attCombo
+ * @param condCombo
+ * @param valueField
+ * @param filterIndex
+ */
+ protected void updateFilter(JComboBox<String> attCombo,
+ JComboBox<Condition> condCombo, JTextField valueField,
+ int filterIndex)
+ {
+ String attName = (String) attCombo.getSelectedItem();
+ Condition cond = (Condition) condCombo.getSelectedItem();
+ String pattern = valueField.getText();
+ KeyedMatcherI km = new KeyedMatcher(attName, cond, pattern);
+
+ filters.set(filterIndex, km);
}
public void fetchDAS_actionPerformed(ActionEvent e)
JvOptionPane.DEFAULT_OPTION, JvOptionPane.INFORMATION_MESSAGE);
}
+ /**
+ * Answers true unless a numeric condition has been selected with a
+ * non-numeric value. Sets the value field to RED with a tooltip if in error.
+ * <p>
+ * If the pattern entered is empty, this method returns false, but does not
+ * mark the field as invalid. This supports selecting an attribute for a new
+ * condition before a match pattern has been entered.
+ *
+ * @param value
+ * @param condCombo
+ */
+ protected boolean validateFilter(JTextField value,
+ JComboBox<Condition> condCombo)
+ {
+ if (value == null || condCombo == null)
+ {
+ return true; // fields not populated
+ }
+
+ Condition cond = (Condition) condCombo.getSelectedItem();
+ value.setBackground(Color.white);
+ value.setToolTipText("");
+ String v1 = value.getText().trim();
+ if (v1.length() == 0)
+ {
+ return false;
+ }
+
+ if (cond.isNumeric())
+ {
+ try
+ {
+ Float.valueOf(v1);
+ } catch (NumberFormatException e)
+ {
+ value.setBackground(Color.red);
+ value.setToolTipText(MessageManager
+ .getString("label.numeric_required"));
+ return false;
+ }
+ }
+
+ return true;
+ }
+
// ///////////////////////////////////////////////////////////////////////
// http://java.sun.com/docs/books/tutorial/uiswing/components/table.html
// ///////////////////////////////////////////////////////////////////////