JPanel groupPanel;
- JSlider transparency = new JSlider();
+ JSlider transparency= new JSlider();
+
+ private JCheckBox showComplementOnTop;
+
+ private JCheckBox showComplement;
/*
* when true, constructor is still executing - so ignore UI events
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.setMaximum(100 - originalTransparencyAsPercent);
-
- originalFilters = new HashMap<>(fr.getFeatureFilters()); // shallow copy
- originalViewStyle = new ViewStyle(af.viewport.getViewStyle());
+ storeOriginalSettings();
try
{
{
frame = new JInternalFrame();
frame.setContentPane(this);
- if (Platform.isAMac())
+ 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)
{
- Desktop.addInternalFrame(frame,
- MessageManager.getString("label.sequence_feature_settings"),
- 600, 480);
+ if (Platform.isAMac())
+ {
+ Desktop.addInternalFrame(frame, title, 600, 480);
+ }
+ else
+ {
+ Desktop.addInternalFrame(frame, title, 600, 450);
+ }
}
else
{
- Desktop.addInternalFrame(frame,
- MessageManager.getString("label.sequence_feature_settings"),
- 600, 450);
+ Desktop.addInternalFrame(frame, title,
+ false, bounds.width, bounds.height);
+ frame.setBounds(bounds);
+ frame.setVisible(true);
}
frame.setMinimumSize(new Dimension(MIN_WIDTH, MIN_HEIGHT));
inConstruction = false;
}
- PropertyChangeListener change;
+ /**
+ * 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());
+ }
@Override
public AlignViewControllerGuiI getAlignframe()
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);
men.show(table, x, 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
synchronized public void discoverAllFeatureData()
{
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
{
if (frame != null)
{
+ af.setFeatureSettingsGeometry(frame.getBounds());
frame.setClosed(true);
}
else
{
SplitContainerI sc = af.getSplitViewContainer();
- sc.closeFeatureSettings(this);
+ sc.closeFeatureSettings(this, closeContainingFrame);
af.featureSettings = null;
}
} catch (Exception exe)
{
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);
- af.getViewport().setViewStyle(originalViewStyle);
- 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();
+ }
}
});
? MessageManager.getString("label.protein")
.toLowerCase()
: "CDS");
- JCheckBox showComplement = new JCheckBox(text);
- showComplement.setSelected(af.getViewport().isShowComplementFeatures());
+ showComplement = new JCheckBox(text);
showComplement.addActionListener(new ActionListener()
{
@Override
}
});
- JCheckBox showComplementOnTop = new JCheckBox(
+ showComplementOnTop = new JCheckBox(
MessageManager.getString("label.on_top"));
- showComplementOnTop
- .setSelected(af.getViewport().isShowComplementFeaturesOnTop());
showComplementOnTop.addActionListener(new ActionListener()
{
@Override
refreshDisplay();
}
});
- // JButton viewComplementSettings = new JButton(MessageManager
- // .formatMessage("label.show_linked_feature_settings",
- // nucleotide
- // ? MessageManager.getString("label.protein")
- // .toLowerCase()
- // : "CDS"));
- // viewComplementSettings.addActionListener(new ActionListener()
- // {
- //
- // @Override
- // public void actionPerformed(ActionEvent e)
- // {
- // AlignViewControllerGuiI complAf = af.getSplitViewContainer()
- // .getComplementAlignFrame(af);
- // FeatureSettings complFeatureSettings = (FeatureSettings) complAf
- // .getFeatureSettingsUI();
- // if (complFeatureSettings != null)
- // {
- // complFeatureSettings.frame.setVisible(true);
- // try
- // {
- // complFeatureSettings.frame.setSelected(true);
- // return;
- // } catch (Exception q)
- // {
- // }
- // }
- // {
- // complAf.showFeatureSettingsUI();
- // }
- // }
- // });
+
+ updateComplementButtons();
+
JPanel lowerPanel = new JPanel(new GridLayout(1, 2));
bigPanel.add(lowerPanel, BorderLayout.SOUTH);
transbuttons.add(sortByDens);
transbuttons.add(help);
- boolean hasComplement = af.getViewport().getCodingComplement() != null;
JPanel transPanelLeft = new JPanel(
new GridLayout(hasComplement ? 4 : 2, 1));
transPanelLeft.add(new JLabel(" Colour transparency" + ":"));
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