001package jmri.jmrit.withrottle; 002 003import jmri.util.startup.PerformActionModel; 004import jmri.util.startup.StartupActionsManager; 005 006import java.awt.FlowLayout; 007import java.awt.GridLayout; 008import java.awt.Insets; 009import java.awt.event.ItemEvent; 010import java.awt.event.ItemListener; 011import java.beans.PropertyChangeEvent; 012import java.io.File; 013import java.util.Arrays; 014 015import javax.swing.BoxLayout; 016import javax.swing.ButtonGroup; 017import javax.swing.JCheckBox; 018import javax.swing.JComponent; 019import javax.swing.JLabel; 020import javax.swing.JPanel; 021import javax.swing.JRadioButton; 022import javax.swing.JSpinner; 023import javax.swing.SpinnerNumberModel; 024 025import jmri.InstanceManager; 026import jmri.swing.JTitledSeparator; 027import jmri.swing.PreferencesPanel; 028import jmri.util.FileUtil; 029import jmri.util.swing.JmriJOptionPane; 030import jmri.util.zeroconf.ZeroConfPreferences; 031import jmri.util.zeroconf.ZeroConfServiceManager; 032 033import org.openide.util.lookup.ServiceProvider; 034 035/** 036 * @author Brett Hoffman Copyright (C) 2010 037 */ 038@ServiceProvider(service = PreferencesPanel.class) 039public class WiThrottlePrefsPanel extends JPanel implements PreferencesPanel { 040 041 JCheckBox eStopCB; 042 JSpinner delaySpinner; 043 044 JCheckBox momF2CB; 045 046 JCheckBox exclusiveCB; 047 048 JSpinner port; 049 050 JCheckBox powerCB; 051 JCheckBox turnoutCB; 052 JCheckBox turnoutCreationCB; 053 JCheckBox routeCB; 054 JCheckBox consistCB; 055 JCheckBox startupCB; 056 JCheckBox useIPv4CB; 057 JCheckBox useIPv6CB; 058 JCheckBox fastClockDisplayCB; 059 ItemListener startupItemListener; 060 int startupActionPosition = -1; 061 JRadioButton wifiRB; 062 JRadioButton dccRB; 063 064 //early defaults while creating panel 065 int eStopInitialValue = 10; 066 int eStopMinValue = 4; 067 int eStopMaxValue = 180; 068 int eStopStepSize = 2; 069 070 WiThrottlePreferences localPrefs; 071 072 public WiThrottlePrefsPanel() { 073 if (InstanceManager.getNullableDefault(WiThrottlePreferences.class) == null) { 074 InstanceManager.store(new WiThrottlePreferences(FileUtil.getUserFilesPath() + "throttle" + File.separator + "WiThrottlePreferences.xml"), WiThrottlePreferences.class); 075 } 076 localPrefs = InstanceManager.getDefault(WiThrottlePreferences.class); 077 initGUI(); 078 setGUI(); 079 } 080 081 public void initGUI() { 082 setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS)); 083 add(new JTitledSeparator(Bundle.getMessage("TitleDelayPanel"))); 084 add(eStopDelayPanel()); 085 add(new JTitledSeparator(Bundle.getMessage("TitleFunctionsPanel"))); 086 add(functionsPanel()); 087 add(new JTitledSeparator(Bundle.getMessage("TitleExclusivePanel"))); 088 add(exclusivePanel()); 089 add(new JTitledSeparator(Bundle.getMessage("TitleNetworkPanel"))); 090 add(networkPanel()); 091 add(new JTitledSeparator(Bundle.getMessage("TitleControllersPanel"))); 092 add(allowedControllers()); 093 } 094 095 private void setGUI() { 096 eStopCB.setSelected(localPrefs.isUseEStop()); 097 delaySpinner.setValue(localPrefs.getEStopDelay()); 098 099 momF2CB.setSelected(localPrefs.isUseMomF2()); 100 101 exclusiveCB.setSelected(localPrefs.isExclusiveUseOfAddress()); 102 103 port.setValue(localPrefs.getPort()); 104 powerCB.setSelected(localPrefs.isAllowTrackPower()); 105 turnoutCB.setSelected(localPrefs.isAllowTurnout()); 106 turnoutCreationCB.setSelected(localPrefs.isAllowTurnoutCreation()); 107 routeCB.setSelected(localPrefs.isAllowRoute()); 108 fastClockDisplayCB.setSelected(localPrefs.isDisplayFastClock()); 109 consistCB.setSelected(localPrefs.isAllowConsist()); 110 InstanceManager.getDefault(StartupActionsManager.class).addPropertyChangeListener((PropertyChangeEvent evt) -> { 111 startupCB.setSelected(isStartUpAction()); 112 }); 113 useIPv4CB.setSelected(isUseIPv4()); 114 useIPv6CB.setSelected(isUseIPv6()); 115 wifiRB.setSelected(localPrefs.isUseWiFiConsist()); 116 dccRB.setSelected(!localPrefs.isUseWiFiConsist()); 117 } 118 119 /** 120 * set the local prefs to match the GUI Local prefs are independent from the 121 * singleton instance prefs. 122 * 123 * @return true if set, false if values are unacceptable. 124 */ 125 private boolean setValues() { 126 boolean didSet = true; 127 localPrefs.setUseEStop(eStopCB.isSelected()); 128 localPrefs.setEStopDelay((Integer) delaySpinner.getValue()); 129 130 localPrefs.setUseMomF2(momF2CB.isSelected()); 131 132 localPrefs.setExclusiveUseOfAddress(exclusiveCB.isSelected()); 133 134 int portNum; 135 try { 136 portNum = (int) port.getValue(); 137 } catch (NumberFormatException NFE) { // Not a number 138 portNum = 0; 139 } 140 if ((portNum < 1) || (portNum > 65535)) { // Invalid port value 141 JmriJOptionPane.showMessageDialog(this, 142 Bundle.getMessage("WarningInvalidPort"), 143 Bundle.getMessage("TitlePortWarningDialog"), 144 JmriJOptionPane.WARNING_MESSAGE); 145 didSet = false; 146 } else { 147 localPrefs.setPort((int) port.getValue()); 148 } 149 150 localPrefs.setAllowTrackPower(powerCB.isSelected()); 151 localPrefs.setAllowTurnout(turnoutCB.isSelected()); 152 localPrefs.setAllowTurnoutCreation(turnoutCreationCB.isSelected()); 153 localPrefs.setAllowRoute(routeCB.isSelected()); 154 localPrefs.setDisplayFastClock(fastClockDisplayCB.isSelected()); 155 localPrefs.setAllowConsist(consistCB.isSelected()); 156 localPrefs.setUseWiFiConsist(wifiRB.isSelected()); 157 ZeroConfPreferences zeroConfPrefs = InstanceManager.getDefault(ZeroConfServiceManager.class).getPreferences(); 158 zeroConfPrefs.setUseIPv4(useIPv4CB.isSelected()); 159 zeroConfPrefs.setUseIPv6(useIPv6CB.isSelected()); 160 161 return didSet; 162 } 163 164 private JPanel eStopDelayPanel() { 165 JPanel panel = new JPanel(); 166 167 eStopCB = new JCheckBox(Bundle.getMessage("LabelUseEStop")); 168 eStopCB.setToolTipText(Bundle.getMessage("ToolTipUseEStop")); 169 SpinnerNumberModel spinMod = new SpinnerNumberModel(eStopInitialValue, eStopMinValue, eStopMaxValue, eStopStepSize); 170 delaySpinner = new JSpinner(spinMod); 171 ((JSpinner.DefaultEditor) delaySpinner.getEditor()).getTextField().setEditable(false); 172 panel.add(eStopCB); 173 panel.add(delaySpinner); 174 panel.add(new JLabel(Bundle.getMessage("LabelEStopDelay"))); 175 return panel; 176 } 177 178 private JPanel functionsPanel() { 179 JPanel panel = new JPanel(); 180 181 momF2CB = new JCheckBox(Bundle.getMessage("LabelMomF2")); 182 momF2CB.setToolTipText(Bundle.getMessage("ToolTipMomF2")); 183 panel.add(momF2CB); 184 return panel; 185 } 186 187 private JPanel exclusivePanel() { 188 JPanel panel = new JPanel(); 189 190 exclusiveCB = new JCheckBox(Bundle.getMessage("LabelExclusive")); 191 exclusiveCB.setToolTipText(Bundle.getMessage("ToolTipExclusive")); 192 panel.add(exclusiveCB); 193 return panel; 194 } 195 196 private JPanel networkPanel() { 197 JPanel nPanelRow1 = new JPanel(); 198 JPanel nPanelRow2 = new JPanel(); 199 JPanel nPanelRow3 = new JPanel(); 200 JPanel nPanel = new JPanel(new GridLayout(3, 1)); 201 202 port = new JSpinner(new SpinnerNumberModel(localPrefs.getPort(), 1, 65535, 1)); 203 port.setToolTipText(Bundle.getMessage("PortToolTip")); 204 port.setEditor(new JSpinner.NumberEditor(port, "#")); 205 JLabel label = new JLabel(Bundle.getMessage("LabelPort")); 206 label.setToolTipText(port.getToolTipText()); 207 nPanelRow1.add(port); 208 nPanelRow1.add(label); 209 nPanel.add(nPanelRow1); 210 211 startupCB = new JCheckBox(Bundle.getMessage("LabelStartup"), isStartUpAction()); 212 startupItemListener = (ItemEvent e) -> { 213 this.startupCB.removeItemListener(this.startupItemListener); 214 StartupActionsManager manager = InstanceManager.getDefault(StartupActionsManager.class); 215 if (this.startupCB.isSelected()) { 216 PerformActionModel model = new PerformActionModel(); 217 model.setClassName(WiThrottleCreationAction.class.getName()); 218 if (this.startupActionPosition == -1 || this.startupActionPosition >= manager.getActions().length) { 219 manager.addAction(model); 220 } else { 221 manager.setActions(this.startupActionPosition, model); 222 } 223 } else { 224 manager.getActions(PerformActionModel.class).stream().filter((model) -> (WiThrottleCreationAction.class.getName().equals(model.getClassName()))).forEach((model) -> { 225 this.startupActionPosition = Arrays.asList(manager.getActions()).indexOf(model); 226 manager.removeAction(model); 227 }); 228 } 229 this.startupCB.addItemListener(this.startupItemListener); 230 }; 231 this.startupCB.addItemListener(this.startupItemListener); 232 nPanelRow2.add(startupCB); 233 nPanel.add(nPanelRow2); 234 235 useIPv4CB = new JCheckBox(Bundle.getMessage("LabelUseIPv4"), isUseIPv4()); 236 useIPv4CB.setToolTipText(Bundle.getMessage("ToolTipUseIPv4")); 237 nPanelRow3.add(useIPv4CB); 238 useIPv6CB = new JCheckBox(Bundle.getMessage("LabelUseIPv6"), isUseIPv6()); 239 useIPv6CB.setToolTipText(Bundle.getMessage("ToolTipUseIPv6")); 240 nPanelRow3.add(useIPv6CB); 241 nPanel.add(nPanelRow3); 242 243 return nPanel; 244 } 245 246 private JPanel allowedControllers() { 247 JPanel panel = new JPanel(); 248 249 powerCB = new JCheckBox(Bundle.getMessage("LabelTrackPower")); 250 powerCB.setToolTipText(Bundle.getMessage("ToolTipTrackPower")); 251 252 turnoutCB = new JCheckBox(Bundle.getMessage("Turnouts")); 253 turnoutCB.setToolTipText(Bundle.getMessage("ToolTipTurnout")); 254 255 turnoutCreationCB = new JCheckBox(Bundle.getMessage("TurnoutCreation")); 256 turnoutCreationCB.setToolTipText(Bundle.getMessage("ToolTipTurnoutCreation")); 257 258 routeCB = new JCheckBox(Bundle.getMessage("LabelRoute")); 259 routeCB.setToolTipText(Bundle.getMessage("ToolTipRoute")); 260 261 fastClockDisplayCB = new JCheckBox(Bundle.getMessage("LabelFastClockDisplayed")); 262 fastClockDisplayCB.setToolTipText(Bundle.getMessage("ToolTipFastClockDisplayed")); 263 264 consistCB = new JCheckBox(Bundle.getMessage("LabelConsist")); 265 consistCB.setToolTipText(Bundle.getMessage("ToolTipConsist")); 266 267 wifiRB = new JRadioButton(Bundle.getMessage("LabelWiFiConsist")); 268 wifiRB.setToolTipText(Bundle.getMessage("ToolTipWiFiConsist")); 269 dccRB = new JRadioButton(Bundle.getMessage("LabelDCCConsist")); 270 dccRB.setToolTipText(Bundle.getMessage("ToolTipDCCConsist")); 271 272 ButtonGroup group = new ButtonGroup(); 273 group.add(wifiRB); 274 group.add(dccRB); 275 276 JPanel gridPanel = new JPanel(new GridLayout(0, 2)); 277 JPanel conPanel = new JPanel(); 278 279 gridPanel.add(powerCB); 280 gridPanel.add(fastClockDisplayCB); 281 gridPanel.add(turnoutCB); 282 gridPanel.add(turnoutCreationCB); 283 gridPanel.add(routeCB); 284 285 conPanel.setLayout(new BoxLayout(conPanel, BoxLayout.Y_AXIS)); 286 wifiRB.setMargin(new Insets(0, 20, 0, 0)); 287 dccRB.setMargin(new Insets(0, 20, 0, 0)); 288 conPanel.add(consistCB); 289 conPanel.add(wifiRB); 290 conPanel.add(dccRB); 291 292 panel.setLayout(new FlowLayout(FlowLayout.CENTER, 40, 0)); 293 panel.add(gridPanel); 294 panel.add(conPanel); 295 296 return panel; 297 } 298 299 //private final static Logger log = LoggerFactory.getLogger(WiThrottlePrefsPanel.class); 300 @Override 301 public String getPreferencesItem() { 302 return "WITHROTTLE"; // NOI18N 303 } 304 305 @Override 306 public String getPreferencesItemText() { 307 return Bundle.getMessage("MenuMenu"); // NOI18N 308 } 309 310 @Override 311 public String getTabbedPreferencesTitle() { 312 return getPreferencesItemText(); 313 } 314 315 @Override 316 public String getLabelKey() { 317 return null; 318 } 319 320 @Override 321 public JComponent getPreferencesComponent() { 322 return this; 323 } 324 325 @Override 326 public boolean isPersistant() { 327 return false; 328 } 329 330 @Override 331 public String getPreferencesTooltip() { 332 return null; 333 } 334 335 @Override 336 public void savePreferences() { 337 if (setValues()) { 338 this.localPrefs.save(); 339 } 340 } 341 342 @Override 343 public boolean isDirty() { 344 return this.localPrefs.isDirty(); 345 } 346 347 @Override 348 public boolean isRestartRequired() { 349 return this.localPrefs.isRestartRequired(); 350 } 351 352 @Override 353 public boolean isPreferencesValid() { 354 return true; // no validity checking performed 355 } 356 357 private boolean isStartUpAction() { 358 return InstanceManager.getDefault(StartupActionsManager.class).getActions(PerformActionModel.class).stream() 359 .anyMatch((model) -> (WiThrottleCreationAction.class.getName().equals(model.getClassName()))); 360 } 361 362 private boolean isUseIPv4() { 363 return InstanceManager.getDefault(ZeroConfServiceManager.class).getPreferences().isUseIPv4(); 364 } 365 366 private boolean isUseIPv6() { 367 return InstanceManager.getDefault(ZeroConfServiceManager.class).getPreferences().isUseIPv6(); 368 } 369}