001package jmri.server.json;
002
003import javax.swing.Box;
004import javax.swing.BoxLayout;
005import javax.swing.JComponent;
006import javax.swing.JFrame;
007import javax.swing.JLabel;
008import javax.swing.JPanel;
009import javax.swing.JSpinner;
010import javax.swing.SpinnerNumberModel;
011import jmri.InstanceManager;
012import jmri.swing.JTitledSeparator;
013import jmri.swing.PreferencesPanel;
014import org.openide.util.lookup.ServiceProvider;
015
016/**
017 * @author Randall Wood Copyright (C) 2012, 2015, 2020
018 */
019@ServiceProvider(service = PreferencesPanel.class)
020public class JsonServerPreferencesPanel extends JPanel implements PreferencesPanel {
021
022    public static final int MAX_HEARTBEAT_INTERVAL = 3600;
023    public static final int MIN_HEARTBEAT_INTERVAL = 1;
024    private JSpinner heartbeatIntervalSpinner;
025    private JSpinner port;
026    private transient JsonServerPreferences preferences;
027    private JFrame parentFrame = null;
028
029    public JsonServerPreferencesPanel() {
030        preferences = new JsonServerPreferences();
031        preferences.apply(InstanceManager.getDefault(JsonServerPreferences.class));
032        initGUI();
033        setGUI();
034    }
035
036    public JsonServerPreferencesPanel(JFrame f) {
037        this();
038        parentFrame = f;
039    }
040
041    private void initGUI() {
042        setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
043        add(new JTitledSeparator(Bundle.getMessage("ServerSectionTitle")));
044        add(portPanel());
045        add(new JTitledSeparator(Bundle.getMessage("JSONSectionTitle")));
046        add(heartbeatPanel());
047        add(Box.createVerticalGlue());
048    }
049
050    private void setGUI() {
051        heartbeatIntervalSpinner.setValue(preferences.getHeartbeatInterval() / 1000); // convert from milliseconds to seconds
052        port.setValue(preferences.getPort());
053    }
054
055    /**
056     * Set the preferences to match the GUI. Local prefs are independent from the
057     * singleton instance prefs.
058     *
059     * @return true if set, false if values are unacceptable.
060     */
061    private boolean setValues() {
062        boolean didSet = true;
063        preferences.setHeartbeatInterval((int) heartbeatIntervalSpinner.getValue() * 1000); // convert to milliseconds from seconds
064        preferences.setPort((int) port.getValue());
065        return didSet;
066    }
067
068    private JPanel heartbeatPanel() {
069        JPanel panel = new JPanel();
070        heartbeatIntervalSpinner = new JSpinner(new SpinnerNumberModel(15, MIN_HEARTBEAT_INTERVAL, MAX_HEARTBEAT_INTERVAL, 1));
071        ((JSpinner.DefaultEditor) heartbeatIntervalSpinner.getEditor()).getTextField().setEditable(true);
072        heartbeatIntervalSpinner.addChangeListener(e -> setValues());
073        heartbeatIntervalSpinner.setToolTipText(Bundle.getMessage("HeartbeatToolTip", MIN_HEARTBEAT_INTERVAL, MAX_HEARTBEAT_INTERVAL));
074        panel.add(heartbeatIntervalSpinner);
075        JLabel label = new JLabel(Bundle.getMessage("HeartbeatLabel"));
076        label.setToolTipText(heartbeatIntervalSpinner.getToolTipText());
077        panel.add(label);
078        return panel;
079    }
080
081    private JPanel portPanel() {
082        JPanel panel = new JPanel();
083        port = new JSpinner(new SpinnerNumberModel(JsonServerPreferences.DEFAULT_PORT, 1, 65535, 1));
084        ((JSpinner.DefaultEditor) port.getEditor()).getTextField().setEditable(true);
085        port.setEditor(new JSpinner.NumberEditor(port, "#"));
086        port.addChangeListener(e -> setValues());
087        port.setToolTipText(Bundle.getMessage("PortToolTip"));
088        panel.add(port);
089        JLabel label = new JLabel(Bundle.getMessage("LabelPort"));
090        label.setToolTipText(port.getToolTipText());
091        panel.add(label);
092        return panel;
093    }
094
095    @Override
096    public String getPreferencesItem() {
097        return Bundle.getMessage("PreferencesItem");
098    }
099
100    @Override
101    public String getPreferencesItemText() {
102        return Bundle.getMessage("PreferencesItemTitle");
103    }
104
105    @Override
106    public String getTabbedPreferencesTitle() {
107        return Bundle.getMessage("PreferencesTabTitle");
108    }
109
110    @Override
111    public String getLabelKey() {
112        return null;
113    }
114
115    @Override
116    public JComponent getPreferencesComponent() {
117        return this;
118    }
119
120    @Override
121    public boolean isPersistant() {
122        return false;
123    }
124
125    @Override
126    public String getPreferencesTooltip() {
127        return Bundle.getMessage("PreferencesTooltip");
128    }
129
130    @Override
131    public void savePreferences() {
132        if (setValues()) {
133            InstanceManager.getDefault(JsonServerPreferences.class).apply(preferences);
134            InstanceManager.getDefault(JsonServerPreferences.class).save();
135            if (parentFrame != null) {
136                parentFrame.dispose();
137            }
138        }
139    }
140
141    @Override
142    public boolean isDirty() {
143        return preferences.compareValuesDifferent(InstanceManager.getDefault(JsonServerPreferences.class))
144                || InstanceManager.getDefault(JsonServerPreferences.class).isDirty();
145    }
146
147    @Override
148    public boolean isRestartRequired() {
149        return InstanceManager.getDefault(JsonServerPreferences.class).isRestartRequired();
150    }
151
152    @Override
153    public boolean isPreferencesValid() {
154        return true; // no validity checking performed
155    }
156}