001package jmri.jmrix.loconet.loconetovertcp;
002
003import jmri.util.startup.PerformActionModel;
004import jmri.util.startup.StartupActionsManager;
005
006import java.awt.event.ItemEvent;
007import java.awt.event.ItemListener;
008import java.util.Arrays;
009
010import javax.swing.GroupLayout;
011import javax.swing.JCheckBox;
012import javax.swing.JComponent;
013import javax.swing.JLabel;
014import javax.swing.JPanel;
015import javax.swing.JSpinner;
016import javax.swing.LayoutStyle;
017import javax.swing.SpinnerNumberModel;
018
019import jmri.InstanceManager;
020import jmri.swing.PreferencesPanel;
021
022import org.jdesktop.beansbinding.AutoBinding;
023import org.jdesktop.beansbinding.BeanProperty;
024import org.jdesktop.beansbinding.BindingGroup;
025import org.jdesktop.beansbinding.Bindings;
026import org.jdesktop.beansbinding.ELProperty;
027import org.openide.util.lookup.ServiceProvider;
028
029/**
030 * Provide access to the LocoNet over TCP server settings.
031 *
032 * @author Randall Wood (C) 2017
033 */
034@ServiceProvider(service = PreferencesPanel.class)
035public class LnTcpPreferencesPanel extends JPanel implements PreferencesPanel {
036
037    private JSpinner port;
038    private JLabel portLabel;
039    private final LnTcpPreferences preferences;
040    private JCheckBox startup;
041    private ItemListener startupItemListener;
042    private int startupActionPosition = -1;
043    private BindingGroup bindingGroup;
044
045    public LnTcpPreferencesPanel() {
046        preferences = InstanceManager.getOptionalDefault(LnTcpPreferences.class).orElseGet(() -> {
047            return InstanceManager.setDefault(LnTcpPreferences.class, new LnTcpPreferences());
048        });
049        initComponents();
050    }
051
052    private void initComponents() {
053        bindingGroup = new BindingGroup();
054        port = new JSpinner();
055        portLabel = new JLabel();
056        startup = new JCheckBox();
057
058        port.setModel(new SpinnerNumberModel(1234, 1, 65535, 1));
059        port.setEditor(new JSpinner.NumberEditor(port, "#"));
060        port.setToolTipText(Bundle.getMessage("ToolTipPort")); // NOI18N
061
062        var binding = Bindings.createAutoBinding(AutoBinding.UpdateStrategy.READ_WRITE, preferences, ELProperty.create("${port}"), port, BeanProperty.create("value"));
063        bindingGroup.addBinding(binding);
064
065        portLabel.setText(Bundle.getMessage("LabelPort")); // NOI18N
066        portLabel.setToolTipText(Bundle.getMessage("ToolTipPort")); // NOI18N
067
068        startup.setSelected(this.isStartupAction());
069        startup.setText(Bundle.getMessage("LabelStartup")); // NOI18N
070        this.startupItemListener = (ItemEvent e) -> {
071            this.startup.removeItemListener(this.startupItemListener);
072            StartupActionsManager manager = InstanceManager.getDefault(StartupActionsManager.class);
073            if (this.startup.isSelected()) {
074                PerformActionModel model = new PerformActionModel();
075                model.setClassName(LnTcpServerAction.class.getName());
076                if (this.startupActionPosition == -1 || this.startupActionPosition >= manager.getActions().length) {
077                    manager.addAction(model);
078                } else {
079                    manager.setActions(this.startupActionPosition, model);
080                }
081            } else {
082                manager.getActions(PerformActionModel.class).stream().filter((model) -> (LnTcpServerAction.class.getName().equals(model.getClassName()))).forEach((model) -> {
083                    this.startupActionPosition = Arrays.asList(manager.getActions()).indexOf(model);
084                    manager.removeAction(model);
085                });
086            }
087            this.startup.addItemListener(this.startupItemListener);
088        };
089        this.startup.addItemListener(this.startupItemListener);
090
091        GroupLayout layout = new GroupLayout(this);
092        this.setLayout(layout);
093        layout.setHorizontalGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
094                .addGroup(layout.createSequentialGroup()
095                        .addContainerGap()
096                        .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
097                                .addGroup(layout.createSequentialGroup()
098                                        .addComponent(port, GroupLayout.PREFERRED_SIZE, 75, GroupLayout.PREFERRED_SIZE)
099                                        .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
100                                        .addComponent(portLabel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
101                                .addComponent(startup, GroupLayout.DEFAULT_SIZE, 388, Short.MAX_VALUE))
102                        .addContainerGap())
103        );
104        layout.setVerticalGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
105                .addGroup(layout.createSequentialGroup()
106                        .addContainerGap()
107                        .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
108                                .addComponent(port, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
109                                .addComponent(portLabel))
110                        .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED)
111                        .addComponent(startup)
112                        .addContainerGap(198, Short.MAX_VALUE))
113        );
114
115        bindingGroup.bind();
116    }
117
118    private boolean isStartupAction() {
119        return InstanceManager.getDefault(StartupActionsManager.class).getActions(PerformActionModel.class).stream()
120                .anyMatch((model) -> (LnTcpServerAction.class.getName().equals(model.getClassName())));
121    }
122
123    @Override
124    public String getPreferencesItem() {
125        return Bundle.getMessage("PreferencesItem");
126    }
127
128    @Override
129    public String getPreferencesItemText() {
130        return Bundle.getMessage("PreferencesItemTitle");
131    }
132
133    @Override
134    public String getTabbedPreferencesTitle() {
135        return Bundle.getMessage("PreferencesItemTitle");
136    }
137
138    @Override
139    public String getLabelKey() {
140        return null;
141    }
142
143    @Override
144    public JComponent getPreferencesComponent() {
145        return this;
146    }
147
148    @Override
149    public boolean isPersistant() {
150        return false;
151    }
152
153    @Override
154    public String getPreferencesTooltip() {
155        return null;
156    }
157
158    @Override
159    public void savePreferences() {
160        this.preferences.savePreferences();
161    }
162
163    @Override
164    public boolean isDirty() {
165        return this.preferences.isDirty();
166    }
167
168    @Override
169    public boolean isRestartRequired() {
170        return this.preferences.isRestartRequired();
171    }
172
173    @Override
174    public boolean isPreferencesValid() {
175        return this.preferences.isPreferencesValid();
176    }
177
178}