diff --git a/src/main/java/net/sf/jabref/external/ExternalFileTypeEditor.java b/src/main/java/net/sf/jabref/external/ExternalFileTypeEditor.java index 374b1778bca8..8f2ca3deff2a 100644 --- a/src/main/java/net/sf/jabref/external/ExternalFileTypeEditor.java +++ b/src/main/java/net/sf/jabref/external/ExternalFileTypeEditor.java @@ -21,6 +21,7 @@ import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; + import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -58,6 +59,7 @@ * Editor for external file types. */ public class ExternalFileTypeEditor extends JDialog { + private JFrame frame; private JDialog dialog; private List fileTypes; @@ -111,6 +113,7 @@ private void init() { dispose(); }); Action cancelAction = new AbstractAction() { + @Override public void actionPerformed(ActionEvent e) { dispose(); @@ -134,9 +137,10 @@ public void actionPerformed(ActionEvent e) { //} }); - add.addActionListener(e -> { + add.addActionListener(e -> { // Generate a new file type: - ExternalFileType type = new ExternalFileType("", "", "", "", "new", IconTheme.JabRefIcon.FILE.getSmallIcon()); + ExternalFileType type = new ExternalFileType("", "", "", "", "new", + IconTheme.JabRefIcon.FILE.getSmallIcon()); // Show the file type editor: getEditor(type).setVisible(true); if (entryEditor.okPressed()) { @@ -246,6 +250,7 @@ public static AbstractAction getAction(JDialog dialog) { return new EditExternalFileTypesAction(dialog); } + class EditListener implements ActionListener { @Override @@ -276,6 +281,7 @@ public Component getTableCellRendererComponent(JTable tab, Object value, boolean } private class FileTypeTableModel extends AbstractTableModel { + @Override public int getColumnCount() { return 5; @@ -354,6 +360,7 @@ public void mouseReleased(MouseEvent e) { } public static class EditExternalFileTypesAction extends MnemonicAwareAction { + private JabRefFrame frame; private JDialog dialog; private ExternalFileTypeEditor editor; diff --git a/src/main/java/net/sf/jabref/gui/FileExtensions.java b/src/main/java/net/sf/jabref/gui/FileExtensions.java index 3b69b5fbff7b..923d3478d772 100644 --- a/src/main/java/net/sf/jabref/gui/FileExtensions.java +++ b/src/main/java/net/sf/jabref/gui/FileExtensions.java @@ -5,12 +5,16 @@ public enum FileExtensions { //importatn: No dot before the extension BIBTEX_DB( "BibTeX Database", "bib"), + AUX( + "Aux file", "aux"), SILVER_PLATTERN( "SilverPlatter", "dat"), JSTYLE( "Style File", "jstyle"), LAYOUT( - "Custom Layout File", "layout"); + "Custom Layout File", "layout"), + XML( + "XML File", "xml"); private final String[] extension; private final String description; @@ -32,6 +36,6 @@ public String getDescription() { } public String getFirstExtensionWithDot() { - return "." + extension[0]; + return "." + extension[0].trim(); } } diff --git a/src/main/java/net/sf/jabref/gui/actions/BrowseAction.java b/src/main/java/net/sf/jabref/gui/actions/BrowseAction.java index 81105c966fa7..6d3267db7237 100644 --- a/src/main/java/net/sf/jabref/gui/actions/BrowseAction.java +++ b/src/main/java/net/sf/jabref/gui/actions/BrowseAction.java @@ -18,6 +18,7 @@ import java.awt.event.ActionEvent; import java.io.File; import java.util.Collections; +import java.util.EnumSet; import java.util.Set; import javax.swing.AbstractAction; @@ -48,18 +49,24 @@ public static BrowseAction buildForDir(JTextField tc) { } public static BrowseAction buildForFile(JTextField tc) { + return new BrowseAction(null, tc, false, Collections.emptySet()); } + public static BrowseAction buildForFile(JTextField tc, FileExtensions extensions) { - public static BrowseAction buildForFile(JTextField tc, Set extension) { - return new BrowseAction(null, tc, false, extension); + return new BrowseAction(null, tc, false, EnumSet.of(extensions)); } + public static BrowseAction buildForFile(JTextField tc, Set extensions) { + return new BrowseAction(null, tc, false, extensions); + } + /* public static BrowseAction buildForFile(JTextField tc, extension...) { + return new BrowseAction(null, tc, false, extension); + }*/ - private BrowseAction(JFrame frame, JTextField tc, boolean dirsOnly, - Set extensions) { + private BrowseAction(JFrame frame, JTextField tc, boolean dirsOnly, Set extensions) { super(Localization.lang("Browse")); this.frame = frame; this.dirsOnly = dirsOnly; diff --git a/src/main/java/net/sf/jabref/gui/auximport/FromAuxDialog.java b/src/main/java/net/sf/jabref/gui/auximport/FromAuxDialog.java index 809fbbf4c3ba..a00264be8bed 100644 --- a/src/main/java/net/sf/jabref/gui/auximport/FromAuxDialog.java +++ b/src/main/java/net/sf/jabref/gui/auximport/FromAuxDialog.java @@ -38,8 +38,6 @@ import java.awt.BorderLayout; import java.awt.event.ActionEvent; -import java.io.File; -import java.util.Collections; import javax.swing.AbstractAction; import javax.swing.ActionMap; @@ -49,7 +47,6 @@ import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JDialog; -import javax.swing.JFileChooser; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; @@ -60,8 +57,9 @@ import net.sf.jabref.Globals; import net.sf.jabref.gui.BasePanel; -import net.sf.jabref.gui.FileDialogs; +import net.sf.jabref.gui.FileExtensions; import net.sf.jabref.gui.JabRefFrame; +import net.sf.jabref.gui.actions.BrowseAction; import net.sf.jabref.gui.keyboard.KeyBinding; import net.sf.jabref.logic.auxparser.AuxParser; import net.sf.jabref.logic.auxparser.AuxParserResult; @@ -73,6 +71,7 @@ import com.jgoodies.forms.layout.FormLayout; public class FromAuxDialog extends JDialog { + private final JPanel statusPanel = new JPanel(); private final JPanel buttons = new JPanel(); private final JButton generateButton = new JButton(); @@ -95,8 +94,7 @@ public class FromAuxDialog extends JDialog { private final JabRefFrame parentFrame; - public FromAuxDialog(JabRefFrame frame, String title, boolean modal, - JTabbedPane viewedDBs) { + public FromAuxDialog(JabRefFrame frame, String title, boolean modal, JTabbedPane viewedDBs) { super(frame, title, modal); parentTabbedPane = viewedDBs; @@ -141,9 +139,11 @@ private void jbInit() { this.setTitle(Localization.lang("AUX file import")); JLabel desc = new JLabel("

" + Localization.lang("AUX file import") + "

" + Localization.lang("This feature generates a new database based on which entries " - + "are needed in an existing LaTeX document.") + "

" - + "

" + Localization.lang("You need to select one of your open databases from which to choose " - + "entries, as well as the AUX file produced by LaTeX when compiling your document.") + "

"); + + "are needed in an existing LaTeX document.") + + "

" + "

" + + Localization.lang("You need to select one of your open databases from which to choose " + + "entries, as well as the AUX file produced by LaTeX when compiling your document.") + + "

"); desc.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); panel1.add(desc, BorderLayout.NORTH); @@ -160,6 +160,7 @@ private void jbInit() { InputMap im = statusPanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); im.put(Globals.getKeyPrefs().getKey(KeyBinding.CLOSE_DIALOG), "close"); am.put("close", new AbstractAction() { + @Override public void actionPerformed(ActionEvent e) { dispose(); @@ -184,15 +185,15 @@ private void initPanels() { auxFileField = new JTextField("", 25); JButton browseAuxFileButton = new JButton(Localization.lang("Browse")); - browseAuxFileButton.addActionListener(new BrowseAction(auxFileField, parentFrame)); + browseAuxFileButton.addActionListener(BrowseAction.buildForFile(auxFileField, FileExtensions.AUX)); notFoundList = new JList<>(); JScrollPane listScrollPane = new JScrollPane(notFoundList); statusInfos = new JTextArea("", 5, 20); JScrollPane statusScrollPane = new JScrollPane(statusInfos); statusInfos.setEditable(false); - DefaultFormBuilder b = new DefaultFormBuilder(new FormLayout( - "left:pref, 4dlu, fill:pref:grow, 4dlu, left:pref", ""), buttons); + DefaultFormBuilder b = new DefaultFormBuilder( + new FormLayout("left:pref, 4dlu, fill:pref:grow, 4dlu, left:pref", ""), buttons); b.appendSeparator(Localization.lang("Options")); b.append(Localization.lang("Reference database") + ":"); b.append(dbChooser, 3); @@ -202,8 +203,8 @@ private void initPanels() { b.append(browseAuxFileButton); b.getPanel().setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - b = new DefaultFormBuilder(new FormLayout( - "fill:pref:grow, 4dlu, fill:pref:grow", "pref, pref, fill:pref:grow"), statusPanel); + b = new DefaultFormBuilder(new FormLayout("fill:pref:grow, 4dlu, fill:pref:grow", "pref, pref, fill:pref:grow"), + statusPanel); b.appendSeparator(Localization.lang("Result")); b.append(Localization.lang("Unknown BibTeX entries") + ":"); b.append(Localization.lang("Messages") + ":"); @@ -249,28 +250,4 @@ public BibDatabase getGenerateDB() { return auxParser.parse().getGeneratedBibDatabase(); } - /** - * Action used to produce a "Browse" button for one of the text fields. - */ - static class BrowseAction extends AbstractAction { - private final JTextField comp; - private final JabRefFrame frame; - - - public BrowseAction(JTextField tc, JabRefFrame frame) { - super(Localization.lang("Browse")); - this.frame = frame; - comp = tc; - } - - @Override - public void actionPerformed(ActionEvent e) { - String chosen = FileDialogs.getNewFile(frame, new File(comp.getText()), Collections.singletonList(".aux"), - JFileChooser.OPEN_DIALOG, false); - if (chosen != null) { - File newFile = new File(chosen); - comp.setText(newFile.getPath()); - } - } - } } diff --git a/src/main/java/net/sf/jabref/gui/exporter/CustomExportDialog.java b/src/main/java/net/sf/jabref/gui/exporter/CustomExportDialog.java index 9af2c407fb6a..15cf0b4ba890 100644 --- a/src/main/java/net/sf/jabref/gui/exporter/CustomExportDialog.java +++ b/src/main/java/net/sf/jabref/gui/exporter/CustomExportDialog.java @@ -21,9 +21,9 @@ import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; + import java.nio.file.Path; import java.nio.file.Paths; -import java.util.EnumSet; import javax.swing.AbstractAction; import javax.swing.ActionMap; @@ -104,7 +104,7 @@ public CustomExportDialog(final JabRefFrame parent) { cancel.addActionListener(e -> dispose()); JButton browse = new JButton(Localization.lang("Browse")); - browse.addActionListener(BrowseAction.buildForFile(layoutFile, EnumSet.of(FileExtensions.LAYOUT))); + browse.addActionListener(BrowseAction.buildForFile(layoutFile, FileExtensions.LAYOUT)); AbstractAction cancelAction = new AbstractAction() { diff --git a/src/main/java/net/sf/jabref/gui/journals/ManageJournalsPanel.java b/src/main/java/net/sf/jabref/gui/journals/ManageJournalsPanel.java index 928069bbd074..96d92770199f 100644 --- a/src/main/java/net/sf/jabref/gui/journals/ManageJournalsPanel.java +++ b/src/main/java/net/sf/jabref/gui/journals/ManageJournalsPanel.java @@ -22,6 +22,7 @@ import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; + import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; @@ -46,7 +47,6 @@ import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JDialog; -import javax.swing.JFileChooser; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; @@ -57,12 +57,15 @@ import javax.swing.table.AbstractTableModel; import net.sf.jabref.Globals; -import net.sf.jabref.gui.FileDialogs; + import net.sf.jabref.gui.IconTheme; import net.sf.jabref.gui.JabRefFrame; +import net.sf.jabref.gui.NewFileDialogs; +import net.sf.jabref.gui.actions.BrowseAction; import net.sf.jabref.gui.help.HelpAction; import net.sf.jabref.gui.keyboard.KeyBinding; import net.sf.jabref.gui.net.MonitoredURLDownload; + import net.sf.jabref.logic.help.HelpFile; import net.sf.jabref.logic.journals.Abbreviation; import net.sf.jabref.logic.journals.JournalAbbreviationLoader; @@ -186,40 +189,26 @@ public ManageJournalsPanel(final JabRefFrame frame) { journalEditPanel = builder2.getPanel(); viewBuiltin.addActionListener(e -> { - JTable table = new JTable(JournalAbbreviationsUtil - .getTableModel(Globals.journalAbbreviationLoader - .getRepository(JournalAbbreviationPreferences.fromPreferences(Globals.prefs)) - .getAbbreviations())); + JTable table = new JTable(JournalAbbreviationsUtil.getTableModel(Globals.journalAbbreviationLoader + .getRepository(JournalAbbreviationPreferences.fromPreferences(Globals.prefs)).getAbbreviations())); JScrollPane pane = new JScrollPane(table); JOptionPane.showMessageDialog(null, pane, Localization.lang("Journal list preview"), JOptionPane.INFORMATION_MESSAGE); }); browseNew.addActionListener(e -> { - String name; - if (!newNameTf.getText().isEmpty()) { - name = FileDialogs.getNewFile(frame, Paths.get(newNameTf.getText()).toFile(), Collections.emptyList(), JFileChooser.SAVE_DIALOG, - false); - } else { - name = FileDialogs.getNewFile(frame, null, Collections.emptyList(), JFileChooser.SAVE_DIALOG, false); - } + String name = new NewFileDialogs(frame, newNameTf.getText()).saveNewFile().toString(); - if (name != null) { + if (!name.isEmpty()) { newNameTf.setText(name); newFile.setSelected(true); } }); browseOld.addActionListener(e -> { - String name; - if (!personalFile.getText().isEmpty()) { - name = FileDialogs.getNewFile(frame, Paths.get(personalFile.getText()).toFile(), - Collections.emptyList(), JFileChooser.OPEN_DIALOG, false); - } else { - name = FileDialogs.getNewFile(frame, null, Collections.emptyList(), JFileChooser.OPEN_DIALOG, false); - } + String name = new NewFileDialogs(frame, personalFile.getText()).getSelectedFile().toString(); - if (name != null) { + if (!name.isEmpty()) { personalFile.setText(name); oldFile.setSelected(true); oldFile.setEnabled(true); @@ -420,15 +409,15 @@ public DownloadAction(JTextField tc) { public void actionPerformed(ActionEvent e) { String chosen; chosen = JOptionPane.showInputDialog(Localization.lang("Choose the URL to download."), ""); - if (chosen == null) { + if ((chosen == null) || comp.getText().isEmpty()) { return; } File toFile; try { - String toName = FileDialogs.getNewFile(frame, new File(System.getProperty("user.home")), - Collections.emptyList(), - JFileChooser.SAVE_DIALOG, false); - if (toName == null) { + + String toName = new NewFileDialogs(frame, System.getProperty("user.home")).saveNewFile().toString(); + + if (toName.isEmpty()) { return; } else { toFile = new File(toName); @@ -444,34 +433,6 @@ public void actionPerformed(ActionEvent e) { } } - class BrowseAction extends AbstractAction { - - private final JTextField comp; - private final boolean dir; - - - public BrowseAction(JTextField tc, boolean dir) { - super(Localization.lang("Browse")); - this.dir = dir; - comp = tc; - } - - @Override - public void actionPerformed(ActionEvent e) { - String chosen; - if (dir) { - chosen = FileDialogs.getNewDir(frame, new File(comp.getText()), Collections.emptyList(), - JFileChooser.OPEN_DIALOG, false); - } else { - chosen = FileDialogs.getNewFile(frame, new File(comp.getText()), Collections.emptyList(), - JFileChooser.OPEN_DIALOG, false); - } - if (chosen != null) { - comp.setText(Paths.get(chosen).toString()); - } - } - } - class AbbreviationsTableModel extends AbstractTableModel implements ActionListener { private final String[] names = new String[] {Localization.lang("Journal name"), @@ -577,7 +538,7 @@ public void actionPerformed(ActionEvent e) { } } - class ExternalFileEntry { + private class ExternalFileEntry { private JPanel pan; private final JTextField tf; @@ -599,8 +560,7 @@ public ExternalFileEntry(String filename) { private void setupPanel() { tf.setEditable(false); - BrowseAction browseA = new BrowseAction(tf, false); - browse.addActionListener(browseA); + browse.addActionListener(BrowseAction.buildForFile(tf)); DownloadAction da = new DownloadAction(tf); download.addActionListener(da); FormBuilder builder = FormBuilder.create().layout(new FormLayout( @@ -623,9 +583,10 @@ private void setupPanel() { JOptionPane.showMessageDialog(null, pane, Localization.lang("Journal list preview"), JOptionPane.INFORMATION_MESSAGE); } catch (FileNotFoundException ex) { + LOGGER.debug("File not found", ex); + JOptionPane.showMessageDialog(null, Localization.lang("File '%0' not found", tf.getText()), Localization.lang("Error"), JOptionPane.ERROR_MESSAGE); - LOGGER.debug("File not found", ex); } }); clear.addActionListener(e -> { diff --git a/src/main/java/net/sf/jabref/gui/openoffice/StyleSelectDialog.java b/src/main/java/net/sf/jabref/gui/openoffice/StyleSelectDialog.java index f352271d990e..d69b64627d71 100644 --- a/src/main/java/net/sf/jabref/gui/openoffice/StyleSelectDialog.java +++ b/src/main/java/net/sf/jabref/gui/openoffice/StyleSelectDialog.java @@ -23,7 +23,6 @@ import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.io.IOException; -import java.util.EnumSet; import java.util.Objects; import java.util.Optional; @@ -486,7 +485,7 @@ public AddFileDialog() { super(diag, Localization.lang("Add style file"), true); JButton browse = new JButton(Localization.lang("Browse")); - browse.addActionListener(BrowseAction.buildForFile(newFile, EnumSet.of(FileExtensions.JSTYLE))); + browse.addActionListener(BrowseAction.buildForFile(newFile, FileExtensions.JSTYLE)); // Build content panel FormBuilder builder = FormBuilder.create(); diff --git a/src/main/java/net/sf/jabref/gui/preftabs/PreferencesDialog.java b/src/main/java/net/sf/jabref/gui/preftabs/PreferencesDialog.java index 5d167a3b9a16..4b208e43f555 100644 --- a/src/main/java/net/sf/jabref/gui/preftabs/PreferencesDialog.java +++ b/src/main/java/net/sf/jabref/gui/preftabs/PreferencesDialog.java @@ -20,9 +20,7 @@ import java.awt.Component; import java.awt.GridLayout; import java.awt.event.ActionEvent; -import java.io.File; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.prefs.BackingStoreException; @@ -30,7 +28,6 @@ import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JDialog; -import javax.swing.JFileChooser; import javax.swing.JList; import javax.swing.JOptionPane; import javax.swing.JPanel; @@ -38,9 +35,11 @@ import net.sf.jabref.Globals; import net.sf.jabref.JabRefException; -import net.sf.jabref.gui.FileDialogs; + +import net.sf.jabref.gui.FileExtensions; import net.sf.jabref.gui.GUIGlobals; import net.sf.jabref.gui.JabRefFrame; +import net.sf.jabref.gui.NewFileDialogs; import net.sf.jabref.gui.keyboard.KeyBinder; import net.sf.jabref.gui.maintable.MainTable; import net.sf.jabref.logic.exporter.ExportFormats; @@ -132,7 +131,6 @@ public PreferencesDialog(JabRefFrame parent) { cardLayout.show(main, o); }); - JPanel buttons = new JPanel(); buttons.setLayout(new GridLayout(4, 1)); buttons.add(importPreferences, 0); @@ -166,38 +164,33 @@ public PreferencesDialog(JabRefFrame parent) { // Import and export actions: exportPreferences.setToolTipText(Localization.lang("Export preferences to file")); exportPreferences.addActionListener(e -> { - String filename = FileDialogs.getNewFile(frame, new File(System.getProperty("user.home")), - Collections.singletonList(".xml"), JFileChooser.SAVE_DIALOG, false); - if (filename == null) { - return; - } - File file = new File(filename); - if (!file.exists() || (JOptionPane.showConfirmDialog(PreferencesDialog.this, - Localization.lang("'%0' exists. Overwrite file?", file.getName()), - Localization.lang("Export preferences"), JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION)) { - try { - prefs.exportPreferences(filename); - } catch (JabRefException ex) { - LOGGER.warn(ex.getMessage(), ex); - JOptionPane.showMessageDialog(PreferencesDialog.this, ex.getLocalizedMessage(), - Localization.lang("Export preferences"), JOptionPane.ERROR_MESSAGE); - } + String filename = new NewFileDialogs(frame, System.getProperty("user.home")) + .withExtension(FileExtensions.XML).saveNewFile().toString(); + + try { + prefs.exportPreferences(filename); + } catch (JabRefException ex) { + LOGGER.warn(ex.getMessage(), ex); + JOptionPane.showMessageDialog(PreferencesDialog.this, ex.getLocalizedMessage(), + Localization.lang("Export preferences"), JOptionPane.ERROR_MESSAGE); } + }); importPreferences.setToolTipText(Localization.lang("Import preferences from file")); importPreferences.addActionListener(e -> { - String filename = FileDialogs.getNewFile(frame, new File(System.getProperty("user.home")), - Collections.singletonList(".xml"), JFileChooser.OPEN_DIALOG, false); - if (filename != null) { + + String fileName = new NewFileDialogs(frame, System.getProperty("user.home")) + .withExtension(FileExtensions.XML).getSelectedFile().toString(); + + if (!fileName.isEmpty()) { try { - prefs.importPreferences(filename); + prefs.importPreferences(fileName); updateAfterPreferenceChanges(); JOptionPane.showMessageDialog(PreferencesDialog.this, Localization.lang("You must restart JabRef for this to come into effect."), - Localization.lang("Import preferences"), - JOptionPane.WARNING_MESSAGE); + Localization.lang("Import preferences"), JOptionPane.WARNING_MESSAGE); } catch (JabRefException ex) { LOGGER.warn(ex.getMessage(), ex); JOptionPane.showMessageDialog(PreferencesDialog.this, ex.getLocalizedMessage(), @@ -207,8 +200,7 @@ public PreferencesDialog(JabRefFrame parent) { }); showPreferences.addActionListener( - e -> new PreferencesFilterDialog(new JabRefPreferencesFilter(Globals.prefs), frame) - .setVisible(true)); + e -> new PreferencesFilterDialog(new JabRefPreferencesFilter(Globals.prefs), frame).setVisible(true)); resetPreferences.addActionListener(e -> { if (JOptionPane.showConfirmDialog(PreferencesDialog.this, Localization.lang("Are you sure you want to reset all settings to default values?"), @@ -217,8 +209,7 @@ public PreferencesDialog(JabRefFrame parent) { prefs.clear(); JOptionPane.showMessageDialog(PreferencesDialog.this, Localization.lang("You must restart JabRef for this to come into effect."), - Localization.lang("Reset preferences"), - JOptionPane.WARNING_MESSAGE); + Localization.lang("Reset preferences"), JOptionPane.WARNING_MESSAGE); } catch (BackingStoreException ex) { LOGGER.warn(ex.getMessage(), ex); JOptionPane.showMessageDialog(PreferencesDialog.this, ex.getLocalizedMessage(), @@ -241,6 +232,7 @@ private void updateAfterPreferenceChanges() { Globals.prefs.updateEntryEditorTabList(); } + class OkAction extends AbstractAction { public OkAction() {