package org.signalml.app.view.common.components.presets; import static org.signalml.app.util.i18n.SvarogI18n._; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.io.IOException; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.border.CompoundBorder; import javax.swing.border.EmptyBorder; import javax.swing.border.TitledBorder; import javax.swing.event.DocumentEvent; import org.signalml.app.SvarogApplication; import org.signalml.app.config.ApplicationConfiguration; import org.signalml.app.config.preset.Preset; import org.signalml.app.config.preset.PresetComboBoxModel; import org.signalml.app.config.preset.PresetManager; import org.signalml.app.config.preset.PresetManagerEvent; import org.signalml.app.config.preset.PresetManagerListener; import org.signalml.app.util.IconUtils; import org.signalml.app.view.common.components.AnyChangeDocumentAdapter; import org.signalml.app.view.common.components.panels.AbstractPanel; import org.signalml.app.view.common.dialogs.AbstractDialog; import org.signalml.app.view.common.dialogs.AbstractPresetDialog; import org.signalml.app.view.common.dialogs.OptionPane; import org.signalml.app.view.common.dialogs.errors.Dialogs; import org.signalml.plugin.export.SignalMLException; import org.signalml.plugin.export.view.FileChooser; import org.signalml.util.Util; /** * This panel contains all controls that are used to load and * save presets. It is used by the AbstractPresetDialog and * AbstractPresetPanel. * * @author Piotr Szachewicz */ public class ComplexPresetControlsPanel extends AbstractPanel { static final long serialVersionUID = 1L; /** * The dialog/panel which is controlled by this preset control panel * (e.g. the presets selected in this PresetControlsPanel affects * the presetPanel). */ private PresetableView presetPanel; /** * the {@link PresetManager manager} of {@link Preset presets} */ protected PresetManager presetManager; /** * the {@link FileChooser file chooser} */ protected FileChooser fileChooser; /** * the model for {@link #presetComboBox} */ private PresetComboBoxModel presetComboBoxModel; /** * the combo box which allows to select the {@link Preset preset} */ private JComboBox presetComboBox; /** * the dialog that allows to select the {@link #getPresetComboBox preset} * and specify the name for it */ private ChoosePresetDialog choosePresetDialog; /** * @see LoadDefaultPresetAction */ private Action loadDefaultPresetAction; /** * @see SaveDefaultPresetAction */ private Action saveDefaultPresetAction; /** * @see RemoveDefaultPresetAction */ private Action removeDefaultPresetAction; /** * @see SavePresetAction */ private Action savePresetAction; /** * @see LoadPresetAction */ private Action loadPresetAction; /** * @see RemovePresetAction */ private Action removePresetAction; /** * @see SaveFileAction */ private Action saveFileAction; /** * @see LoadFileAction */ private Action loadFileAction; /** * the button for {@link #loadDefaultPresetAction} */ private JButton loadDefaultPresetButton; /** * the button for {@link #saveDefaultPresetAction} */ private JButton saveDefaultPresetButton; /** * the button for {@link #removeDefaultPresetAction} */ private JButton removeDefaultPresetButton; /** * the button for {@link #savePresetAction} */ private JButton savePresetButton; /** * the button for {@link #removePresetAction} */ private JButton removePresetButton; /** * the button for {@link #saveFileAction} */ private JButton saveFileButton; /** * the button for {@link #loadFileAction} */ private JButton loadFileButton; private boolean showLoadSaveRemoveDefaultPresetButton; /** * Constructor. Sets message source and the {@link PresetManager preset * manager}. * @param presetManager the preset manager to set */ public ComplexPresetControlsPanel(PresetableView presetPanel, PresetManager presetManager) { this(presetPanel, presetManager, false); } public ComplexPresetControlsPanel(PresetableView presetPanel, PresetManager presetManager, boolean showLoadSaveRemoveDefaultPresetButton) { super(); assert presetPanel != null; assert presetManager != null; this.presetPanel = presetPanel; this.presetManager = presetManager; this.showLoadSaveRemoveDefaultPresetButton = showLoadSaveRemoveDefaultPresetButton; createInterface(); } protected void createInterface() { presetManager.addPresetManagerListener(new PresetManagerChangeListener()); setLayout(new BoxLayout(this, BoxLayout.X_AXIS)); setTitledBorder(_("Presets")); loadDefaultPresetAction = new LoadDefaultPresetAction(); saveDefaultPresetAction = new SaveDefaultPresetAction(); removeDefaultPresetAction = new RemoveDefaultPresetAction(); savePresetAction = new SavePresetAction(); loadPresetAction = new LoadPresetAction(); removePresetAction = new RemovePresetAction(); saveFileAction = new SaveFileAction(); loadFileAction = new LoadFileAction(); savePresetButton = new JButton(savePresetAction); removePresetButton = new JButton(removePresetAction); saveFileButton = new JButton(saveFileAction); loadFileButton = new JButton(loadFileAction); add(getPresetComboBox()); add(Box.createHorizontalStrut(3)); add(savePresetButton); add(Box.createHorizontalStrut(3)); add(removePresetButton); add(Box.createHorizontalStrut(6)); add(Box.createHorizontalGlue()); if (getShowLoadSaveRemoveDefaultPresetButton()) { loadDefaultPresetButton = new JButton(loadDefaultPresetAction); add(loadDefaultPresetButton); add(Box.createHorizontalStrut(3)); saveDefaultPresetButton = new JButton(saveDefaultPresetAction); add(saveDefaultPresetButton); add(Box.createHorizontalStrut(3)); removeDefaultPresetButton = new JButton(removeDefaultPresetAction); add(removeDefaultPresetButton); add(Box.createHorizontalStrut(3)); add(Box.createHorizontalStrut(3)); add(Box.createHorizontalGlue()); } add(loadFileButton); add(Box.createHorizontalStrut(3)); add(saveFileButton); setEnableds(); } /** * Returns if this dialog knows if there are any changes in it (and * therefore supports {@link #isChanged()}). * @return {@code true} if this dialog knows if there are any changes in * it, {@code false} otherwise */ protected boolean isTrackingChanges() { return false; } /** * Returns if this dialog should show the button to load the default * {@link Preset preset}. * @return {@code true} if this dialog should show the button to load the * default preset, {@code false} otherwise */ protected boolean getShowLoadSaveRemoveDefaultPresetButton() { return showLoadSaveRemoveDefaultPresetButton; } /** * Creates the combo box which allows to select the {@link Preset preset}. * @return created combo box */ protected JComboBox getPresetComboBox() { if (presetComboBox == null) { presetComboBoxModel = new PresetComboBoxModel(_("<< select to load preset >>"), presetManager); presetComboBox = new JComboBox(presetComboBoxModel); presetComboBox.setPreferredSize(new Dimension(200,20)); presetComboBox.addActionListener(loadPresetAction); resetPresetComboBoxSelection(); } return presetComboBox; } public void resetPresetComboBoxSelection() { getPresetComboBox().setSelectedIndex(0); } /** * Returns the {@link ChoosePresetDialog}. * @return the ChoosePresetDialog */ protected ChoosePresetDialog getChoosePresetDialog() { if (choosePresetDialog == null) { choosePresetDialog = new ChoosePresetDialog(); } return choosePresetDialog; } /** * Returns the {@link PresetManager preset manager}. * @return the preset manager */ public PresetManager getPresetManager() { return presetManager; } /** * Returns the {@link FileChooser file chooser}. * @return the file chooser */ public FileChooser getFileChooser() { return fileChooser; } /** * Sets the {@link FileChooser file chooser}. * @param fileChooser the file chooser to set */ public void setFileChooser(FileChooser fileChooser) { this.fileChooser = fileChooser; } /** * Returns the {@link ApplicationConfiguration configuration} of Svarog. * @return the configuration of Svarog */ public ApplicationConfiguration getApplicationConfig() { return SvarogApplication.getApplicationConfiguration(); } /** * (Creates and) returns the current {@link Preset preset}. * Must be specified in the implementing class. * @return the current preset * @throws SignalMLException TODO never thrown in implementations (???) */ public Preset getPresetFromMainPanel() throws SignalMLException { return presetPanel.getPreset(); } /** * Sets the given preset as the current {@link Preset preset}. * Fills all necessary fields of the dialog with the data from this preset. * Must be specified in the implementing class. * @param preset the preset to use as the new current preset. * @throws SignalMLException TODO never thrown in implementations */ private void setPresetToMainPanel(Preset preset) throws SignalMLException { if (presetPanel.isPresetCompatible(preset)) presetPanel.setPreset(preset); else resetPresetComboBoxSelection(); } protected void resetPanel() { getPresetComboBox().setSelectedIndex(0); getPresetComboBox().repaint(); setEnableds(); } /** * Sets if buttons should be enabled: * <ul> * <li>removePresetAction - if there is at least one {@link Preset preset} * </li> * <li>loadDefaultPresetAction & removeDefaultPresetAction - * if the default preset exists</li> * </ul> */ protected void setEnableds() { boolean hasDefault = (presetManager.getDefaultPreset() != null); boolean hasPresets = (presetManager.getPresetCount() > 0); getPresetComboBox().setEnabled(hasPresets); removePresetAction.setEnabled(hasPresets); loadDefaultPresetAction.setEnabled(hasDefault); removeDefaultPresetAction.setEnabled(hasDefault); } /** * Listens on changes in the {@link PresetManager preset manager} and * {@link AbstractPresetDialog#setEnabled(boolean) updates} the states of * buttons. */ protected class PresetManagerChangeListener implements PresetManagerListener { /** * {@link AbstractPresetDialog#setEnabled(boolean) Updates} the states * of buttons */ @Override public void defaultPresetChanged(PresetManagerEvent ev) { setEnableds(); } /** * {@link AbstractPresetDialog#setEnabled(boolean) Updates} the states * of buttons */ @Override public void presetAdded(PresetManagerEvent ev) { setEnableds(); } /** * {@link AbstractPresetDialog#setEnabled(boolean) Updates} the states * of buttons */ @Override public void presetRemoved(PresetManagerEvent ev) { setEnableds(); } /** * Does nothing. */ @Override public void presetReplaced(PresetManagerEvent ev) { // ignored } } /** * Action that sets the {@link AbstractPresetDialog#getPreset() current} * {@link Preset preset} as the * {@link PresetManager#setDefaultPreset(Preset) default} one. */ protected class SaveDefaultPresetAction extends AbstractAction { private static final long serialVersionUID = 1L; /** * Constructor. Sets the icon and the tool-tip text for this action. */ public SaveDefaultPresetAction() { super(); putValue(AbstractAction.SMALL_ICON, IconUtils.loadClassPathIcon("org/signalml/app/icon/default_preset_save.png")); putValue(AbstractAction.SHORT_DESCRIPTION,_("Make default")); } /** * Called when this action is performed: * <ul> * <li>{@link AbstractPresetDialog#getPreset() gets} the current * {@link Preset preset} from the dialog,</li> * <li>if the default preset already exists asks the user if it should * be replaced,</li> * <li>{@link PresetManager#setDefaultPreset(Preset) sets} the preset * as the default one.</li> * </ul> */ @Override public void actionPerformed(ActionEvent ev) { Preset preset; try { preset = getPresetFromMainPanel(); } catch (SignalMLException ex) { logger.error("Failed to get preset", ex); Dialogs.showExceptionDialog(ComplexPresetControlsPanel.this, ex); return; } if (preset == null) { return; } if (!presetManager.getPresetClass().isAssignableFrom(preset.getClass())) { throw new ClassCastException("Bad preset class"); } Preset existingPreset = presetManager.getDefaultPreset(); if (existingPreset != null) { final String msg = _("The default preset will be permanently overwritten. Are you sure?"); if (Dialogs.showWarningYesNoDialog(msg) == Dialogs.DIALOG_OPTIONS.NO) return; } presetManager.setDefaultPreset(preset); if (getApplicationConfig().isSaveConfigOnEveryChange()) { try { presetManager.writeToPersistence(null); } catch (IOException ex) { logger.error("Failed to save preset configuration", ex); } } } } /** * Action that replaces the current {@link Preset preset} in the dialog * with the {@link PresetManager#getDefaultPreset()} default preset * (fills the dialog using the default preset). */ protected class LoadDefaultPresetAction extends AbstractAction { private static final long serialVersionUID = 1L; /** * Constructor. Sets the icon and the tool-tip text for this action. */ public LoadDefaultPresetAction() { super(); putValue(AbstractAction.SMALL_ICON, IconUtils.loadClassPathIcon("org/signalml/app/icon/default_preset_load.png")); putValue(AbstractAction.SHORT_DESCRIPTION,_("Load default")); } /** * Called when this action is performed: * <ul> * <li>{@link PresetManager#getDefaultPreset() gets} the default * {@link Preset preset},</li> * <li>if there were changes in the dialog or dialog doesn't know if * there were, shows the warning to the user that the current preset * will be overridden and allows him to cancel the operation,</li> * <li>{@link AbstractPresetDialog#setPreset(Preset) fills} the dialog * from the preset.</li> * </ul> */ @Override public void actionPerformed(ActionEvent ev) { Preset preset = presetManager.getDefaultPreset(); if (preset == null) { return; } try { setPresetToMainPanel(preset); } catch (SignalMLException ex) { logger.error("Failed to set preset", ex); Dialogs.showExceptionDialog(ComplexPresetControlsPanel.this, ex); return; } } } /** * Action that sets that there is no default {@link Preset preset}. */ protected class RemoveDefaultPresetAction extends AbstractAction { private static final long serialVersionUID = 1L; /** * Constructor. Sets the icon and the tool-tip text for this action. */ public RemoveDefaultPresetAction() { super(); putValue(AbstractAction.SMALL_ICON, IconUtils.loadClassPathIcon("org/signalml/app/icon/default_preset_remove.png")); putValue(AbstractAction.SHORT_DESCRIPTION,_("Remove default")); } /** * Called when this action is performed: * <ul> * <li>if there is no default {@link Preset preset} does nothing,</li> * <li>displays the warning to the user,</li> * <li>if user accepted the warning sets that there is no active * preset.</li> * </ul> */ @Override public void actionPerformed(ActionEvent ev) { Preset preset = presetManager.getDefaultPreset(); if (preset == null) { return; } presetManager.setDefaultPreset(null); if (getApplicationConfig().isSaveConfigOnEveryChange()) { try { presetManager.writeToPersistence(null); } catch (IOException ex) { logger.error("Failed to save preset configuration", ex); } } } } /** * Action that saves the {@link AbstractPresetDialog#getPreset() current * preset} to the list of presets. */ protected class SavePresetAction extends AbstractAction { private static final long serialVersionUID = 1L; /** * Constructor. Sets the icon and the tool-tip text for this action. */ public SavePresetAction() { super(); putValue(AbstractAction.SMALL_ICON, IconUtils.loadClassPathIcon("org/signalml/app/icon/preset_save.png")); putValue(AbstractAction.SHORT_DESCRIPTION,_("Save")); } /** * Called when this action is performed: * <ul> * <li>{@link AbstractPresetDialog#getPreset() gets} the current * {@link Preset preset} from the dialog,</li> * <li>{@link ChoosePresetDialog#getName(String, boolean) gets} the * name for this preset,</li> * <li>if the preset of such name exists asks if it should be replaced, * </li> * <li>saves the preset to the {@link PresetManager}.</li> * </ul> */ @Override public void actionPerformed(ActionEvent ev) { Preset preset; try { preset = getPresetFromMainPanel(); } catch (SignalMLException ex) { logger.error("Failed to get preset", ex); Dialogs.showExceptionDialog(ComplexPresetControlsPanel.this, ex); return; } if (preset == null) { return; } if (!presetManager.getPresetClass().isAssignableFrom(preset.getClass())) { throw new ClassCastException("Bad preset class"); } String newName = getChoosePresetDialog().getName(preset.getName(), true); if (newName == null) { return; } Preset existingPreset = presetManager.getPresetByName(newName); if (existingPreset != null) { final String msg = _("Preset already exists, do you really want to overwrite this preset?"); if (Dialogs.showWarningYesNoDialog(msg) == Dialogs.DIALOG_OPTIONS.NO) { return; } } preset.setName(newName); presetManager.setPreset(preset); presetComboBoxModel.setSelectedItem(preset); if (getApplicationConfig().isSaveConfigOnEveryChange()) { try { presetManager.writeToPersistence(null); } catch (IOException ex) { logger.error("Failed to save preset configuration", ex); } } } } /** * Action that {@link AbstractPresetDialog#setPreset(Preset) sets} * the selected {@link Preset preset} as active. */ protected class LoadPresetAction extends AbstractAction { private static final long serialVersionUID = 1L; /** * Constructor. Sets the icon and the tool-tip text for this action. */ public LoadPresetAction() { super(); putValue(AbstractAction.SMALL_ICON, IconUtils.loadClassPathIcon("org/signalml/app/icon/preset_load.png")); putValue(AbstractAction.SHORT_DESCRIPTION,_("Load")); } /** * Called when the action is performed: * <ul> * <li>gets the selected {@link Preset preset} or if there is no this * functions ends, * </li> * <li>if there were changes in the dialog or dialog doesn't know if * there were, shows the warning to the user that the current preset * will be overridden and allows him to cancel the operation,</li> * <li>{@link AbstractPresetDialog#setPreset(Preset) sets} this preset * as the active one (fills the dialog with the data from it).</li> * </ul> */ @Override public void actionPerformed(ActionEvent ev) { int index = getPresetComboBox().getSelectedIndex(); if (index <= 0) { return; } Preset preset = presetManager.getPresetAt(index-1); getPresetComboBox().repaint(); if (preset == null) { return; } try { setPresetToMainPanel(preset); } catch (SignalMLException ex) { logger.error("Failed to set preset", ex); Dialogs.showExceptionDialog(ComplexPresetControlsPanel.this, ex); return; } } } /** * Action that removes the selected preset. * If there is no selected preset does nothing. * If there is warns the user before the removal. */ protected class RemovePresetAction extends AbstractAction { private static final long serialVersionUID = 1L; /** * Constructor. Sets the icon and the tool-tip text for this action. */ public RemovePresetAction() { super(); putValue(AbstractAction.SMALL_ICON, IconUtils.loadClassPathIcon("org/signalml/app/icon/preset_remove.png")); putValue(AbstractAction.SHORT_DESCRIPTION,_("Remove")); } /** * Called when the action is performed: * <ul> * <li>gets the selected {@link Preset preset} or if there is no this * functions ends, * </li> * <li>warns the user and if the user cancels operation this function * ends,</li> * <li>removes the selected preset.</li> * </ul> */ @Override public void actionPerformed(ActionEvent ev) { String name = getChoosePresetDialog().getName(null, false); if (name == null) { return; } Preset preset = presetManager.getPresetByName(name); if (preset == null) { return; } presetManager.removePresetByName(name); if (getApplicationConfig().isSaveConfigOnEveryChange()) { try { presetManager.writeToPersistence(null); } catch (IOException ex) { logger.error("Failed to save preset configuration", ex); } } } } /** * Action of saving the {@link Preset preset} to the file. * {@link AbstractPresetDialog#getPreset() Obtains} the preset and saves it * to the file selected by user. */ protected class SaveFileAction extends AbstractAction { private static final long serialVersionUID = 1L; /** * Constructor. Sets the icon and the tool-tip text for this action. */ public SaveFileAction() { super(); putValue(AbstractAction.SMALL_ICON, IconUtils.loadClassPathIcon("org/signalml/app/icon/script_save.png")); putValue(AbstractAction.SHORT_DESCRIPTION,_("Export preset to file...")); } /** * Called when the action is performed: * <ul> * <li>{@link AbstractPresetDialog#getPreset() Obtains} the * {@link Preset preset} from dialog,</li> * <li>asks the user to select the file to which the preset should be * saved</li> * <li>{@link PresetManager#writeToFile(File, Preset) saves} the preset * to the selected file.</li> * </ul> */ @Override public void actionPerformed(ActionEvent ev) { Preset preset; try { preset = getPresetFromMainPanel(); } catch (SignalMLException ex) { logger.error("Failed to get preset", ex); Dialogs.showExceptionDialog(ComplexPresetControlsPanel.this, ex); return; } if (preset == null) { return; } if (!presetManager.getPresetClass().isAssignableFrom(preset.getClass())) { throw new ClassCastException("Bad preset class"); } boolean hasFile = false; File file = null; do { file = fileChooser.chooseSavePresetFile(ComplexPresetControlsPanel.this.getParentWindow()); if (file == null) { return; } hasFile = true; if (file.exists()) { int res = OptionPane.showFileAlreadyExists(ComplexPresetControlsPanel.this.getParentWindow()); if (res != OptionPane.OK_OPTION) { hasFile = false; } } } while (!hasFile); try { presetManager.writeToFile(file, preset); } catch (IOException ex) { logger.error("Exception when writing file", ex); Dialogs.showExceptionDialog(ComplexPresetControlsPanel.this.getParentWindow(), ex); return; } } } /** * The action of loading the {@link Preset preset} from file. * Asks the user to select the file and * {@link PresetManager#readFromFile(File) loads} the preset from file. */ protected class LoadFileAction extends AbstractAction { private static final long serialVersionUID = 1L; /** * Constructor. Sets the icon and the tool-tip text for this action. */ public LoadFileAction() { super(); putValue(AbstractAction.SMALL_ICON, IconUtils.loadClassPathIcon("org/signalml/app/icon/script_load.png")); putValue(AbstractAction.SHORT_DESCRIPTION,_("Import preset from file...")); } /** * Called when the button is clicked. * <ul> * <li>asks the user to select the file with {@link Preset preset},</li> * <li>{@link PresetManager#readFromFile(File) loads} the preset from * the selected file,</li> * <li>if there were changes in the dialog or dialog doesn't know if * there were, shows the warning to the user that the current preset * will be overridden and allows him to cancel the operation,</li> * <li>{@link AbstractPresetDialog#setPreset(Preset) sets} this preset * as the active one (fills the dialog with the data from it),</li> * <li>{@link ChoosePresetDialog#getName(String, boolean) gets} the * name for this preset,</li> * <li>if the preset of such name exists asks if it should be replaced, * </li> * <li>saves the preset to the {@link PresetManager}.</li> * </ul> */ @Override public void actionPerformed(ActionEvent ev) { File file = fileChooser.chooseLoadPresetFile(ComplexPresetControlsPanel.this.getParentWindow()); if (file == null) { return; } Preset preset; try { preset = presetManager.readFromFile(file); } catch (Exception ex) { logger.error("Exception when reading preset from file", ex); Dialogs.showError("There was a problem while loading the preset file - is it a correct file?"); return; } try { setPresetToMainPanel(preset); } catch (SignalMLException ex) { logger.error("Failed to set preset", ex); Dialogs.showExceptionDialog(ComplexPresetControlsPanel.this.getParentWindow(), ex); return; } String newName = getChoosePresetDialog().getName(preset.getName(), true); if (newName == null) { return; } Preset existingPreset = presetManager.getPresetByName(newName); if (existingPreset != null) { final String msg = _("Preset already exists, do you really want to overwrite this preset?"); if (Dialogs.showWarningYesNoDialog(msg) == Dialogs.DIALOG_OPTIONS.NO) { return; } } preset.setName(newName); presetManager.setPreset(preset); if (getApplicationConfig().isSaveConfigOnEveryChange()) { try { presetManager.writeToPersistence(null); } catch (IOException ex) { logger.error("Failed to save preset configuration", ex); } } } } /** * Dialog that allows to select the {@link #getPresetComboBox preset} * and specify the name for it. */ protected class ChoosePresetDialog extends AbstractDialog { private static final long serialVersionUID = 1L; /** * the model for a combo box that allows to select the preset */ private PresetComboBoxModel presetComboBoxModel; /** * the combo box that allows to select the preset */ protected JComboBox presetComboBox; /** * the text field to specify the name for the preset */ private JTextField nameTextField; protected boolean editable = true; /** * Constructor. Sets the message source from enclosing class and * uses the enclosing class as the parent window to this dialog. */ protected ChoosePresetDialog() { super(ComplexPresetControlsPanel.this.getParentWindow(), true); } /** * Returns if the text field with the name of the preset should be * editable. * @return {@code true} if the text field with the name of the * preset should be editable, {@code false} otherwise */ public boolean isEditable() { return editable; } /** * Sets if the text field with the name of the preset should be * editable. * @param editable {@code true} if the text field with the name of the * preset should be editable, {@code false} otherwise */ public void setEditable(boolean editable) { if (this.editable != editable) { this.editable = editable; getNameTextField().setEditable(editable); } } @Override public void fillDialogFromModel(Object model) { // do nothing } @Override public void fillModelFromDialog(Object model) { // do nothing } @Override protected void initialize() { setTitle(_("Select preset")); super.initialize(); } /** * Adds the panel with 3 elements: * <ul> * <li>icon with a question mark,</li> * <li>{@link #getPresetComboBox() combo box} to select the preset,</li> * <li>{@link #getNameTextField() text field} with the name of the * preset (may be editable or not).</li> * </ul> */ @Override public JComponent createInterface() { JPanel interfacePanel = new JPanel(new BorderLayout()); interfacePanel.setBorder(new CompoundBorder( new TitledBorder(_("Select preset name")), new EmptyBorder(3,3,3,3) )); JPanel inputPanel = new JPanel(); inputPanel.setBorder(new EmptyBorder(0,8,0,0)); inputPanel.setLayout(new BoxLayout(inputPanel, BoxLayout.Y_AXIS)); inputPanel.add(getPresetComboBox()); inputPanel.add(Box.createVerticalStrut(10)); inputPanel.add(getNameTextField()); JLabel iconLabel = new JLabel(IconUtils.getQuestionIcon()); iconLabel.setVerticalAlignment(JLabel.TOP); interfacePanel.add(iconLabel, BorderLayout.WEST); interfacePanel.add(inputPanel, BorderLayout.CENTER); return interfacePanel; } /** * Returns the {@link PresetComboBoxModel model} for a combo box * to select presets. * If the model doesn't exist it is created. * @return the model */ public PresetComboBoxModel getPresetComboBoxModel() { if (presetComboBoxModel == null) { presetComboBoxModel = new PresetComboBoxModel(_("<< select to choose preset >>"), presetManager); } return presetComboBoxModel; } /** * If the preset combo box already exists it is simply returned. * If it doesn't, it is created. * Created combo box contains the listener, which sets the * {@link #getNameTextField() name field} depending on the selected * preset. * @return the preset combo box */ public JComboBox getPresetComboBox() { if (presetComboBox == null) { ; presetComboBox = new JComboBox(getPresetComboBoxModel()); presetComboBox.setSelectedIndex(0); presetComboBox.setPreferredSize(new Dimension(200,25)); presetComboBox.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { int index = presetComboBox.getSelectedIndex(); if (index <= 0) { return; } Preset p = presetManager.getPresetAt(index-1); if (p != null) { JTextField nameTextField = getNameTextField(); nameTextField.setText(p.getName()); if (editable) { nameTextField.selectAll(); nameTextField.requestFocusInWindow(); } } presetComboBox.setSelectedIndex(0); presetComboBox.repaint(); } }); } return presetComboBox; } /** * Returns the text field with the name of the preset. * If the field doesn't exist it is created. * If this name contains at least one character the OK button is * activated. * @return the text field with the name of the preset. */ public JTextField getNameTextField() { if (nameTextField == null) { nameTextField = new JTextField(); nameTextField.setPreferredSize(new Dimension(200,25)); nameTextField.getDocument().addDocumentListener(new AnyChangeDocumentAdapter() { @Override public void anyUpdate(DocumentEvent e) { getOkAction().setEnabled(e.getDocument().getLength() > 0); } }); } return nameTextField; } /** * Shows this dialog and returns the entered name. * @param initialName the name that (if it is not empty) will be * set as the value of {@link #getNameTextField() name text field} * @param editable {@code true} if the name text field should be * editable, {@code false} otherwise * @return the specified name or null if there is no name (or the name * is empty) */ public String getName(String initialName, boolean editable) { initializeNow(); setEditable(editable); JTextField nameTextField = getNameTextField(); if (initialName != null && !initialName.isEmpty()) { nameTextField.setText(initialName); getOkAction().setEnabled(true); } else { nameTextField.setText(""); getOkAction().setEnabled(false); } if (editable) { nameTextField.selectAll(); nameTextField.requestFocusInWindow(); } boolean ok = showDialog(null, true); if (!ok) { return null; } String name = nameTextField.getText(); name = Util.trimString(name); if (name == null || name.isEmpty()) { return null; } return name; } @Override public boolean supportsModelClass(Class<?> clazz) { return (clazz == null); } } }