001package jmri.jmrit.operations.setup.gui; 002 003import java.awt.GridBagLayout; 004 005import javax.swing.*; 006 007import jmri.InstanceManager; 008import jmri.jmrit.operations.locations.LocationManager; 009import jmri.jmrit.operations.setup.OperationsSetupXml; 010import jmri.jmrit.operations.setup.Setup; 011import jmri.jmrit.operations.trains.TrainManager; 012import jmri.util.swing.JmriJOptionPane; 013 014/** 015 * Frame for user edit of setup options 016 * 017 * @author Dan Boudreau Copyright (C) 2010, 2011, 2012, 2013, 2015 018 */ 019public class OptionPanel extends OperationsPreferencesPanel { 020 021 // labels 022 // major buttons 023 JButton saveButton = new JButton(Bundle.getMessage("ButtonSave")); 024 025 // radio buttons 026 JRadioButton buildNormal = new JRadioButton(Bundle.getMessage("Normal")); 027 JRadioButton buildAggressive = new JRadioButton(Bundle.getMessage("Aggressive")); 028 029 // check boxes 030 JCheckBox routerCheckBox = new JCheckBox(Bundle.getMessage("EnableCarRouting")); 031 JCheckBox routerYardCheckBox = new JCheckBox(Bundle.getMessage("EnableCarRoutingYard")); 032 JCheckBox routerStagingCheckBox = new JCheckBox(Bundle.getMessage("EnableCarRoutingStaging")); 033 JCheckBox routerAllTrainsBox = new JCheckBox(Bundle.getMessage("AllTrains")); 034 JCheckBox routerRestrictBox = new JCheckBox(Bundle.getMessage("EnableTrackDestinationRestrictions")); 035 036 JCheckBox valueCheckBox = new JCheckBox(Bundle.getMessage("EnableValue")); 037 JCheckBox rfidCheckBox = new JCheckBox(Bundle.getMessage("EnableRfid")); 038 JCheckBox carLoggerCheckBox = new JCheckBox(Bundle.getMessage("EnableCarLogging")); 039 JCheckBox engineLoggerCheckBox = new JCheckBox(Bundle.getMessage("EnableEngineLogging")); 040 JCheckBox trainLoggerCheckBox = new JCheckBox(Bundle.getMessage("EnableTrainLogging")); 041 042 JCheckBox localInterchangeCheckBox = new JCheckBox(Bundle.getMessage("AllowLocalInterchange")); 043 JCheckBox localSpurCheckBox = new JCheckBox(Bundle.getMessage("AllowLocalSpur")); 044 JCheckBox localYardCheckBox = new JCheckBox(Bundle.getMessage("AllowLocalYard")); 045 046 JCheckBox trainIntoStagingCheckBox = new JCheckBox(Bundle.getMessage("TrainIntoStaging")); 047 JCheckBox stagingAvailCheckBox = new JCheckBox(Bundle.getMessage("StagingAvailable")); 048 JCheckBox stagingTurnCheckBox = new JCheckBox(Bundle.getMessage("AllowCarsToReturn")); 049 JCheckBox promptFromTrackStagingCheckBox = new JCheckBox(Bundle.getMessage("PromptFromStaging")); 050 JCheckBox promptToTrackStagingCheckBox = new JCheckBox(Bundle.getMessage("PromptToStaging")); 051 JCheckBox tryNormalStagingCheckBox = new JCheckBox(Bundle.getMessage("TryNormalStaging")); 052 053 JCheckBox generateCvsManifestCheckBox = new JCheckBox(Bundle.getMessage("GenerateCsvManifest")); 054 JCheckBox generateCvsSwitchListCheckBox = new JCheckBox(Bundle.getMessage("GenerateCsvSwitchList")); 055 056 JCheckBox enableVsdCheckBox = new JCheckBox(Bundle.getMessage("EnableVSD")); 057 JCheckBox saveTrainManifestCheckBox = new JCheckBox(Bundle.getMessage("SaveManifests")); 058 059 // text field 060 JTextField rfidTextField = new JTextField(10); 061 JTextField valueTextField = new JTextField(10); 062 063 // combo boxes 064 JComboBox<Integer> numberPassesComboBox = new JComboBox<>(); 065 066 public OptionPanel() { 067 068 // load checkboxes 069 localInterchangeCheckBox.setSelected(Setup.isLocalInterchangeMovesEnabled()); 070 localSpurCheckBox.setSelected(Setup.isLocalSpurMovesEnabled()); 071 localYardCheckBox.setSelected(Setup.isLocalYardMovesEnabled()); 072 // staging options 073 trainIntoStagingCheckBox.setSelected(Setup.isStagingTrainCheckEnabled()); 074 stagingAvailCheckBox.setSelected(Setup.isStagingTrackImmediatelyAvail()); 075 stagingTurnCheckBox.setSelected(Setup.isStagingAllowReturnEnabled()); 076 promptToTrackStagingCheckBox.setSelected(Setup.isStagingPromptToEnabled()); 077 promptFromTrackStagingCheckBox.setSelected(Setup.isStagingPromptFromEnabled()); 078 tryNormalStagingCheckBox.setSelected(Setup.isStagingTryNormalBuildEnabled()); 079 // router 080 routerCheckBox.setSelected(Setup.isCarRoutingEnabled()); 081 routerYardCheckBox.setSelected(Setup.isCarRoutingViaYardsEnabled()); 082 routerStagingCheckBox.setSelected(Setup.isCarRoutingViaStagingEnabled()); 083 routerAllTrainsBox.setSelected(!Setup.isOnlyActiveTrainsEnabled()); 084 routerRestrictBox.setSelected(Setup.isCheckCarDestinationEnabled()); 085 // logging options 086 carLoggerCheckBox.setSelected(Setup.isCarLoggerEnabled()); 087 engineLoggerCheckBox.setSelected(Setup.isEngineLoggerEnabled()); 088 trainLoggerCheckBox.setSelected(Setup.isTrainLoggerEnabled()); 089 // save manifests 090 saveTrainManifestCheckBox.setSelected(Setup.isSaveTrainManifestsEnabled()); 091 092 generateCvsManifestCheckBox.setSelected(Setup.isGenerateCsvManifestEnabled()); 093 generateCvsSwitchListCheckBox.setSelected(Setup.isGenerateCsvSwitchListEnabled()); 094 valueCheckBox.setSelected(Setup.isValueEnabled()); 095 rfidCheckBox.setSelected(Setup.isRfidEnabled()); 096 enableVsdCheckBox.setSelected(Setup.isVsdPhysicalLocationEnabled()); 097 098 // load text fields 099 rfidTextField.setText(Setup.getRfidLabel()); 100 valueTextField.setText(Setup.getValueLabel()); 101 102 // add tool tips 103 saveButton.setToolTipText(Bundle.getMessage("SaveToolTip")); 104 rfidTextField.setToolTipText(Bundle.getMessage("EnterNameRfidTip")); 105 valueTextField.setToolTipText(Bundle.getMessage("EnterNameValueTip")); 106 stagingTurnCheckBox.setToolTipText(Bundle.getMessage("AlsoAvailablePerTrain")); 107 108 // load combobox, allow 2 to 4 passes 109 for (int x = 2; x < 5; x++) { 110 numberPassesComboBox.addItem(x); 111 } 112 113 numberPassesComboBox.setSelectedItem(Setup.getNumberPasses()); 114 padComboBox(numberPassesComboBox, 2); 115 116 setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); 117 118 JPanel panel = new JPanel(); 119 panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); 120 JScrollPane panelPane = new JScrollPane(panel); 121 122 // Build Options panel 123 JPanel pBuild = new JPanel(); 124 pBuild.setLayout(new BoxLayout(pBuild, BoxLayout.Y_AXIS)); 125 pBuild.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("BorderLayoutBuildOptions"))); 126 127 JPanel pOpt = new JPanel(); 128 pOpt.setLayout(new GridBagLayout()); 129 130 addItem(pOpt, buildNormal, 1, 0); 131 addItem(pOpt, buildAggressive, 2, 0); 132 pBuild.add(pOpt); 133 134 JPanel pPasses = new JPanel(); 135 pPasses.setLayout(new GridBagLayout()); 136 pPasses.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("BorderLayoutNumberPasses"))); 137 addItem(pPasses, numberPassesComboBox, 0, 0); 138 pBuild.add(pPasses); 139 140 // Switcher Service 141 JPanel pSwitcher = new JPanel(); 142 pSwitcher.setLayout(new GridBagLayout()); 143 pSwitcher.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("BorderLayoutSwitcherService"))); 144 145 addItemLeft(pSwitcher, localInterchangeCheckBox, 1, 1); 146 addItemLeft(pSwitcher, localSpurCheckBox, 1, 2); 147 addItemLeft(pSwitcher, localYardCheckBox, 1, 3); 148 149 // Staging 150 JPanel pStaging = new JPanel(); 151 pStaging.setLayout(new GridBagLayout()); 152 pStaging.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("BorderLayoutStaging"))); 153 154 addItemLeft(pStaging, trainIntoStagingCheckBox, 1, 4); 155 addItemLeft(pStaging, stagingAvailCheckBox, 1, 5); 156 addItemLeft(pStaging, stagingTurnCheckBox, 1, 6); 157 addItemLeft(pStaging, promptFromTrackStagingCheckBox, 1, 7); 158 addItemLeft(pStaging, promptToTrackStagingCheckBox, 1, 8); 159 addItemLeft(pStaging, tryNormalStagingCheckBox, 1, 9); 160 161 // Router panel 162 JPanel pRouter = new JPanel(); 163 pRouter.setLayout(new GridBagLayout()); 164 pRouter.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("BorderLayoutRouterOptions"))); 165 addItemLeft(pRouter, routerCheckBox, 1, 0); 166 addItemLeft(pRouter, routerYardCheckBox, 1, 1); 167 addItemLeft(pRouter, routerStagingCheckBox, 1, 2); 168 addItemLeft(pRouter, routerAllTrainsBox, 1, 3); 169 addItemLeft(pRouter, routerRestrictBox, 1, 4); 170 171 // Logger panel 172 JPanel pLogger = new JPanel(); 173 pLogger.setLayout(new GridBagLayout()); 174 pLogger.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("BorderLayoutLoggerOptions"))); 175 addItemLeft(pLogger, engineLoggerCheckBox, 1, 0); 176 addItemLeft(pLogger, carLoggerCheckBox, 1, 1); 177 addItemLeft(pLogger, trainLoggerCheckBox, 1, 2); 178 179 // Custom Manifests and Switch Lists 180 JPanel pCustom = new JPanel(); 181 pCustom.setLayout(new GridBagLayout()); 182 pCustom.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("BorderLayoutCustomManifests"))); 183 addItemLeft(pCustom, generateCvsManifestCheckBox, 1, 0); 184 addItemLeft(pCustom, generateCvsSwitchListCheckBox, 1, 1); 185 186 // Options 187 JPanel pOption = new JPanel(); 188 pOption.setLayout(new GridBagLayout()); 189 pOption.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("BorderLayoutOptions"))); 190 addItemLeft(pOption, saveTrainManifestCheckBox, 1, 1); 191 addItemLeft(pOption, valueCheckBox, 1, 2); 192 addItemLeft(pOption, valueTextField, 2, 2); 193 addItemLeft(pOption, rfidCheckBox, 1, 3); 194 addItemLeft(pOption, rfidTextField, 2, 3); 195 addItemLeft(pOption, enableVsdCheckBox, 1, 4); 196 197 // row 11 198 JPanel pControl = new JPanel(); 199 pControl.setLayout(new GridBagLayout()); 200 addItem(pControl, saveButton, 3, 9); 201 202 panel.add(pBuild); 203 panel.add(pSwitcher); 204 panel.add(pStaging); 205 panel.add(pRouter); 206 panel.add(pLogger); 207 panel.add(pCustom); 208 panel.add(pOption); 209 210 add(panelPane); 211 add(pControl); 212 213 // setup buttons 214 addButtonAction(saveButton); 215 216 // radio buttons 217 ButtonGroup buildGroup = new ButtonGroup(); 218 buildGroup.add(buildNormal); 219 buildGroup.add(buildAggressive); 220 addRadioButtonAction(buildNormal); 221 addRadioButtonAction(buildAggressive); 222 223 // check boxes 224 addCheckBoxAction(routerCheckBox); 225 addCheckBoxAction(routerRestrictBox); 226 setRouterCheckBoxesEnabled(); 227 228 setBuildOption(); 229 enableComponents(); 230 } 231 232 private void setBuildOption() { 233 buildNormal.setSelected(!Setup.isBuildAggressive()); 234 buildAggressive.setSelected(Setup.isBuildAggressive()); 235 } 236 237 private void enableComponents() { 238 // disable staging option if normal mode 239 stagingAvailCheckBox.setEnabled(buildAggressive.isSelected()); 240 numberPassesComboBox.setEnabled(buildAggressive.isSelected()); 241 tryNormalStagingCheckBox.setEnabled(buildAggressive.isSelected()); 242 } 243 244 @Override 245 public void radioButtonActionPerformed(java.awt.event.ActionEvent ae) { 246 log.debug("radio button selected"); 247 // can't change the build option if there are trains built 248 if (InstanceManager.getDefault(TrainManager.class).isAnyTrainBuilt()) { 249 setBuildOption(); // restore the correct setting 250 JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("CanNotChangeBuild"), 251 Bundle.getMessage("MustTerminateOrReset"), JmriJOptionPane.ERROR_MESSAGE); 252 } 253 enableComponents(); 254 // Special case where there are train build failures that created work. 255 // Track reserve needs to cleaned up by reseting build failed trains 256 if (buildAggressive.isSelected() != Setup.isBuildAggressive() && 257 InstanceManager.getDefault(LocationManager.class).hasWork()) { 258 InstanceManager.getDefault(TrainManager.class).resetBuildFailedTrains(); 259 } 260 } 261 262 // Save button 263 @Override 264 public void buttonActionPerformed(java.awt.event.ActionEvent ae) { 265 if (ae.getSource() == saveButton) { 266 this.savePreferences(); 267 var topLevelAncestor = getTopLevelAncestor(); 268 if (Setup.isCloseWindowOnSaveEnabled() && topLevelAncestor instanceof OptionFrame) { 269 ((OptionFrame) topLevelAncestor).dispose(); 270 } 271 } 272 } 273 274 @Override 275 protected void checkBoxActionPerformed(java.awt.event.ActionEvent ae) { 276 if (ae.getSource() == routerCheckBox) { 277 setRouterCheckBoxesEnabled(); 278 } 279 if (ae.getSource() == routerRestrictBox && routerRestrictBox.isSelected()) { 280 JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("WarnExtremeTrackDest"), 281 Bundle.getMessage("WarnExtremeTitle"), JmriJOptionPane.WARNING_MESSAGE); 282 } 283 } 284 285 private void setRouterCheckBoxesEnabled() { 286 routerYardCheckBox.setEnabled(routerCheckBox.isSelected()); 287 routerStagingCheckBox.setEnabled(routerCheckBox.isSelected()); 288 routerAllTrainsBox.setEnabled(routerCheckBox.isSelected()); 289 routerRestrictBox.setEnabled(routerCheckBox.isSelected()); 290 } 291 292 @Override 293 public String getTabbedPreferencesTitle() { 294 return Bundle.getMessage("TitleOptions"); 295 } 296 297 @Override 298 public String getPreferencesTooltip() { 299 return null; 300 } 301 302 @Override 303 public void savePreferences() { 304 // build option 305 Setup.setBuildAggressive(buildAggressive.isSelected()); 306 Setup.setNumberPasses((Integer) numberPassesComboBox.getSelectedItem()); 307 // Local moves? 308 Setup.setLocalInterchangeMovesEnabled(localInterchangeCheckBox.isSelected()); 309 Setup.setLocalSpurMovesEnabled(localSpurCheckBox.isSelected()); 310 Setup.setLocalYardMovesEnabled(localYardCheckBox.isSelected()); 311 // Staging options 312 Setup.setStagingTrainCheckEnabled(trainIntoStagingCheckBox.isSelected()); 313 Setup.setStagingTrackImmediatelyAvail(stagingAvailCheckBox.isSelected()); 314 Setup.setStagingAllowReturnEnabled(stagingTurnCheckBox.isSelected()); 315 Setup.setStagingPromptFromEnabled(promptFromTrackStagingCheckBox.isSelected()); 316 Setup.setStagingPromptToEnabled(promptToTrackStagingCheckBox.isSelected()); 317 Setup.setStagingTryNormalBuildEnabled(tryNormalStagingCheckBox.isSelected()); 318 // Car routing enabled? 319 Setup.setCarRoutingEnabled(routerCheckBox.isSelected()); 320 Setup.setCarRoutingViaYardsEnabled(routerYardCheckBox.isSelected()); 321 Setup.setCarRoutingViaStagingEnabled(routerStagingCheckBox.isSelected()); 322 Setup.setOnlyActiveTrainsEnabled(!routerAllTrainsBox.isSelected()); 323 Setup.setCheckCarDestinationEnabled(routerRestrictBox.isSelected()); 324 // Options 325 Setup.setGenerateCsvManifestEnabled(generateCvsManifestCheckBox.isSelected()); 326 Setup.setGenerateCsvSwitchListEnabled(generateCvsSwitchListCheckBox.isSelected()); 327 Setup.setSaveTrainManifestsEnabled(saveTrainManifestCheckBox.isSelected()); 328 Setup.setValueEnabled(valueCheckBox.isSelected()); 329 Setup.setValueLabel(valueTextField.getText()); 330 Setup.setRfidEnabled(rfidCheckBox.isSelected()); 331 Setup.setRfidLabel(rfidTextField.getText()); 332 // Logging enabled? 333 Setup.setEngineLoggerEnabled(engineLoggerCheckBox.isSelected()); 334 Setup.setCarLoggerEnabled(carLoggerCheckBox.isSelected()); 335 Setup.setTrainLoggerEnabled(trainLoggerCheckBox.isSelected()); 336 // VSD 337 Setup.setVsdPhysicalLocationEnabled(enableVsdCheckBox.isSelected()); 338 // write the file 339 InstanceManager.getDefault(OperationsSetupXml.class).writeOperationsFile(); 340 } 341 342 @Override 343 public boolean isDirty() { 344 return !( // build option 345 Setup.isBuildAggressive() == buildAggressive.isSelected() && 346 Setup.getNumberPasses() == (int) numberPassesComboBox.getSelectedItem() 347 // Local moves? 348 && 349 Setup.isLocalInterchangeMovesEnabled() == localInterchangeCheckBox.isSelected() && 350 Setup.isLocalSpurMovesEnabled() == localSpurCheckBox.isSelected() && 351 Setup.isLocalYardMovesEnabled() == localYardCheckBox.isSelected() 352 // Staging options 353 && 354 Setup.isStagingTrainCheckEnabled() == trainIntoStagingCheckBox.isSelected() && 355 Setup.isStagingTrackImmediatelyAvail() == stagingAvailCheckBox.isSelected() && 356 Setup.isStagingAllowReturnEnabled() == stagingTurnCheckBox.isSelected() && 357 Setup.isStagingPromptFromEnabled() == promptFromTrackStagingCheckBox.isSelected() && 358 Setup.isStagingPromptToEnabled() == promptToTrackStagingCheckBox.isSelected() && 359 Setup.isStagingTryNormalBuildEnabled() == tryNormalStagingCheckBox.isSelected() 360 // Car routing enabled? 361 && 362 Setup.isCarRoutingEnabled() == routerCheckBox.isSelected() && 363 Setup.isCarRoutingViaYardsEnabled() == routerYardCheckBox.isSelected() && 364 Setup.isCarRoutingViaStagingEnabled() == routerStagingCheckBox.isSelected() && 365 Setup.isOnlyActiveTrainsEnabled() == !routerAllTrainsBox.isSelected() && 366 Setup.isCheckCarDestinationEnabled() == routerRestrictBox.isSelected() 367 // Options 368 && 369 Setup.isGenerateCsvManifestEnabled() == generateCvsManifestCheckBox.isSelected() && 370 Setup.isGenerateCsvSwitchListEnabled() == generateCvsSwitchListCheckBox.isSelected() && 371 Setup.isValueEnabled() == valueCheckBox.isSelected() && 372 Setup.getValueLabel().equals(valueTextField.getText()) && 373 Setup.isRfidEnabled() == rfidCheckBox.isSelected() && 374 Setup.getRfidLabel().equals(rfidTextField.getText()) && 375 Setup.isSaveTrainManifestsEnabled() == saveTrainManifestCheckBox.isSelected() 376 // Logging enabled? 377 && 378 Setup.isEngineLoggerEnabled() == engineLoggerCheckBox.isSelected() && 379 Setup.isCarLoggerEnabled() == carLoggerCheckBox.isSelected() && 380 Setup.isTrainLoggerEnabled() == trainLoggerCheckBox.isSelected() 381 // VSD 382 && 383 Setup.isVsdPhysicalLocationEnabled() == enableVsdCheckBox.isSelected()); 384 } 385 386 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(OptionPanel.class); 387 388}