import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridLayout;
+import java.awt.LayoutManager;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.help.HelpSetException;
import javax.swing.AbstractCellEditor;
import javax.swing.BorderFactory;
+import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.Icon;
import javax.swing.JButton;
public class FeatureSettings extends JPanel
implements FeatureSettingsControllerI
{
+ private static final String COLON = ":";
+
private static final int MIN_WIDTH = 400;
private static final int MIN_HEIGHT = 400;
+ private static final int MAX_TOOLTIP_LENGTH = 50;
+
DasSourceBrowser dassourceBrowser;
DasSequenceFeatureFetcher dasFeatureFetcher;
private JTextArea filtersAsText;
+ // set white normally, black to debug layout
+ private Color debugBorderColour = Color.white;
+
/**
* Constructor
*
});
men.add(dens);
- if (minmax != null)
+
+ /*
+ * variable colour options include colour by label, by score,
+ * by selected attribute text, or attribute value
+ */
+ final JCheckBoxMenuItem mxcol = new JCheckBoxMenuItem(
+ MessageManager.getString("label.variable_colour"));
+ mxcol.setSelected(!featureColour.isSimpleColour());
+ men.add(mxcol);
+ mxcol.addActionListener(new ActionListener()
{
- final float[][] typeMinMax = minmax.get(type);
- /*
- * final JCheckBoxMenuItem chb = new JCheckBoxMenuItem("Vary Height"); //
- * this is broken at the moment and isn't that useful anyway!
- * chb.setSelected(minmax.get(type) != null); chb.addActionListener(new
- * ActionListener() {
- *
- * public void actionPerformed(ActionEvent e) {
- * chb.setState(chb.getState()); if (chb.getState()) { minmax.put(type,
- * null); } else { minmax.put(type, typeMinMax); } }
- *
- * });
- *
- * men.add(chb);
- */
- if (typeMinMax != null && typeMinMax[0] != null)
- {
- // if (table.getValueAt(row, column));
- // graduated colourschemes for those where minmax exists for the
- // positional features
- final JCheckBoxMenuItem mxcol = new JCheckBoxMenuItem(
- "Graduated Colour");
- mxcol.setSelected(!featureColour.isSimpleColour());
- men.add(mxcol);
- mxcol.addActionListener(new ActionListener()
- {
- JColorChooser colorChooser;
+ JColorChooser colorChooser;
- @Override
- public void actionPerformed(ActionEvent e)
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ if (e.getSource() == mxcol)
+ {
+ if (featureColour.isSimpleColour())
{
- if (e.getSource() == mxcol)
- {
- if (featureColour.isSimpleColour())
- {
- FeatureColourChooser fc = new FeatureColourChooser(me.fr,
- type);
- fc.addActionListener(this);
- }
- else
- {
- // bring up simple color chooser
- colorChooser = new JColorChooser();
- JDialog dialog = JColorChooser.createDialog(me,
- "Select new Colour", true, // modal
- colorChooser, this, // OK button handler
- null); // no CANCEL button handler
- colorChooser.setColor(featureColour.getMaxColour());
- dialog.setVisible(true);
- }
- }
- else
- {
- if (e.getSource() instanceof FeatureColourChooser)
- {
- FeatureColourChooser fc = (FeatureColourChooser) e
- .getSource();
- table.setValueAt(fc.getLastColour(), selectedRow, 1);
- table.validate();
- }
- else
- {
- // probably the color chooser!
- table.setValueAt(new FeatureColour(colorChooser.getColor()),
- selectedRow, 1);
- table.validate();
- me.updateFeatureRenderer(
- ((FeatureTableModel) table.getModel()).getData(),
- false);
- }
- }
+ FeatureColourChooser fc = new FeatureColourChooser(me.fr, type);
+ fc.addActionListener(this);
}
-
- });
+ else
+ {
+ // bring up simple color chooser
+ colorChooser = new JColorChooser();
+ JDialog dialog = JColorChooser.createDialog(me,
+ "Select new Colour", true, // modal
+ colorChooser, this, // OK button handler
+ null); // no CANCEL button handler
+ colorChooser.setColor(featureColour.getMaxColour());
+ dialog.setVisible(true);
+ }
+ }
+ else
+ {
+ if (e.getSource() instanceof FeatureColourChooser)
+ {
+ FeatureColourChooser fc = (FeatureColourChooser) e.getSource();
+ table.setValueAt(fc.getLastColour(), selectedRow, 1);
+ table.validate();
+ }
+ else
+ {
+ // probably the color chooser!
+ table.setValueAt(new FeatureColour(colorChooser.getColor()),
+ selectedRow, 1);
+ table.validate();
+ me.updateFeatureRenderer(
+ ((FeatureTableModel) table.getModel()).getData(), false);
+ }
+ }
}
- }
+
+ });
+
JMenuItem selCols = new JMenuItem(
MessageManager.getString("label.select_columns_containing"));
selCols.addActionListener(new ActionListener()
*/
JPanel chooseTypePanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
chooseTypePanel.setBackground(Color.white);
- chooseTypePanel.setBorder(BorderFactory
- .createTitledBorder(MessageManager
- .getString("label.feature_type")));
+ JvSwingUtils.createItalicTitledBorder(chooseTypePanel,
+ MessageManager.getString("label.feature_type"), true);
filteredFeatureChoice = new JComboBox<>();
filteredFeatureChoice.addItemListener(new ItemListener()
{
/*
* the panel with the filters for the selected feature type
*/
- JPanel filtersPanel = new JPanel(new GridLayout(0, 1));
+ JPanel filtersPanel = new JPanel();
+ filtersPanel.setLayout(new BoxLayout(filtersPanel, BoxLayout.Y_AXIS));
filtersPanel.setBackground(Color.white);
- filtersPanel.setBorder(BorderFactory
- .createTitledBorder(MessageManager.getString("label.filters")));
+ JvSwingUtils.createItalicTitledBorder(filtersPanel,
+ MessageManager.getString("label.filters"), true);
/*
* add AND or OR radio buttons
*/
JPanel andOrPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
andOrPanel.setBackground(Color.white);
+ andOrPanel.setBorder(BorderFactory.createLineBorder(debugBorderColour));
andFilters = new JRadioButton("And");
orFilters = new JRadioButton("Or");
ActionListener actionListener = new ActionListener()
/*
* panel with filters - populated by refreshFiltersDisplay
*/
- chooseFiltersPanel = new JPanel(new GridLayout(0, 1));
+ chooseFiltersPanel = new JPanel();
+ LayoutManager box = new BoxLayout(chooseFiltersPanel,
+ BoxLayout.Y_AXIS);
+ chooseFiltersPanel.setLayout(box);
filtersPanel.add(chooseFiltersPanel);
/*
*/
JPanel showFiltersPanel = new JPanel(new BorderLayout(5, 5));
showFiltersPanel.setBackground(Color.white);
- showFiltersPanel.setBorder(BorderFactory
- .createTitledBorder(MessageManager
- .getString("label.match_condition")));
+ JvSwingUtils.createItalicTitledBorder(showFiltersPanel,
+ MessageManager.getString("label.match_condition"), true);
filtersAsText = new JTextArea();
filtersAsText.setLineWrap(true);
filtersAsText.setWrapStyleWord(true);
}
if (!found)
{
- filteredFeatureChoice
- .addItem("No filterable feature attributes known");
+ filteredFeatureChoice.addItem(MessageManager
+ .getString("label.no_feature_attributes"));
+ filteredFeatureChoice.setEnabled(false);
}
filteredFeatureChoice.addItemListener(listener);
-
}
/**
* clear the panel and list of filter conditions
*/
chooseFiltersPanel.removeAll();
-
- String selectedType = (String) filteredFeatureChoice.getSelectedItem();
-
filters.clear();
/*
* look up attributes known for feature type
*/
- List<String> attNames = FeatureAttributes.getInstance().getAttributes(
- selectedType);
+ String selectedType = (String) filteredFeatureChoice.getSelectedItem();
+ List<String[]> attNames = FeatureAttributes.getInstance()
+ .getAttributes(selectedType);
/*
* if this feature type has filters set, load them first
{
orFilters.setSelected(true);
}
- Iterator<KeyedMatcherI> matchers = featureFilters.getMatchers();
- while (matchers.hasNext())
- {
- filters.add(matchers.next());
- }
+ featureFilters.getMatchers().forEach(matcher -> filters.add(matcher));
}
/*
* and an empty filter for the user to populate (add)
*/
- KeyedMatcherI noFilter = new KeyedMatcher("", Condition.values()[0], "");
+ KeyedMatcherI noFilter = new KeyedMatcher(Condition.values()[0], "",
+ (String) null);
filters.add(noFilter);
/*
* render the conditions in rows, each in its own JPanel
*/
- int i = 0;
+ int filterIndex = 0;
for (KeyedMatcherI filter : filters)
{
- String key = filter.getKey();
+ String[] attName = filter.getKey();
Condition condition = filter.getMatcher()
.getCondition();
String pattern = filter.getMatcher().getPattern();
- JPanel row = addFilter(key, attNames, condition, pattern, i);
+ JPanel row = addFilter(attName, attNames, condition, pattern, filterIndex);
+ row.setBorder(BorderFactory.createLineBorder(debugBorderColour));
chooseFiltersPanel.add(row);
- i++;
+ filterIndex++;
}
+ // chooseFiltersPanel.add(Box.createVerticalGlue());
filtersPane.validate();
filtersPane.repaint();
* <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).
+ * 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 attName
* @param attNames
* @param cond
* @param pattern
- * @param i
+ * @param filterIndex
* @return
*/
- protected JPanel addFilter(String attribute, List<String> attNames,
- Condition cond, String pattern, int i)
+ protected JPanel addFilter(String[] attName, List<String[]> attNames,
+ Condition cond, String pattern, int filterIndex)
{
JPanel filterRow = new JPanel(new FlowLayout(FlowLayout.LEFT));
filterRow.setBackground(Color.white);
/*
- * inputs for attribute, condition, pattern
+ * drop-down choice of attribute, with description as a tooltip
+ * if we can obtain it
*/
- JComboBox<String> attCombo = new JComboBox<>();
+ String featureType = (String) filteredFeatureChoice.getSelectedItem();
+ final JComboBox<String> attCombo = populateAttributesDropdown(
+ featureType, attNames);
JComboBox<Condition> condCombo = new JComboBox<>();
JTextField patternField = new JTextField(8);
{
if (validateFilter(patternField, condCombo))
{
- updateFilter(attCombo, condCombo, patternField, i);
+ updateFilter(attCombo, condCombo, patternField, filterIndex);
filtersChanged();
}
}
}
};
- /*
- * drop-down choice of attribute
- */
- if (attNames.isEmpty())
+ if (attName == null) // the 'add a condition' row
{
- attCombo.addItem("---");
- attCombo.setToolTipText(MessageManager
- .getString("label.no_attributes_known"));
+ attCombo.setSelectedItem(null);
}
else
{
- attCombo.setToolTipText("");
- for (String attName : attNames)
- {
- attCombo.addItem(attName);
- }
- if ("".equals(attribute))
- {
- attCombo.setSelectedItem(null);
- }
- else
- {
- attCombo.setSelectedItem(attribute);
- }
- attCombo.addItemListener(itemListener);
+ attCombo.setSelectedItem(String.join(COLON, attName));
}
+ attCombo.addItemListener(itemListener);
+
filterRow.add(attCombo);
/*
*/
if (pattern != null && pattern.trim().length() > 0)
{
- // todo: gif for - button
+ // todo: gif for button drawing '-' or 'x'
JButton removeCondition = new BasicArrowButton(SwingConstants.WEST);
removeCondition.setToolTipText(MessageManager
.getString("label.delete_row"));
@Override
public void actionPerformed(ActionEvent e)
{
- filters.remove(i);
+ filters.remove(filterIndex);
filtersChanged();
}
});
}
/**
+ * 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.
+ *
+ * @param featureType
+ * @param attNames
+ */
+ protected JComboBox<String> populateAttributesDropdown(
+ String featureType, List<String[]> attNames)
+ {
+ List<String> displayNames = new ArrayList<>();
+ List<String> tooltips = new ArrayList<>();
+ FeatureAttributes fa = FeatureAttributes.getInstance();
+ for (String[] attName : attNames)
+ {
+ String desc = fa.getDescription(featureType, attName);
+ if (desc != null && desc.length() > MAX_TOOLTIP_LENGTH)
+ {
+ desc = desc.substring(0, MAX_TOOLTIP_LENGTH) + "...";
+ }
+ displayNames.add(String.join(COLON, attName));
+ tooltips.add(desc == null ? "" : desc);
+ }
+
+ JComboBox<String> attCombo = JvSwingUtils.buildComboWithTooltips(
+ displayNames, tooltips);
+ if (attNames.isEmpty())
+ {
+ attCombo.setToolTipText(MessageManager
+ .getString("label.no_attributes"));
+ }
+ return attCombo;
+ }
+
+ /**
* Action on any change to feature filtering, namely
* <ul>
* <li>change of selected attribute</li>
String attName = (String) attCombo.getSelectedItem();
Condition cond = (Condition) condCombo.getSelectedItem();
String pattern = valueField.getText();
- KeyedMatcherI km = new KeyedMatcher(attName, cond, pattern);
+ KeyedMatcherI km = new KeyedMatcher(cond, pattern,
+ attName.split(COLON));
filters.set(filterIndex, km);
}
boolean isSelected, boolean hasFocus, int row, int column)
{
FeatureColourI cellColour = (FeatureColourI) color;
- // JLabel comp = new JLabel();
- // comp.
setOpaque(true);
- // comp.
- // setBounds(getBounds());
- Color newColor;
setToolTipText(baseTT);
setBackground(tbl.getBackground());
if (!cellColour.isSimpleColour())
Rectangle cr = tbl.getCellRect(row, column, false);
FeatureSettings.renderGraduatedColor(this, cellColour,
(int) cr.getWidth(), (int) cr.getHeight());
-
}
else
{
this.setText("");
this.setIcon(null);
- newColor = cellColour.getColour();
- setBackground(newColor);
+ setBackground(cellColour.getColour());
}
if (isSelected)
{
int w, int h)
{
boolean thr = false;
- String tt = "";
- String tx = "";
+ StringBuilder tt = new StringBuilder();
+ StringBuilder tx = new StringBuilder();
+
+ if (gcol.isColourByAttribute())
+ {
+ tx.append(String.join(":", gcol.getAttributeName()));
+ }
+ else if (!gcol.isColourByLabel())
+ {
+ tx.append(MessageManager.getString("label.score"));
+ }
+ tx.append(" ");
if (gcol.isAboveThreshold())
{
thr = true;
- tx += ">";
- tt += "Thresholded (Above " + gcol.getThreshold() + ") ";
+ tx.append(">");
+ tt.append("Thresholded (Above ").append(gcol.getThreshold())
+ .append(") ");
}
if (gcol.isBelowThreshold())
{
thr = true;
- tx += "<";
- tt += "Thresholded (Below " + gcol.getThreshold() + ") ";
+ tx.append("<");
+ tt.append("Thresholded (Below ").append(gcol.getThreshold())
+ .append(") ");
}
if (gcol.isColourByLabel())
{
- tt = "Coloured by label text. " + tt;
+ tt.append("Coloured by label text. ").append(tt);
if (thr)
{
- tx += " ";
+ tx.append(" ");
+ }
+ if (!gcol.isColourByAttribute())
+ {
+ tx.append("Label");
}
- tx += "Label";
comp.setIcon(null);
}
else
// + ", " + minCol.getBlue() + ")");
}
comp.setHorizontalAlignment(SwingConstants.CENTER);
- comp.setText(tx);
+ comp.setText(tx.toString());
if (tt.length() > 0)
{
if (comp.getToolTipText() == null)
{
- comp.setToolTipText(tt);
+ comp.setToolTipText(tt.toString());
}
else
{
- comp.setToolTipText(tt + " " + comp.getToolTipText());
+ comp.setToolTipText(tt.append(" ").append(comp.getToolTipText())
+ .toString());
}
}
}
button.setBorderPainted(false);
// Set up the dialog that the button brings up.
colorChooser = new JColorChooser();
- dialog = JColorChooser.createDialog(button, "Select new Colour", true, // modal
+ dialog = JColorChooser.createDialog(button,
+ MessageManager.getString("label.select_new_colour"), true, // modal
colorChooser, this, // OK button handler
null); // no CANCEL button handler
}