*/
package jalview.gui;
-import jalview.api.FeatureColourI;
-import jalview.api.FeatureSettingsControllerI;
-import jalview.datamodel.AlignmentI;
-import jalview.datamodel.SequenceI;
-import jalview.datamodel.features.FeatureMatcher;
-import jalview.datamodel.features.FeatureMatcherI;
-import jalview.datamodel.features.FeatureMatcherSet;
-import jalview.datamodel.features.FeatureMatcherSetI;
-import jalview.gui.Help.HelpId;
-import jalview.io.JalviewFileChooser;
-import jalview.io.JalviewFileView;
-import jalview.schemes.FeatureColour;
-import jalview.util.MessageManager;
-import jalview.util.Platform;
-import jalview.viewmodel.seqfeatures.FeatureRendererModel.FeatureSettingsBean;
-import jalview.xml.binding.jalview.JalviewUserColours;
-import jalview.xml.binding.jalview.JalviewUserColours.Colour;
-import jalview.xml.binding.jalview.JalviewUserColours.Filter;
-import jalview.xml.binding.jalview.ObjectFactory;
-
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 javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
-import javax.swing.JColorChooser;
-import javax.swing.JDialog;
+import javax.swing.JCheckBoxMenuItem;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants;
+import javax.swing.ToolTipManager;
import javax.swing.border.Border;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
+import jalview.api.AlignViewControllerGuiI;
+import jalview.api.AlignViewportI;
+import jalview.api.FeatureColourI;
+import jalview.api.FeatureSettingsControllerI;
+import jalview.api.SplitContainerI;
+import jalview.api.ViewStyleI;
+import jalview.controller.FeatureSettingsControllerGuiI;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SequenceI;
+import jalview.datamodel.features.FeatureMatcher;
+import jalview.datamodel.features.FeatureMatcherI;
+import jalview.datamodel.features.FeatureMatcherSet;
+import jalview.datamodel.features.FeatureMatcherSetI;
+import jalview.gui.Help.HelpId;
+import jalview.gui.JalviewColourChooser.ColourChooserListener;
+import jalview.io.JalviewFileChooser;
+import jalview.io.JalviewFileView;
+import jalview.schemes.FeatureColour;
+import jalview.util.MessageManager;
+import jalview.util.Platform;
+import jalview.viewmodel.seqfeatures.FeatureRendererModel.FeatureSettingsBean;
+import jalview.viewmodel.styles.ViewStyle;
+import jalview.xml.binding.jalview.JalviewUserColours;
+import jalview.xml.binding.jalview.JalviewUserColours.Colour;
+import jalview.xml.binding.jalview.JalviewUserColours.Filter;
+import jalview.xml.binding.jalview.ObjectFactory;
+
public class FeatureSettings extends JPanel
- implements FeatureSettingsControllerI
+ implements FeatureSettingsControllerI, FeatureSettingsControllerGuiI
{
private static final String SEQUENCE_FEATURE_COLOURS = MessageManager
.getString("label.sequence_feature_colours");
private static final int MIN_HEIGHT = 400;
- private final static String BASE_TOOLTIP = MessageManager.getString("label.click_to_edit");
+ private final static String BASE_TOOLTIP = MessageManager
+ .getString("label.click_to_edit");
final FeatureRenderer fr;
*/
Object[][] originalData;
- float originalTransparency;
+ private float originalTransparency;
+ private ViewStyleI originalViewStyle;
+
private Map<String, FeatureMatcherSetI> originalFilters;
final JInternalFrame frame;
JPanel groupPanel;
- JSlider transparency;
+ JSlider transparency = new JSlider();
+
+ private JCheckBox showComplementOnTop;
+
+ private JCheckBox showComplement;
/*
* when true, constructor is still executing - so ignore UI events
/*
* true when Feature Settings are updating from feature renderer
*/
- boolean handlingUpdate = false;
+ private boolean handlingUpdate = false;
/*
+ * a change listener to ensure the dialog is updated if
+ * FeatureRenderer discovers new features
+ */
+ private PropertyChangeListener change;
+
+ /*
* holds {featureCount, totalExtent} for each feature type
*/
Map<String, float[]> typeWidth = null;
+ private void storeOriginalSettings()
+ {
+ // save transparency for restore on Cancel
+ originalTransparency = fr.getTransparency();
+
+ updateTransparencySliderFromFR();
+
+ originalFilters = new HashMap<>(fr.getFeatureFilters()); // shallow copy
+ originalViewStyle = new ViewStyle(af.viewport.getViewStyle());
+ }
+
+ private void updateTransparencySliderFromFR()
+ {
+ boolean incon = inConstruction;
+ inConstruction = true;
+
+ int transparencyAsPercent = (int) (fr.getTransparency() * 100);
+ transparency.setValue(100 - transparencyAsPercent);
+ inConstruction = incon;
+ }
/**
* Constructor
*
this.af = alignFrame;
fr = af.getFeatureRenderer();
- // save transparency for restore on Cancel
- originalTransparency = fr.getTransparency();
- int originalTransparencyAsPercent = (int) (originalTransparency * 100);
- transparency = new JSlider(0, 70, 100 - originalTransparencyAsPercent);
-
- originalFilters = new HashMap<>(fr.getFeatureFilters()); // shallow copy
+ storeOriginalSettings();
try
{
default:
break;
}
-
+
return tip;
}
tableHeader.setFont(new Font("Verdana", Font.PLAIN, 12));
tableHeader.setReorderingAllowed(false);
table.setFont(new Font("Verdana", Font.PLAIN, 12));
-
- table.setDefaultEditor(FeatureColour.class, new ColorEditor(this));
+ ToolTipManager.sharedInstance().registerComponent(table);
+ table.setDefaultEditor(FeatureColour.class, new ColorEditor());
table.setDefaultRenderer(FeatureColour.class, new ColorRenderer());
- table.setDefaultEditor(FeatureMatcherSet.class, new FilterEditor(this));
+ table.setDefaultEditor(FeatureMatcherSet.class, new FilterEditor());
table.setDefaultRenderer(FeatureMatcherSet.class, new FilterRenderer());
TableColumn colourColumn = new TableColumn(COLOUR_COLUMN, 75,
- new ColorRenderer(), new ColorEditor(this));
+ new ColorRenderer(), new ColorEditor());
table.addColumn(colourColumn);
TableColumn filterColumn = new TableColumn(FILTER_COLUMN, 75,
- new FilterRenderer(), new FilterEditor(this));
+ new FilterRenderer(), new FilterEditor());
table.addColumn(filterColumn);
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
@Override
public void mousePressed(MouseEvent evt)
{
- selectedRow = table.rowAtPoint(evt.getPoint());
+ Point pt = evt.getPoint();
+ selectedRow = table.rowAtPoint(pt);
String type = (String) table.getValueAt(selectedRow, TYPE_COLUMN);
if (evt.isPopupTrigger())
{
Object colour = table.getValueAt(selectedRow, COLOUR_COLUMN);
- popupSort(selectedRow, type, colour, fr.getMinMax(), evt.getX(),
- evt.getY());
+ showPopupMenu(selectedRow, type, colour, evt.getPoint());
}
- else if (evt.getClickCount() == 2)
+ else if (evt.getClickCount() == 2
+ && table.columnAtPoint(pt) == TYPE_COLUMN)
{
boolean invertSelection = evt.isAltDown();
boolean toggleSelection = Platform.isControlDown(evt);
boolean extendSelection = evt.isShiftDown();
fr.ap.alignFrame.avc.markColumnsContainingFeatures(
invertSelection, extendSelection, toggleSelection, type);
+ fr.ap.av.sendSelection();
}
}
{
String type = (String) table.getValueAt(selectedRow, TYPE_COLUMN);
Object colour = table.getValueAt(selectedRow, COLOUR_COLUMN);
- popupSort(selectedRow, type, colour, fr.getMinMax(), evt.getX(),
- evt.getY());
+ showPopupMenu(selectedRow, type, colour, evt.getPoint());
}
}
});
}
discoverAllFeatureData();
- final PropertyChangeListener change;
final FeatureSettings fs = this;
fr.addPropertyChangeListener(change = new PropertyChangeListener()
{
});
- frame = new JInternalFrame();
- frame.setContentPane(this);
- if (Platform.isAMac())
+ SplitContainerI splitframe = af.getSplitViewContainer();
+ if (splitframe != null)
{
- Desktop.addInternalFrame(frame,
- MessageManager.getString("label.sequence_feature_settings"),
- 600, 480);
+ frame = null; // keeps eclipse happy
+ splitframe.addFeatureSettingsUI(this);
}
else
{
- Desktop.addInternalFrame(frame,
- MessageManager.getString("label.sequence_feature_settings"),
- 600, 450);
- }
- frame.setMinimumSize(new Dimension(MIN_WIDTH, MIN_HEIGHT));
+ frame = new JInternalFrame();
+ frame.setContentPane(this);
+ Rectangle bounds = af.getFeatureSettingsGeometry();
+ String title;
+ if (af.getAlignPanels().size() > 1 || Desktop.getAlignmentPanels(
+ af.alignPanel.av.getSequenceSetId()).length > 1)
+ {
+ title = MessageManager.formatMessage(
+ "label.sequence_feature_settings_for_view",
+ af.alignPanel.getViewName());
+ }
+ else
+ {
+ title = MessageManager.getString("label.sequence_feature_settings");
+ }
+ if (bounds == null)
+ {
+ if (Platform.isAMacAndNotJS())
+ {
+ Desktop.addInternalFrame(frame, title, 600, 480);
+ }
+ else
+ {
+ Desktop.addInternalFrame(frame, title, 600, 450);
+ }
+ }
+ else
+ {
+ Desktop.addInternalFrame(frame, title, false, bounds.width,
+ bounds.height);
+ frame.setBounds(bounds);
+ frame.setVisible(true);
+ }
+ frame.setMinimumSize(new Dimension(MIN_WIDTH, MIN_HEIGHT));
- frame.addInternalFrameListener(
- new javax.swing.event.InternalFrameAdapter()
- {
- @Override
- public void internalFrameClosed(
- javax.swing.event.InternalFrameEvent evt)
+ frame.addInternalFrameListener(
+ new javax.swing.event.InternalFrameAdapter()
{
- fr.removePropertyChangeListener(change);
- };
- });
- frame.setLayer(JLayeredPane.PALETTE_LAYER);
- inConstruction = false;
+ @Override
+ public void internalFrameClosed(
+ javax.swing.event.InternalFrameEvent evt)
+ {
+ featureSettings_isClosed();
+ };
+ });
+ frame.setLayer(JLayeredPane.PALETTE_LAYER);
+ }
+ inConstruction = false;
+ }
+
+ /**
+ * Sets the state of buttons to show complement features from viewport
+ * settings
+ */
+ private void updateComplementButtons()
+ {
+ showComplement.setSelected(af.getViewport().isShowComplementFeatures());
+ showComplementOnTop
+ .setSelected(af.getViewport().isShowComplementFeaturesOnTop());
}
- protected void popupSort(final int rowSelected, final String type,
- final Object typeCol, final Map<String, float[][]> minmax, int x,
- int y)
+ @Override
+ public AlignViewControllerGuiI getAlignframe()
{
- final FeatureColourI featureColour = (FeatureColourI) typeCol;
+ return af;
+ }
+ @Override
+ public void featureSettings_isClosed()
+ {
+ fr.removePropertyChangeListener(change);
+ change = null;
+ }
+
+ /**
+ * Constructs and shows a popup menu of possible actions on the selected row and
+ * feature type
+ *
+ * @param rowSelected
+ * @param type
+ * @param typeCol
+ * @param pt
+ */
+ protected void showPopupMenu(final int rowSelected, final String type, final Object typeCol, final Point pt)
+ {
JPopupMenu men = new JPopupMenu(MessageManager
.formatMessage("label.settings_for_param", new String[]
{ type }));
+ final FeatureColourI featureColour = (FeatureColourI) typeCol;
+
+ /*
+ * menu option to select (or deselect) variable colour
+ */
+ final JCheckBoxMenuItem variableColourCB = new JCheckBoxMenuItem(
+ MessageManager.getString("label.variable_colour"));
+ variableColourCB.setSelected(!featureColour.isSimpleColour());
+ men.add(variableColourCB);
+
+ /*
+ * checkbox action listener doubles up as listener to OK
+ * from the variable colour / filters dialog
+ */
+ variableColourCB.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ if (e.getSource() == variableColourCB)
+ {
+ // BH 2018 for JavaScript because this is a checkbox
+ men.setVisible(true);
+ men.setVisible(false);
+ if (featureColour.isSimpleColour())
+ {
+ /*
+ * toggle simple colour to variable colour - show dialog
+ */
+ FeatureTypeSettings fc = new FeatureTypeSettings(fr, type);
+ fc.addActionListener(this);
+ }
+ else
+ {
+ /*
+ * toggle variable to simple colour - show colour chooser
+ */
+ String title = MessageManager
+ .formatMessage("label.select_colour_for", type);
+ ColourChooserListener listener = new ColourChooserListener()
+ {
+ @Override
+ public void colourSelected(Color c)
+ {
+ table.setValueAt(new FeatureColour(c), rowSelected,
+ COLOUR_COLUMN);
+ table.validate();
+ updateFeatureRenderer(
+ ((FeatureTableModel) table.getModel()).getData(),
+ false);
+ }
+ };
+ JalviewColourChooser.showColourChooser(FeatureSettings.this,
+ title, featureColour.getMaxColour(), listener);
+ }
+ }
+ else
+ {
+ if (e.getSource() instanceof FeatureTypeSettings)
+ {
+ /*
+ * update after OK in feature colour dialog; the updated
+ * colour will have already been set in the FeatureRenderer
+ */
+ FeatureColourI fci = fr.getFeatureColours().get(type);
+ table.setValueAt(fci, rowSelected, COLOUR_COLUMN);
+ // BH 2018 setting a table value does not invalidate it.
+ // System.out.println("FeatureSettings is valied" +
+ // table.validate();
+ }
+ }
+ }
+ });
+
+ men.addSeparator();
+
JMenuItem scr = new JMenuItem(
MessageManager.getString("label.sort_by_score"));
men.add(scr);
- final FeatureSettings me = this;
scr.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
- me.af.avc
- .sortAlignmentByFeatureScore(Arrays.asList(new String[]
- { type }));
+ sortByScore(Arrays.asList(new String[] { type }));
}
-
});
JMenuItem dens = new JMenuItem(
MessageManager.getString("label.sort_by_density"));
dens.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
- me.af.avc
- .sortAlignmentByFeatureDensity(Arrays.asList(new String[]
- { type }));
+ sortByDensity(Arrays.asList(new String[] { type }));
}
-
});
men.add(dens);
{
fr.ap.alignFrame.avc.markColumnsContainingFeatures(false, false,
false, type);
+ fr.ap.av.sendSelection();
}
});
JMenuItem clearCols = new JMenuItem(MessageManager
{
fr.ap.alignFrame.avc.markColumnsContainingFeatures(true, false,
false, type);
+ fr.ap.av.sendSelection();
}
});
JMenuItem hideCols = new JMenuItem(
public void actionPerformed(ActionEvent arg0)
{
fr.ap.alignFrame.hideFeatureColumns(type, true);
+ fr.ap.av.sendSelection();
}
});
JMenuItem hideOtherCols = new JMenuItem(
public void actionPerformed(ActionEvent arg0)
{
fr.ap.alignFrame.hideFeatureColumns(type, false);
+ fr.ap.av.sendSelection();
}
});
men.add(selCols);
men.add(clearCols);
men.add(hideCols);
men.add(hideOtherCols);
- men.show(table, x, y);
+ men.show(table, pt.x, pt.y);
+ }
+
+ /**
+ * Sort the sequences in the alignment by the number of features for the given
+ * feature types (or all features if null)
+ *
+ * @param featureTypes
+ */
+ protected void sortByDensity(List<String> featureTypes)
+ {
+ af.avc.sortAlignmentByFeatureDensity(featureTypes);
+ }
+
+ /**
+ * Sort the sequences in the alignment by average score for the given feature
+ * types (or all features if null)
+ *
+ * @param featureTypes
+ */
+ protected void sortByScore(List<String> featureTypes)
+ {
+ af.avc.sortAlignmentByFeatureScore(featureTypes);
+ }
+
+ /**
+ * Returns true if at least one feature type is visible. Else shows a warning
+ * dialog and returns false.
+ *
+ * @param title
+ * @return
+ */
+ private boolean canSortBy(String title)
+ {
+ if (fr.getDisplayedFeatureTypes().isEmpty())
+ {
+ JvOptionPane.showMessageDialog(this,
+ MessageManager.getString("label.no_features_to_sort_by"),
+ title, JvOptionPane.OK_OPTION);
+ return false;
+ }
+ return true;
}
@Override
{
fr.setGroupVisibility(check.getText(), check.isSelected());
resetTable(new String[] { grp });
- af.alignPanel.paintAlignment(true, true);
+ refreshDisplay();
}
});
groupPanel.add(check);
}
/**
- * Updates 'originalData' (used for restore on Cancel) if we detect that changes
- * have been made outwith this dialog
+ * Updates 'originalData' (used for restore on Cancel) if we detect that
+ * changes have been made outwith this dialog
* <ul>
* <li>a new feature type added (and made visible)</li>
* <li>a feature colour changed (in the Amend Features dialog)</li>
/**
* Remove from the groups panel any checkboxes for groups that are not in the
- * foundGroups set. This enables removing a group from the display when the last
- * feature in that group is deleted.
+ * foundGroups set. This enables removing a group from the display when the
+ * last feature in that group is deleted.
*
* @param foundGroups
*/
chooser.setDialogTitle(
MessageManager.getString("label.load_feature_colours"));
chooser.setToolTipText(MessageManager.getString("action.load"));
-
- int value = chooser.showOpenDialog(this);
-
- if (value == JalviewFileChooser.APPROVE_OPTION)
+ chooser.setResponseHandler(0, new Runnable()
{
- File file = chooser.getSelectedFile();
- load(file);
- }
+ @Override
+ public void run()
+ {
+ File file = chooser.getSelectedFile();
+ load(file);
+ }
+ });
+ chooser.showOpenDialog(this);
}
/**
if (table != null)
{
resetTable(null);
- Object[][] data = ((FeatureTableModel) table.getModel())
- .getData();
+ Object[][] data = ((FeatureTableModel) table.getModel()).getData();
ensureOrder(data);
updateFeatureRenderer(data, false);
table.repaint();
chooser.setDialogTitle(
MessageManager.getString("label.save_feature_colours"));
chooser.setToolTipText(MessageManager.getString("action.save"));
-
- int value = chooser.showSaveDialog(this);
-
- if (value == JalviewFileChooser.APPROVE_OPTION)
+ int option = chooser.showSaveDialog(this);
+ if (option == JalviewFileChooser.APPROVE_OPTION)
{
- save(chooser.getSelectedFile());
+ File file = chooser.getSelectedFile();
+ save(file);
}
}
ucs.setSchemeName("Sequence Features");
try
{
- PrintWriter out = new PrintWriter(new OutputStreamWriter(
- new FileOutputStream(file), "UTF-8"));
+ PrintWriter out = new PrintWriter(
+ new OutputStreamWriter(new FileOutputStream(file), "UTF-8"));
/*
* sort feature types by colour order, from 0 (highest)
FeatureMatcherSetI filter = fr.getFeatureFilter(featureType);
if (filter != null && !filter.isEmpty())
{
- Iterator<FeatureMatcherI> iterator = filter.getMatchers().iterator();
+ Iterator<FeatureMatcherI> iterator = filter.getMatchers()
+ .iterator();
FeatureMatcherI firstMatcher = iterator.next();
jalview.xml.binding.jalview.FeatureMatcherSet ms = jalview.project.Jalview2XML
- .marshalFilter(firstMatcher, iterator,
- filter.isAnded());
+ .marshalFilter(firstMatcher, iterator, filter.isAnded());
Filter filterModel = new Filter();
filterModel.setFeatureType(featureType);
filterModel.setMatcherSet(ms);
else
{
width[i] /= max; // normalize
- fr.setOrder(data[i][TYPE_COLUMN].toString(), width[i]); // store for later
+ fr.setOrder(data[i][TYPE_COLUMN].toString(), width[i]); // store for
+ // later
}
if (i > 0)
{
table.repaint();
}
+ /**
+ * close ourselves but leave any existing UI handlers (e.g a CDS/Protein tabbed
+ * feature settings dialog) intact
+ */
+ public void closeOldSettings()
+ {
+ closeDialog(false);
+ }
+
+ /**
+ * close the feature settings dialog (and any containing frame)
+ */
public void close()
{
+ closeDialog(true);
+ }
+
+ private void closeDialog(boolean closeContainingFrame)
+ {
try
{
- frame.setClosed(true);
+ if (frame != null)
+ {
+ af.setFeatureSettingsGeometry(frame.getBounds());
+ frame.setClosed(true);
+ }
+ else
+ {
+ SplitContainerI sc = af.getSplitViewContainer();
+ sc.closeFeatureSettings(this, closeContainingFrame);
+ af.featureSettings = null;
+ }
} catch (Exception exe)
{
}
}
/**
- * Update the priority order of features; only repaint if this changed the order
- * of visible features
+ * Update the priority order of features; only repaint if this changed the
+ * order of visible features
*
* @param data
* @param visibleNew
*/
- private void updateFeatureRenderer(Object[][] data, boolean visibleNew)
+ void updateFeatureRenderer(Object[][] data, boolean visibleNew)
{
FeatureSettingsBean[] rowData = getTableAsBeans(data);
if (fr.setFeaturePriority(rowData, visibleNew))
{
- af.alignPanel.paintAlignment(true, true);
+ refreshDisplay();
}
}
{
this.setLayout(new BorderLayout());
+ final boolean hasComplement = af.getViewport()
+ .getCodingComplement() != null;
+
JPanel settingsPane = new JPanel();
settingsPane.setLayout(new BorderLayout());
}
});
- JButton sortByScore = new JButton(
- MessageManager.getString("label.seq_sort_by_score"));
+ final String byScoreLabel = MessageManager.getString("label.seq_sort_by_score");
+ JButton sortByScore = new JButton(byScoreLabel);
sortByScore.setFont(JvSwingUtils.getLabelFont());
sortByScore.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
- af.avc.sortAlignmentByFeatureScore(null);
+ if (canSortBy(byScoreLabel))
+ {
+ sortByScore(null);
+ }
}
});
- JButton sortByDens = new JButton(
- MessageManager.getString("label.sequence_sort_by_density"));
+ final String byDensityLabel = MessageManager.getString("label.sequence_sort_by_density");
+ JButton sortByDens = new JButton(byDensityLabel);
sortByDens.setFont(JvSwingUtils.getLabelFont());
sortByDens.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
- af.avc.sortAlignmentByFeatureDensity(null);
+ if (canSortBy(byDensityLabel))
+ {
+ sortByDensity(null);
+ }
}
});
}
}
});
-
- JButton cancel = new JButton(MessageManager.getString("action.cancel"));
+ // Cancel for a SplitFrame should just revert changes to the currently displayed
+ // settings. May want to do this for either or both - so need a splitview
+ // feature settings cancel/OK.
+ JButton cancel = new JButton(MessageManager
+ .getString(hasComplement ? "action.revert" : "action.cancel"));
+ cancel.setToolTipText(MessageManager.getString(hasComplement
+ ? "action.undo_changes_to_feature_settings"
+ : "action.undo_changes_to_feature_settings_and_close_the_dialog"));
cancel.setFont(JvSwingUtils.getLabelFont());
+ // TODO: disable cancel (and apply!) until current settings are different
cancel.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
- fr.setTransparency(originalTransparency);
- fr.setFeatureFilters(originalFilters);
- updateFeatureRenderer(originalData);
- close();
+ revert();
+ refreshDisplay();
+ if (!hasComplement)
+ {
+ close();
+ }
}
});
-
- JButton ok = new JButton(MessageManager.getString("action.ok"));
+ // Cancel for the whole dialog should cancel both CDS and Protein.
+ // OK for an individual feature settings just applies changes, but dialog
+ // remains open
+ JButton ok = new JButton(MessageManager
+ .getString(hasComplement ? "action.apply" : "action.ok"));
ok.setFont(JvSwingUtils.getLabelFont());
ok.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
- close();
+ if (!hasComplement)
+ {
+ close();
+ }
+ else
+ {
+ storeOriginalSettings();
+ }
}
});
if (!inConstruction)
{
fr.setTransparency((100 - transparency.getValue()) / 100f);
- af.alignPanel.paintAlignment(true, true);
+ refreshDisplay();
}
}
});
+ transparency.setMaximum(70);
transparency.setToolTipText(
MessageManager.getString("label.transparency_tip"));
- JPanel transPanel = new JPanel(new GridLayout(1, 2));
- bigPanel.add(transPanel, BorderLayout.SOUTH);
+ boolean nucleotide = af.getViewport().getAlignment().isNucleotide();
+ String text = MessageManager.formatMessage("label.show_linked_features",
+ nucleotide
+ ? MessageManager.getString("label.protein")
+ .toLowerCase()
+ : "CDS");
+ showComplement = new JCheckBox(text);
+ showComplement.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ af.getViewport()
+ .setShowComplementFeatures(showComplement.isSelected());
+ refreshDisplay();
+ }
+ });
+
+ showComplementOnTop = new JCheckBox(
+ MessageManager.getString("label.on_top"));
+ showComplementOnTop.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ af.getViewport().setShowComplementFeaturesOnTop(
+ showComplementOnTop.isSelected());
+ refreshDisplay();
+ }
+ });
+
+ updateComplementButtons();
+
+ JPanel lowerPanel = new JPanel(new GridLayout(1, 2));
+ bigPanel.add(lowerPanel, BorderLayout.SOUTH);
JPanel transbuttons = new JPanel(new GridLayout(5, 1));
transbuttons.add(optimizeOrder);
transbuttons.add(sortByScore);
transbuttons.add(sortByDens);
transbuttons.add(help);
- transPanel.add(transparency);
- transPanel.add(transbuttons);
+
+ JPanel transPanelLeft = new JPanel(
+ new GridLayout(hasComplement ? 4 : 2, 1));
+ transPanelLeft.add(new JLabel(" Colour transparency" + ":"));
+ transPanelLeft.add(transparency);
+ if (hasComplement)
+ {
+ JPanel cp = new JPanel(new FlowLayout(FlowLayout.LEFT));
+ cp.add(showComplement);
+ cp.add(showComplementOnTop);
+ transPanelLeft.add(cp);
+ }
+ lowerPanel.add(transPanelLeft);
+ lowerPanel.add(transbuttons);
JPanel buttonPanel = new JPanel();
buttonPanel.add(ok);
}
/**
+ * Repaints alignment, structure and overview (if shown). If there is a
+ * complementary view which is showing this view's features, then also
+ * repaints that.
+ */
+ void refreshDisplay()
+ {
+ af.alignPanel.paintAlignment(true, true);
+ AlignViewportI complement = af.getViewport().getCodingComplement();
+ if (complement != null && complement.isShowComplementFeatures())
+ {
+ AlignFrame af2 = Desktop.getAlignFrameFor(complement);
+ af2.alignPanel.paintAlignment(true, true);
+ }
+ }
+
+ /**
* Answers a suitable tooltip to show on the colour cell of the table
*
* @param fcol
* @param withHint
- * if true include 'click to edit' and similar text
+ * if true include 'click to edit' and similar text
* @return
*/
public static String getColorTooltip(FeatureColourI fcol,
{
boolean thr = false;
StringBuilder tx = new StringBuilder();
-
+
if (gcol.isColourByAttribute())
{
tx.append(FeatureMatcher
}
/**
- * Answers the class of the object in column c of the first row of the table
+ * Answers the class of column c of the table
*/
@Override
public Class<?> getColumnClass(int c)
{
- Object v = getValueAt(0, c);
- return v == null ? null : v.getClass();
+ switch (c)
+ {
+ case TYPE_COLUMN:
+ return String.class;
+ case COLOUR_COLUMN:
+ return FeatureColour.class;
+ case FILTER_COLUMN:
+ return FeatureMatcherSet.class;
+ default:
+ return Boolean.class;
+ }
}
@Override
renderGraduatedColor(comp, gcol, w, h);
}
+ @SuppressWarnings("serial")
class ColorEditor extends AbstractCellEditor
implements TableCellEditor, ActionListener
{
- FeatureSettings me;
-
FeatureColourI currentColor;
FeatureTypeSettings chooser;
JButton button;
- JColorChooser colorChooser;
-
- JDialog dialog;
-
protected static final String EDIT = "edit";
int rowSelected = 0;
- public ColorEditor(FeatureSettings me)
+ public ColorEditor()
{
- this.me = me;
// Set up the editor (from the table's point of view),
// which is a button.
// This button brings up the color chooser dialog,
button.setActionCommand(EDIT);
button.addActionListener(this);
button.setBorderPainted(false);
}
/**
- * Handles events from the editor button and from the dialog's OK button.
+ * Handles events from the editor button, and from the colour/filters
+ * dialog's OK button
*/
@Override
public void actionPerformed(ActionEvent e)
{
- // todo test e.getSource() instead here
- if (EDIT.equals(e.getActionCommand()))
+ if (button == e.getSource())
{
- // The user has clicked the cell, so
- // bring up the dialog.
if (currentColor.isSimpleColour())
{
- // bring up simple color chooser
- button.setBackground(currentColor.getColour());
- colorChooser.setColor(currentColor.getColour());
- dialog.setVisible(true);
+ /*
+ * simple colour chooser
+ */
+ String ttl = MessageManager
+ .formatMessage("label.select_colour_for", type);
+ ColourChooserListener listener = new ColourChooserListener()
+ {
+ @Override
+ public void colourSelected(Color c)
+ {
+ currentColor = new FeatureColour(c);
+ table.setValueAt(currentColor, rowSelected, COLOUR_COLUMN);
+ fireEditingStopped();
+ }
+
+ @Override
+ public void cancel()
+ {
+ fireEditingStopped();
+ }
+ };
+ JalviewColourChooser.showColourChooser(button, ttl,
+ currentColor.getColour(), listener);
}
else
{
- // bring up graduated chooser.
- chooser = new FeatureTypeSettings(me.fr, type);
+ /*
+ * variable colour and filters dialog
+ */
+ chooser = new FeatureTypeSettings(fr, type);
+ if (!Platform.isJS())
/**
- * @j2sNative
+ * Java only
+ *
+ * @j2sIgnore
*/
{
chooser.setRequestFocusEnabled(true);
chooser.requestFocus();
}
chooser.addActionListener(this);
- // Make the renderer reappear.
fireEditingStopped();
}
}
else
{
- if (currentColor.isSimpleColour())
- {
- /*
- * read off colour picked in colour chooser after OK pressed
- */
- currentColor = new FeatureColour(colorChooser.getColor());
- me.table.setValueAt(currentColor, rowSelected, COLOUR_COLUMN);
- }
- else
+ /*
+ * after OK in variable colour dialog, any changes to colour
+ * (or filters!) are already set in FeatureRenderer, so just
+ * update table data without triggering updateFeatureRenderer
+ */
+ currentColor = fr.getFeatureColours().get(type);
+ FeatureMatcherSetI currentFilter = fr.getFeatureFilter(type);
+ if (currentFilter == null)
{
- /*
- * after OK in variable colour dialog, any changes to colour
- * (or filters!) are already set in FeatureRenderer, so just
- * update table data without triggering updateFeatureRenderer
- */
- currentColor = fr.getFeatureColours().get(type);
- FeatureMatcherSetI currentFilter = me.fr.getFeatureFilter(type);
- if (currentFilter == null)
- {
- currentFilter = new FeatureMatcherSet();
- }
- Object[] data = ((FeatureTableModel) table.getModel())
- .getData()[rowSelected];
- data[COLOUR_COLUMN] = currentColor;
- data[FILTER_COLUMN] = currentFilter;
+ currentFilter = new FeatureMatcherSet();
}
+ Object[] data = ((FeatureTableModel) table.getModel())
+ .getData()[rowSelected];
+ data[COLOUR_COLUMN] = currentColor;
+ data[FILTER_COLUMN] = currentFilter;
fireEditingStopped();
- me.table.validate();
+ // SwingJS needs an explicit repaint() here,
+ // rather than relying upon no validation having
+ // occurred since the stopEditing call was made.
+ // Its laying out has not been stopped by the modal frame
+ table.validate();
+ table.repaint();
}
}
+ /**
+ * Override allows access to this method from anonymous inner classes
+ */
+ @Override
+ protected void fireEditingStopped()
+ {
+ super.fireEditingStopped();
+ }
+
// Implement the one CellEditor method that AbstractCellEditor doesn't.
@Override
public Object getCellEditorValue()
// Implement the one method defined by TableCellEditor.
@Override
- public Component getTableCellEditorComponent(JTable theTable, Object value,
- boolean isSelected, int row, int column)
+ public Component getTableCellEditorComponent(JTable theTable,
+ Object value, boolean isSelected, int row, int column)
{
currentColor = (FeatureColourI) value;
this.rowSelected = row;
- type = me.table.getValueAt(row, TYPE_COLUMN).toString();
+ type = table.getValueAt(row, TYPE_COLUMN).toString();
button.setOpaque(true);
- button.setBackground(me.getBackground());
+ button.setBackground(FeatureSettings.this.getBackground());
if (!currentColor.isSimpleColour())
{
JLabel btn = new JLabel();
/**
* The cell editor for the Filter column. It displays the text of any filters
- * for the feature type in that row (in full as a tooltip, possible abbreviated
- * as display text). On click in the cell, opens the Feature Display Settings
- * dialog at the Filters tab.
+ * for the feature type in that row (in full as a tooltip, possible
+ * abbreviated as display text). On click in the cell, opens the Feature
+ * Display Settings dialog at the Filters tab.
*/
+ @SuppressWarnings("serial")
class FilterEditor extends AbstractCellEditor
implements TableCellEditor, ActionListener
{
- FeatureSettings me;
FeatureMatcherSetI currentFilter;
int rowSelected = 0;
- public FilterEditor(FeatureSettings me)
+ public FilterEditor()
{
- this.me = me;
button = new JButton();
button.setActionCommand(EDIT);
button.addActionListener(this);
{
if (button == e.getSource())
{
- FeatureTypeSettings chooser = new FeatureTypeSettings(me.fr, type);
+ FeatureTypeSettings chooser = new FeatureTypeSettings(fr, type);
chooser.addActionListener(this);
chooser.setRequestFocusEnabled(true);
chooser.requestFocus();
* update table data without triggering updateFeatureRenderer
*/
FeatureColourI currentColor = fr.getFeatureColours().get(type);
- currentFilter = me.fr.getFeatureFilter(type);
+ currentFilter = fr.getFeatureFilter(type);
if (currentFilter == null)
{
currentFilter = new FeatureMatcherSet();
}
+
Object[] data = ((FeatureTableModel) table.getModel())
.getData()[rowSelected];
data[COLOUR_COLUMN] = currentColor;
data[FILTER_COLUMN] = currentFilter;
fireEditingStopped();
- me.table.validate();
+ // SwingJS needs an explicit repaint() here,
+ // rather than relying upon no validation having
+ // occurred since the stopEditing call was made.
+ // Its laying out has not been stopped by the modal frame
+ table.validate();
+ table.repaint();
}
}
}
@Override
- public Component getTableCellEditorComponent(JTable theTable, Object value,
- boolean isSelected, int row, int column)
+ public Component getTableCellEditorComponent(JTable theTable,
+ Object value, boolean isSelected, int row, int column)
{
currentFilter = (FeatureMatcherSetI) value;
this.rowSelected = row;
- type = me.table.getValueAt(row, TYPE_COLUMN).toString();
+ type = table.getValueAt(row, TYPE_COLUMN).toString();
button.setOpaque(true);
- button.setBackground(me.getBackground());
+ button.setBackground(FeatureSettings.this.getBackground());
button.setText(currentFilter.toString());
button.setIcon(null);
return button;
}
}
+
+ public boolean isOpen()
+ {
+ if (af.getSplitViewContainer() != null)
+ {
+ return af.getSplitViewContainer().isFeatureSettingsOpen();
+ }
+ return frame != null && !frame.isClosed();
+ }
+
+ @Override
+ public void revert()
+ {
+ fr.setTransparency(originalTransparency);
+ fr.setFeatureFilters(originalFilters);
+ updateFeatureRenderer(originalData);
+ af.getViewport().setViewStyle(originalViewStyle);
+ updateTransparencySliderFromFR();
+ updateComplementButtons();
+ refreshDisplay();
+ }
}
class FeatureIcon implements Icon
g.fillRect(s1, 0, e1 - s1, height);
}
g.setColor(gcol.getMaxColour());
- g.fillRect(0, e1, width - e1, height);
+ // g.fillRect(0, e1, width - e1, height); // BH 2018
+ g.fillRect(e1, 0, width - e1, height);
}
}
}
*/
package jalview.gui;
+import jalview.api.AlignViewportI;
import jalview.api.AlignmentViewPanel;
import jalview.api.FeatureColourI;
import jalview.bin.Cache;
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;
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;
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;
*/
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");
/*
* 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
* 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
private float max;
/*
* 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<Object> threshold = new JComboBox<>();
- JSlider slider = new JSlider();
+ private Slider slider;
- private JTextField thresholdValue = new JTextField(20);
+ JTextField thresholdValue = new JTextField(20);
private JCheckBox thresholdIsMin = new JCheckBox();
/*
* filters for the currently selected feature type
*/
- private List<FeatureMatcherI> filters;
+ List<FeatureMatcherI> filters;
private JPanel chooseFiltersPanel;
return;
}
- updateColoursTab();
+ updateColoursPanel();
- updateFiltersTab();
+ updateFiltersPanel();
adjusting = false;
}
/**
- * 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);
* 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);
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);
}
};
/*
- * 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);
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
{
if (minColour.isEnabled())
{
- showColourChooser(minColour, "label.select_colour_minimum_value");
+ String ttl = MessageManager.getString("label.select_colour_minimum_value");
+ showColourChooser(minColour, ttl);
}
}
});
{
if (maxColour.isEnabled())
{
- showColourChooser(maxColour, "label.select_colour_maximum_value");
+ String ttl = MessageManager.getString("label.select_colour_maximum_value");
+ showColourChooser(maxColour, ttl);
}
}
});
thresholdValue_actionPerformed();
}
});
+ slider = new Slider(0f, 100f, 50f);
slider.setPaintLabels(false);
slider.setPaintTicks(true);
slider.setBackground(Color.white);
{
if (!adjusting)
{
- thresholdValue
- .setText(String.valueOf(slider.getValue() / scaleFactor));
+ setThresholdValueText(slider.getSliderValue());
thresholdValue.setBackground(Color.white); // to reset red for invalid
sliderValueChanged();
}
*/
if (ap != null)
{
- ap.paintAlignment(true, true);
+ refreshDisplay(true);
}
}
});
simpleColour = new JRadioButton(
MessageManager.getString("label.simple_colour"));
simpleColour.setPreferredSize(new Dimension(RADIO_WIDTH, 20));
+ simpleColour.setOpaque(false);
simpleColour.addItemListener(new ItemListener()
{
@Override
{
if (simpleColour.isSelected())
{
- showColourChooser(singleColour, "label.select_colour");
+ String ttl = MessageManager.formatMessage("label.select_colour_for", featureType);
+ showColourChooser(singleColour, ttl);
}
}
});
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
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);
}
/**
* save the colour, and repaint stuff
*/
fr.setColour(featureType, acg);
- ap.paintAlignment(updateStructsAndOverview, updateStructsAndOverview);
+ refreshDisplay(updateStructsAndOverview);
- updateColoursTab();
+ updateColoursPanel();
}
/**
}
float minValue = min;
float maxValue = max;
- final int thresholdOption = threshold.getSelectedIndex();
+ int thresholdOption = threshold.getSelectedIndex();
if (thresholdIsMin.isSelected()
&& thresholdOption == ABOVE_THRESHOLD_OPTION)
{
{
fr.setColour(featureType, originalColour);
fr.setFeatureFilter(featureType, originalFilter);
- ap.paintAlignment(true, true);
+ refreshDisplay(true);
}
/**
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;
}
/**
+ * 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,
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)
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
* 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
{
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);
+ }
}
/*
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
* @param condCombo
* @param patternField
*/
- private void populateConditions(String attName, Condition cond,
+ void populateConditions(String attName, Condition cond,
JComboBox<Condition> condCombo, JTextField patternField)
{
Datatype type = FeatureAttributes.getInstance().getDatatype(featureType,
* (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();
+ updateFiltersPanel();
+ }
+
+ /**
+ * 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);
+ }
}
}