001package apps.gui3.tabbedpreferences;
002
003import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
004
005import java.awt.event.WindowEvent;
006
007import javax.swing.WindowConstants;
008
009import jmri.InstanceManager;
010import jmri.ShutDownManager;
011import jmri.swing.PreferencesPanel;
012import jmri.util.JmriJFrame;
013import jmri.util.swing.JmriJOptionPane;
014
015/**
016 * Support displaying {@link TabbedPreferences} in a window.
017 *<p>
018 * The {@link TabbedPreferences} object is requested from the InstanceManager, and
019 * if need-be created and initialized in the process of doing that.
020 *
021 * @author Kevin Dickerson Copyright 2010
022 * @author Bob Jacobsen Copyright 2019
023 */
024public class TabbedPreferencesFrame extends JmriJFrame {
025
026    @Override
027    public String getTitle() {
028        return getTabbedPreferences().getTitle();
029    }
030
031    public boolean isMultipleInstances() {
032        return true;
033    }
034
035    public TabbedPreferencesFrame() {
036        super();
037        add(getTabbedPreferences());
038        addHelpMenu("package.apps.TabbedPreferences", true); // NOI18N
039        setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
040        pack();
041    }
042
043    public void gotoPreferenceItem(String item, String sub) {
044        getTabbedPreferences().gotoPreferenceItem(item, sub);
045    }
046
047    @Override
048    @SuppressFBWarnings(value = "OVERRIDING_METHODS_MUST_INVOKE_SUPER",
049            justification = "This handles dirty processing locally")
050    public void windowClosing(WindowEvent e) {
051        ShutDownManager sdm = InstanceManager.getDefault(ShutDownManager.class);
052        if (!getTabbedPreferences().isPreferencesValid() && !sdm.isShuttingDown()) {
053            for (PreferencesPanel panel : getTabbedPreferences().getPreferencesPanels().values()) {
054                if (!panel.isPreferencesValid()) {
055                    switch (JmriJOptionPane.showConfirmDialog(this,
056                            Bundle.getMessage("InvalidPreferencesMessage", panel.getTabbedPreferencesTitle()),
057                            Bundle.getMessage("InvalidPreferencesTitle"),
058                            JmriJOptionPane.YES_NO_OPTION,
059                            JmriJOptionPane.ERROR_MESSAGE)) {
060                        case JmriJOptionPane.YES_OPTION:
061                            // abort window closing and return to broken preferences
062                            getTabbedPreferences().gotoPreferenceItem(panel.getPreferencesItem(), panel.getTabbedPreferencesTitle());
063                            return;
064                        default:
065                            // do nothing
066                            break;
067                    }
068                }
069            }
070        }
071        if (getTabbedPreferences().isDirty()) {
072            var buttons = JmriJOptionPane.YES_NO_CANCEL_OPTION;
073            if (sdm.isShuttingDown()) {
074                buttons = JmriJOptionPane.YES_NO_OPTION;
075            }
076            switch (JmriJOptionPane.showConfirmDialog(this,
077                    Bundle.getMessage("UnsavedChangesMessage", getTabbedPreferences().getTitle()), // NOI18N
078                    Bundle.getMessage("UnsavedChangesTitle"), // NOI18N
079                    buttons,
080                    JmriJOptionPane.QUESTION_MESSAGE)) {
081                case JmriJOptionPane.YES_OPTION:
082                    // save preferences
083                    getTabbedPreferences().savePressed(getTabbedPreferences().invokeSaveOptions());
084                    break;
085                case JmriJOptionPane.NO_OPTION:
086                    // do nothing
087                    break;
088                case JmriJOptionPane.CANCEL_OPTION:
089                default:
090                    // abort window closing
091                    return;
092            }
093        }
094        this.setVisible(false);
095    }
096
097    /**
098     * Ensure a TabbedPreferences instance is always available.
099     *
100     * @return the default TabbedPreferences instance, creating it if needed
101     */
102    private TabbedPreferences getTabbedPreferences() {
103        return InstanceManager.getOptionalDefault(TabbedPreferences.class).orElseGet(() -> {
104            return InstanceManager.setDefault(TabbedPreferences.class, new TabbedPreferences());
105        });
106    }
107}