001package jmri.jmrit.operations.setup; 002 003import java.awt.GridBagLayout; 004import java.beans.PropertyChangeListener; 005import java.io.IOException; 006import java.text.MessageFormat; 007import java.util.List; 008 009import javax.swing.*; 010 011import org.slf4j.Logger; 012import org.slf4j.LoggerFactory; 013 014import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; 015import jmri.InstanceManager; 016import jmri.jmrit.display.LocoIcon; 017import jmri.jmrit.operations.OperationsXml; 018import jmri.jmrit.operations.rollingstock.cars.CarTypes; 019import jmri.jmrit.operations.routes.Route; 020import jmri.jmrit.operations.routes.RouteLocation; 021import jmri.jmrit.operations.routes.RouteManager; 022import jmri.jmrit.operations.routes.RouteManagerXml; 023import jmri.util.swing.ExceptionDisplayFrame; 024import jmri.util.swing.UnexpectedExceptionContext; 025import jmri.web.server.WebServerPreferences; 026 027/** 028 * Frame for user edit of operation parameters 029 * 030 * @author Dan Boudreau Copyright (C) 2008, 2010, 2011, 2012 031 */ 032public class OperationsSettingsPanel extends OperationsPreferencesPanel implements PropertyChangeListener { 033 034 private final static Logger log = LoggerFactory.getLogger(OperationsSettingsPanel.class); 035 036 // labels 037 private final JLabel textIconNorth = new JLabel(Bundle.getMessage("IconNorth")); 038 private final JLabel textIconSouth = new JLabel(Bundle.getMessage("IconSouth")); 039 private final JLabel textIconEast = new JLabel(Bundle.getMessage("IconEast")); 040 private final JLabel textIconWest = new JLabel(Bundle.getMessage("IconWest")); 041 private final JLabel textIconLocal = new JLabel(Bundle.getMessage("IconLocal")); 042 private final JLabel textIconTerminate = new JLabel(Bundle.getMessage("IconTerminate")); 043 044 // major buttons 045 private final JButton backupButton = new JButton(Bundle.getMessage("Backup")); 046 private final JButton restoreButton = new JButton(Bundle.getMessage("Restore")); 047 private final JButton saveButton = new JButton(Bundle.getMessage("ButtonSave")); 048 049 // radio buttons 050 private final JRadioButton scaleZ = new JRadioButton("Z"); // NOI18N 051 private final JRadioButton scaleN = new JRadioButton("N"); // NOI18N 052 private final JRadioButton scaleTT = new JRadioButton("TT"); // NOI18N 053 private final JRadioButton scaleHOn3 = new JRadioButton("HOn3"); // NOI18N 054 private final JRadioButton scaleOO = new JRadioButton("OO"); // NOI18N 055 private final JRadioButton scaleHO = new JRadioButton("HO"); // NOI18N 056 private final JRadioButton scaleSn3 = new JRadioButton("Sn3"); // NOI18N 057 private final JRadioButton scaleS = new JRadioButton("S"); // NOI18N 058 private final JRadioButton scaleOn3 = new JRadioButton("On3"); // NOI18N 059 private final JRadioButton scaleO = new JRadioButton("O"); // NOI18N 060 private final JRadioButton scaleG = new JRadioButton("G"); // NOI18N 061 062 private final JRadioButton typeDesc = new JRadioButton(Bundle.getMessage("Descriptive")); 063 private final JRadioButton typeAAR = new JRadioButton(Bundle.getMessage("AAR")); 064 065 private final JRadioButton feetUnit = new JRadioButton(Bundle.getMessage("Feet")); 066 private final JRadioButton meterUnit = new JRadioButton(Bundle.getMessage("Meter")); 067 068 // check boxes 069 final JCheckBox eastCheckBox = new JCheckBox(Bundle.getMessage("eastwest")); 070 final JCheckBox northCheckBox = new JCheckBox(Bundle.getMessage("northsouth")); 071 private final JCheckBox mainMenuCheckBox = new JCheckBox(Bundle.getMessage("MainMenu")); 072 private final JCheckBox closeOnSaveCheckBox = new JCheckBox(Bundle.getMessage("CloseOnSave")); 073 private final JCheckBox autoSaveCheckBox = new JCheckBox(Bundle.getMessage("AutoSave")); 074 private final JCheckBox autoBackupCheckBox = new JCheckBox(Bundle.getMessage("AutoBackup")); 075 private final JCheckBox iconCheckBox = new JCheckBox(Bundle.getMessage("trainIcon")); 076 private final JCheckBox appendCheckBox = new JCheckBox(Bundle.getMessage("trainIconAppend")); 077 078 // text field 079 JTextField panelTextField = new JTextField(30); 080 JTextField railroadNameTextField = new JTextField(35); 081 JTextField maxLengthTextField = new JTextField(5); 082 JTextField maxEngineSizeTextField = new JTextField(3); 083 JTextField hptTextField = new JTextField(3); 084 JTextField switchTimeTextField = new JTextField(3); 085 JTextField travelTimeTextField = new JTextField(3); 086 JTextField yearTextField = new JTextField(4); 087 088 // combo boxes 089 private final JComboBox<String> northComboBox = new JComboBox<>(); 090 private final JComboBox<String> southComboBox = new JComboBox<>(); 091 private final JComboBox<String> eastComboBox = new JComboBox<>(); 092 private final JComboBox<String> westComboBox = new JComboBox<>(); 093 private final JComboBox<String> localComboBox = new JComboBox<>(); 094 private final JComboBox<String> terminateComboBox = new JComboBox<>(); 095 096 // text area 097 private final JTextArea commentTextArea = new JTextArea(2, 80); 098 099 public OperationsSettingsPanel() { 100 super(); 101 102 // the following code sets the frame's initial state 103 // create manager to load operation settings 104 InstanceManager.getDefault(OperationsSetupXml.class); 105 106 // load fields 107 maxLengthTextField.setText(Integer.toString(Setup.getMaxTrainLength())); 108 maxEngineSizeTextField.setText(Integer.toString(Setup.getMaxNumberEngines())); 109 hptTextField.setText(Integer.toString(Setup.getHorsePowerPerTon())); 110 switchTimeTextField.setText(Integer.toString(Setup.getSwitchTime())); 111 travelTimeTextField.setText(Integer.toString(Setup.getTravelTime())); 112 panelTextField.setText(Setup.getPanelName()); 113 yearTextField.setText(Setup.getYearModeled()); 114 commentTextArea.setText(Setup.getComment()); 115 116 // load checkboxes 117 mainMenuCheckBox.setSelected(Setup.isMainMenuEnabled()); 118 closeOnSaveCheckBox.setSelected(Setup.isCloseWindowOnSaveEnabled()); 119 autoSaveCheckBox.setSelected(Setup.isAutoSaveEnabled()); 120 autoBackupCheckBox.setSelected(Setup.isAutoBackupEnabled()); 121 iconCheckBox.setSelected(Setup.isTrainIconCordEnabled()); 122 appendCheckBox.setSelected(Setup.isTrainIconAppendEnabled()); 123 124 // add tool tips 125 backupButton.setToolTipText(Bundle.getMessage("BackupToolTip")); 126 restoreButton.setToolTipText(Bundle.getMessage("RestoreToolTip")); 127 saveButton.setToolTipText(Bundle.getMessage("SaveToolTip")); 128 panelTextField.setToolTipText(Bundle.getMessage("EnterPanelName")); 129 yearTextField.setToolTipText(Bundle.getMessage("EnterYearModeled")); 130 autoSaveCheckBox.setToolTipText(Bundle.getMessage("AutoSaveTip")); 131 autoBackupCheckBox.setToolTipText(Bundle.getMessage("AutoBackUpTip")); 132 maxLengthTextField.setToolTipText(Bundle.getMessage("MaxLengthTip")); 133 maxEngineSizeTextField.setToolTipText(Bundle.getMessage("MaxEngineTip")); 134 hptTextField.setToolTipText(Bundle.getMessage("HPperTonTip")); 135 switchTimeTextField.setToolTipText(Bundle.getMessage("SwitchTimeTip")); 136 travelTimeTextField.setToolTipText(Bundle.getMessage("TravelTimeTip")); 137 railroadNameTextField.setToolTipText(Bundle.getMessage("RailroadNameTip")); 138 commentTextArea.setToolTipText(Bundle.getMessage("CommentTip")); 139 140 // Layout the panel by rows 141 setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); 142 JPanel panel = new JPanel(); 143 JScrollPane panelPane = new JScrollPane(panel); 144 panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); 145 panelPane.setBorder(BorderFactory.createTitledBorder("")); 146 147 // row 1a 148 JPanel p1 = new JPanel(); 149 p1.setLayout(new BoxLayout(p1, BoxLayout.X_AXIS)); 150 151 JPanel pRailroadName = new JPanel(); 152 pRailroadName.setLayout(new GridBagLayout()); 153 pRailroadName.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("RailroadName"))); 154 addItem(pRailroadName, railroadNameTextField, 0, 0); 155 p1.add(pRailroadName); 156 157 // row 1b 158 JPanel pTrainDir = new JPanel(); 159 pTrainDir.setLayout(new GridBagLayout()); 160 pTrainDir.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("direction"))); 161 addItemLeft(pTrainDir, northCheckBox, 1, 2); 162 addItemLeft(pTrainDir, eastCheckBox, 2, 2); 163 p1.add(pTrainDir); 164 165 setDirectionCheckBox(Setup.getTrainDirection()); 166 167 // row 3a 168 JPanel p3 = new JPanel(); 169 p3.setLayout(new BoxLayout(p3, BoxLayout.X_AXIS)); 170 171 JPanel pTrainLength = new JPanel(); 172 pTrainLength.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("MaxLength"))); 173 addItem(pTrainLength, maxLengthTextField, 0, 0); 174 p3.add(pTrainLength); 175 176 // row 3b 177 JPanel pMaxEngine = new JPanel(); 178 pMaxEngine.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("MaxEngine"))); 179 addItem(pMaxEngine, maxEngineSizeTextField, 0, 0); 180 p3.add(pMaxEngine); 181 182 // row 3c 183 JPanel pHPT = new JPanel(); 184 pHPT.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("HPT"))); 185 addItem(pHPT, hptTextField, 0, 0); 186 p3.add(pHPT); 187 188 JPanel pSwitchTime = new JPanel(); 189 pSwitchTime.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("MoveTime"))); 190 addItem(pSwitchTime, switchTimeTextField, 0, 0); 191 p3.add(pSwitchTime); 192 193 // row 3d 194 JPanel pTravelTime = new JPanel(); 195 pTravelTime.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("TravelTime"))); 196 addItem(pTravelTime, travelTimeTextField, 0, 0); 197 p3.add(pTravelTime); 198 199 // row 2 200 JPanel pScale = new JPanel(); 201 pScale.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Scale"))); 202 203 ButtonGroup scaleGroup = new ButtonGroup(); 204 scaleGroup.add(scaleZ); 205 scaleGroup.add(scaleN); 206 scaleGroup.add(scaleTT); 207 scaleGroup.add(scaleHOn3); 208 scaleGroup.add(scaleOO); 209 scaleGroup.add(scaleHO); 210 scaleGroup.add(scaleSn3); 211 scaleGroup.add(scaleS); 212 scaleGroup.add(scaleOn3); 213 scaleGroup.add(scaleO); 214 scaleGroup.add(scaleG); 215 216 pScale.add(scaleZ); 217 pScale.add(scaleN); 218 pScale.add(scaleTT); 219 pScale.add(scaleHOn3); 220 pScale.add(scaleOO); 221 pScale.add(scaleHO); 222 pScale.add(scaleSn3); 223 pScale.add(scaleS); 224 pScale.add(scaleOn3); 225 pScale.add(scaleO); 226 pScale.add(scaleG); 227 setScale(); 228 229 // row 4a 230 JPanel p9 = new JPanel(); 231 p9.setLayout(new BoxLayout(p9, BoxLayout.X_AXIS)); 232 233 JPanel pCarTypeButtons = new JPanel(); 234 pCarTypeButtons.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("CarTypes"))); 235 ButtonGroup carTypeGroup = new ButtonGroup(); 236 carTypeGroup.add(typeDesc); 237 carTypeGroup.add(typeAAR); 238 pCarTypeButtons.add(typeDesc); 239 pCarTypeButtons.add(typeAAR); 240 p9.add(pCarTypeButtons); 241 setCarTypes(); 242 243 // row 4b 244 JPanel pLengthUnit = new JPanel(); 245 pLengthUnit.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("BorderLayoutLength"))); 246 ButtonGroup lengthUnitGroup = new ButtonGroup(); 247 lengthUnitGroup.add(feetUnit); 248 lengthUnitGroup.add(meterUnit); 249 pLengthUnit.add(feetUnit); 250 pLengthUnit.add(meterUnit); 251 p9.add(pLengthUnit); 252 setLengthUnit(); 253 254 // row 4c 255 JPanel pYearModeled = new JPanel(); 256 pYearModeled.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("BorderLayoutYearModeled"))); 257 pYearModeled.add(yearTextField); 258 259 p9.add(pYearModeled); 260 261 // Option panel 262 JPanel options = new JPanel(); 263 options.setLayout(new GridBagLayout()); 264 options.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("BorderLayoutOptions"))); 265 addItem(options, mainMenuCheckBox, 0, 0); 266 addItem(options, closeOnSaveCheckBox, 1, 0); 267 addItem(options, autoSaveCheckBox, 2, 0); 268 addItem(options, autoBackupCheckBox, 3, 0); 269 270 // p9.add(options); 271 // 1st scroll panel 272 panel.add(p1); 273 panel.add(pScale); 274 panel.add(p3); 275 panel.add(p9); 276 277 // Icon panel 278 JPanel pIcon = new JPanel(); 279 pIcon.setLayout(new BoxLayout(pIcon, BoxLayout.Y_AXIS)); 280 JScrollPane pIconPane = new JScrollPane(pIcon); 281 pIconPane.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("BorderLayoutPanelOptions"))); 282 283 // row 1 Icon panel 284 JPanel p1Icon = new JPanel(); 285 p1Icon.setLayout(new BoxLayout(p1Icon, BoxLayout.X_AXIS)); 286 287 JPanel pPanelName = new JPanel(); 288 pPanelName.setLayout(new GridBagLayout()); 289 pPanelName.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("BorderLayoutPanelName"))); 290 addItem(pPanelName, panelTextField, 0, 0); 291 p1Icon.add(pPanelName); 292 293 JPanel pIconControl = new JPanel(); 294 pIconControl.setLayout(new GridBagLayout()); 295 pIconControl.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("BorderLayoutIconOptions"))); 296 addItem(pIconControl, appendCheckBox, 0, 0); 297 addItem(pIconControl, iconCheckBox, 1, 0); 298 p1Icon.add(pIconControl); 299 300 pIcon.add(p1Icon); 301 302 JPanel pIconColors = new JPanel(); 303 pIconColors.setLayout(new GridBagLayout()); 304 pIconColors.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("BorderLayoutIconColors"))); 305 306 textIconNorth.setLabelFor(northComboBox); 307 addItem(pIconColors, textIconNorth, 0, 4); 308 addItemLeft(pIconColors, northComboBox, 1, 4); 309 textIconSouth.setLabelFor(southComboBox); 310 addItem(pIconColors, textIconSouth, 0, 5); 311 addItemLeft(pIconColors, southComboBox, 1, 5); 312 textIconEast.setLabelFor(eastComboBox); 313 addItem(pIconColors, textIconEast, 0, 8); 314 addItemLeft(pIconColors, eastComboBox, 1, 8); 315 textIconWest.setLabelFor(westComboBox); 316 addItem(pIconColors, textIconWest, 0, 9); 317 addItemLeft(pIconColors, westComboBox, 1, 9); 318 textIconLocal.setLabelFor(localComboBox); 319 addItem(pIconColors, textIconLocal, 0, 10); 320 addItemLeft(pIconColors, localComboBox, 1, 10); 321 textIconTerminate.setLabelFor(terminateComboBox); 322 addItem(pIconColors, textIconTerminate, 0, 11); 323 addItemLeft(pIconColors, terminateComboBox, 1, 11); 324 325 pIcon.add(pIconColors); 326 327 loadIconComboBox(northComboBox); 328 loadIconComboBox(southComboBox); 329 loadIconComboBox(eastComboBox); 330 loadIconComboBox(westComboBox); 331 loadIconComboBox(localComboBox); 332 loadIconComboBox(terminateComboBox); 333 northComboBox.setSelectedItem(Setup.getTrainIconColorNorth()); 334 southComboBox.setSelectedItem(Setup.getTrainIconColorSouth()); 335 eastComboBox.setSelectedItem(Setup.getTrainIconColorEast()); 336 westComboBox.setSelectedItem(Setup.getTrainIconColorWest()); 337 localComboBox.setSelectedItem(Setup.getTrainIconColorLocal()); 338 terminateComboBox.setSelectedItem(Setup.getTrainIconColorTerminate()); 339 340 // comment 341 JPanel pC = new JPanel(); 342 pC.setLayout(new GridBagLayout()); 343 pC.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Comment"))); 344 JScrollPane commentScroller = new JScrollPane(commentTextArea, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, 345 JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); 346 addItem(pC, commentScroller, 0, 0); 347 348 pIcon.add(pC); 349 350 // row 15 351 JPanel pControl = new JPanel(); 352 pControl.setLayout(new GridBagLayout()); 353 addItem(pControl, restoreButton, 0, 9); 354 addItem(pControl, backupButton, 1, 9); 355 addItem(pControl, saveButton, 3, 9); 356 357 add(panelPane); 358 add(options); 359 add(pIconPane); 360 add(pControl); 361 362 // set up buttons 363 addButtonAction(backupButton); 364 addButtonAction(restoreButton); 365 addButtonAction(saveButton); 366 addCheckBoxAction(eastCheckBox); 367 addCheckBoxAction(northCheckBox); 368 369 // now provide the railroad name 370 railroadNameTextField.setText(Setup.getRailroadName()); 371 } 372 373 // Save, Delete, Add buttons 374 @Override 375 public void buttonActionPerformed(java.awt.event.ActionEvent ae) { 376 if (ae.getSource() == backupButton) { 377 // Backup and Restore dialogs are now modal. so no need to check for an existing 378 // instance 379 BackupDialog bd = new BackupDialog(); 380 bd.pack(); 381 bd.setLocationRelativeTo(null); 382 bd.setVisible(true); 383 } 384 if (ae.getSource() == restoreButton) { 385 RestoreDialog rd = new RestoreDialog(); 386 rd.pack(); 387 rd.setLocationRelativeTo(null); 388 rd.setVisible(true); 389 } 390 if (ae.getSource() == saveButton) { 391 save(); 392 } 393 } 394 395 @SuppressFBWarnings(value = "BC_UNCONFIRMED_CAST_OF_RETURN_VALUE", justification = "checks for instance of OperationsSetupFrame") 396 private void save() { 397 // check input fields 398 int maxTrainLength; 399 try { 400 maxTrainLength = Integer.parseInt(maxLengthTextField.getText()); 401 } catch (NumberFormatException e) { 402 JOptionPane.showMessageDialog(this, Bundle.getMessage("MaxLength"), Bundle.getMessage("CanNotAcceptNumber"), 403 JOptionPane.ERROR_MESSAGE); 404 return; 405 } 406 // warn about train length being too short 407 if (maxTrainLength != Setup.getMaxTrainLength()) { 408 if (maxTrainLength < 500 && Setup.getLengthUnit().equals(Setup.FEET) || 409 maxTrainLength < 160 && Setup.getLengthUnit().equals(Setup.METER)) { 410 JOptionPane.showMessageDialog(this, 411 MessageFormat.format(Bundle.getMessage("LimitTrainLength"), 412 new Object[] { maxTrainLength, Setup.getLengthUnit().toLowerCase() }), 413 Bundle.getMessage("WarningTooShort"), JOptionPane.WARNING_MESSAGE); 414 } 415 } 416 417 try { 418 Integer.parseInt(maxEngineSizeTextField.getText()); 419 } catch (NumberFormatException e) { 420 JOptionPane.showMessageDialog(this, Bundle.getMessage("MaxEngine"), Bundle.getMessage("CanNotAcceptNumber"), 421 JOptionPane.ERROR_MESSAGE); 422 return; 423 } 424 425 try { 426 Integer.parseInt(hptTextField.getText()); 427 } catch (NumberFormatException e) { 428 JOptionPane.showMessageDialog(this, Bundle.getMessage("HPT"), Bundle.getMessage("CanNotAcceptNumber"), 429 JOptionPane.ERROR_MESSAGE); 430 return; 431 } 432 433 try { 434 Integer.parseInt(switchTimeTextField.getText()); 435 } catch (NumberFormatException e) { 436 JOptionPane.showMessageDialog(this, Bundle.getMessage("MoveTime"), Bundle.getMessage("CanNotAcceptNumber"), 437 JOptionPane.ERROR_MESSAGE); 438 return; 439 } 440 441 try { 442 Integer.parseInt(travelTimeTextField.getText()); 443 } catch (NumberFormatException e) { 444 JOptionPane.showMessageDialog(this, Bundle.getMessage("TravelTime"), 445 Bundle.getMessage("CanNotAcceptNumber"), JOptionPane.ERROR_MESSAGE); 446 return; 447 } 448 449 try { 450 if (!yearTextField.getText().trim().isEmpty()) { 451 Integer.parseInt(yearTextField.getText().trim()); 452 } 453 } catch (NumberFormatException e) { 454 JOptionPane.showMessageDialog(this, Bundle.getMessage("BorderLayoutYearModeled"), 455 Bundle.getMessage("CanNotAcceptNumber"), JOptionPane.ERROR_MESSAGE); 456 return; 457 } 458 459 // if max train length has changed, check routes 460 checkRoutes(); 461 462 // set car types 463 if (typeDesc.isSelected() && !Setup.getCarTypes().equals(Setup.DESCRIPTIVE) || 464 typeAAR.isSelected() && !Setup.getCarTypes().equals(Setup.AAR)) { 465 466 // backup files before changing car type descriptions 467 AutoBackup backup = new AutoBackup(); 468 try { 469 backup.autoBackup(); 470 } catch (IOException ex) { 471 UnexpectedExceptionContext context = new UnexpectedExceptionContext(ex, 472 "Auto backup before changing Car types"); // NOI18N 473 new ExceptionDisplayFrame(context, null).setVisible(true); 474 } 475 476 if (typeDesc.isSelected()) { 477 InstanceManager.getDefault(CarTypes.class).changeDefaultNames(Setup.DESCRIPTIVE); 478 Setup.setCarTypes(Setup.DESCRIPTIVE); 479 } else { 480 InstanceManager.getDefault(CarTypes.class).changeDefaultNames(Setup.AAR); 481 Setup.setCarTypes(Setup.AAR); 482 } 483 484 // save all the modified files 485 OperationsXml.save(); 486 } 487 // main menu enabled? 488 Setup.setMainMenuEnabled(mainMenuCheckBox.isSelected()); 489 Setup.setCloseWindowOnSaveEnabled(closeOnSaveCheckBox.isSelected()); 490 Setup.setAutoSaveEnabled(autoSaveCheckBox.isSelected()); 491 Setup.setAutoBackupEnabled(autoBackupCheckBox.isSelected()); 492 493 // add panel name to setup 494 Setup.setPanelName(panelTextField.getText()); 495 496 // train Icon X&Y 497 Setup.setTrainIconCordEnabled(iconCheckBox.isSelected()); 498 Setup.setTrainIconAppendEnabled(appendCheckBox.isSelected()); 499 500 // save train icon colors 501 Setup.setTrainIconColorNorth((String) northComboBox.getSelectedItem()); 502 Setup.setTrainIconColorSouth((String) southComboBox.getSelectedItem()); 503 Setup.setTrainIconColorEast((String) eastComboBox.getSelectedItem()); 504 Setup.setTrainIconColorWest((String) westComboBox.getSelectedItem()); 505 Setup.setTrainIconColorLocal((String) localComboBox.getSelectedItem()); 506 Setup.setTrainIconColorTerminate((String) terminateComboBox.getSelectedItem()); 507 // set train direction 508 int direction = 0; 509 if (eastCheckBox.isSelected()) { 510 direction = Setup.EAST + Setup.WEST; 511 } 512 if (northCheckBox.isSelected()) { 513 direction += Setup.NORTH + Setup.SOUTH; 514 } 515 Setup.setTrainDirection(direction); 516 Setup.setMaxNumberEngines(Integer.parseInt(maxEngineSizeTextField.getText())); 517 Setup.setHorsePowerPerTon(Integer.parseInt(hptTextField.getText())); 518 // set switch time 519 Setup.setSwitchTime(Integer.parseInt(switchTimeTextField.getText())); 520 // set travel time 521 Setup.setTravelTime(Integer.parseInt(travelTimeTextField.getText())); 522 // set scale 523 Setup.setScale(getSelectedScale()); 524 525 if (!railroadNameTextField.getText() 526 .equals(InstanceManager.getDefault(WebServerPreferences.class).getRailroadName())) { 527 Setup.setRailroadName(railroadNameTextField.getText()); 528 int results = JOptionPane.showConfirmDialog(this, 529 MessageFormat.format(Bundle.getMessage("ChangeRailroadName"), 530 new Object[] { InstanceManager.getDefault(WebServerPreferences.class).getRailroadName(), 531 Setup.getRailroadName() }), 532 Bundle.getMessage("ChangeJMRIRailroadName"), JOptionPane.YES_NO_OPTION); 533 if (results == JOptionPane.YES_OPTION) { 534 InstanceManager.getDefault(WebServerPreferences.class).setRailroadName(Setup.getRailroadName()); 535 InstanceManager.getDefault(WebServerPreferences.class).save(); 536 } 537 } 538 // Set Unit of Length 539 if (feetUnit.isSelected()) { 540 Setup.setLengthUnit(Setup.FEET); 541 } 542 if (meterUnit.isSelected()) { 543 Setup.setLengthUnit(Setup.METER); 544 } 545 Setup.setYearModeled(yearTextField.getText().trim()); 546 // set max train length 547 Setup.setMaxTrainLength(Integer.parseInt(maxLengthTextField.getText())); 548 Setup.setComment(commentTextArea.getText()); 549 550 InstanceManager.getDefault(OperationsSetupXml.class).writeOperationsFile(); 551 if (Setup.isCloseWindowOnSaveEnabled() && this.getTopLevelAncestor() instanceof OperationsSettingsFrame) { 552 ((OperationsSettingsFrame) this.getTopLevelAncestor()).dispose(); 553 } 554 } 555 556 // if max train length has changed, check routes 557 private void checkRoutes() { 558 int maxLength = Integer.parseInt(maxLengthTextField.getText()); 559 if (maxLength > Setup.getMaxTrainLength()) { 560 JOptionPane.showMessageDialog(this, Bundle.getMessage("RouteLengthNotModified"), 561 MessageFormat.format(Bundle.getMessage("MaxTrainLengthIncreased"), 562 new Object[] { maxLength, Setup.getLengthUnit().toLowerCase() }), 563 JOptionPane.INFORMATION_MESSAGE); 564 } 565 if (maxLength < Setup.getMaxTrainLength()) { 566 StringBuilder sb = new StringBuilder(); 567 List<Route> routes = InstanceManager.getDefault(RouteManager.class).getRoutesByNameList(); 568 int count = 0; 569 for (Route route : routes) { 570 for (RouteLocation rl : route.getLocationsBySequenceList()) { 571 if (rl.getMaxTrainLength() > maxLength) { 572 String s = MessageFormat.format(Bundle.getMessage("RouteMaxLengthExceeds"), 573 new Object[] { route.getName(), rl.getName(), rl.getMaxTrainLength(), maxLength }); 574 log.info(s); 575 sb.append(s).append(NEW_LINE); 576 count++; 577 break; 578 } 579 } 580 // maximum of 20 route warnings 581 if (count > 20) { 582 sb.append(Bundle.getMessage("More")).append(NEW_LINE); 583 break; 584 } 585 } 586 if (sb.length() > 0) { 587 JOptionPane.showMessageDialog(this, sb.toString(), Bundle.getMessage("YouNeedToAdjustRoutes"), 588 JOptionPane.WARNING_MESSAGE); 589 if (JOptionPane.showConfirmDialog(this, 590 MessageFormat.format(Bundle.getMessage("ChangeMaximumTrainDepartureLength"), 591 new Object[] { maxLength }), 592 Bundle.getMessage("ModifyAllRoutes"), JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) { 593 routes.stream().forEach((route) -> { 594 route.getLocationsBySequenceList().stream().filter((rl) -> (rl.getMaxTrainLength() > maxLength)) 595 .map((rl) -> { 596 log.debug("Setting route ({}) routeLocation ({}) max traim length to {}", 597 route.getName(), rl.getName(), maxLength); // NOI18N 598 return rl; 599 }).forEach((rl) -> { 600 rl.setMaxTrainLength(maxLength); 601 }); 602 }); 603 // save the route changes 604 InstanceManager.getDefault(RouteManagerXml.class).writeOperationsFile(); 605 } 606 } 607 } 608 } 609 610 @Override 611 public void checkBoxActionPerformed(java.awt.event.ActionEvent ae) { 612 if (ae.getSource() == northCheckBox) { 613 if (!northCheckBox.isSelected()) { 614 eastCheckBox.setSelected(true); 615 } 616 } 617 if (ae.getSource() == eastCheckBox) { 618 if (!eastCheckBox.isSelected()) { 619 northCheckBox.setSelected(true); 620 } 621 } 622 int direction = 0; 623 if (eastCheckBox.isSelected()) { 624 direction += Setup.EAST; 625 } 626 if (northCheckBox.isSelected()) { 627 direction += Setup.NORTH; 628 } 629 setDirectionCheckBox(direction); 630 } 631 632 private void setScale() { 633 switch (Setup.getScale()) { 634 case Setup.Z_SCALE: 635 scaleZ.setSelected(true); 636 break; 637 case Setup.N_SCALE: 638 scaleN.setSelected(true); 639 break; 640 case Setup.TT_SCALE: 641 scaleTT.setSelected(true); 642 break; 643 case Setup.HOn3_SCALE: 644 scaleHOn3.setSelected(true); 645 break; 646 case Setup.OO_SCALE: 647 scaleOO.setSelected(true); 648 break; 649 case Setup.HO_SCALE: 650 scaleHO.setSelected(true); 651 break; 652 case Setup.Sn3_SCALE: 653 scaleSn3.setSelected(true); 654 break; 655 case Setup.S_SCALE: 656 scaleS.setSelected(true); 657 break; 658 case Setup.On3_SCALE: 659 scaleOn3.setSelected(true); 660 break; 661 case Setup.O_SCALE: 662 scaleO.setSelected(true); 663 break; 664 case Setup.G_SCALE: 665 scaleG.setSelected(true); 666 break; 667 default: 668 log.error("Unknown scale"); 669 } 670 } 671 672 private int getSelectedScale() { 673 int scale = 0; 674 if (scaleZ.isSelected()) { 675 scale = Setup.Z_SCALE; 676 } 677 if (scaleN.isSelected()) { 678 scale = Setup.N_SCALE; 679 } 680 if (scaleTT.isSelected()) { 681 scale = Setup.TT_SCALE; 682 } 683 if (scaleOO.isSelected()) { 684 scale = Setup.OO_SCALE; 685 } 686 if (scaleHOn3.isSelected()) { 687 scale = Setup.HOn3_SCALE; 688 } 689 if (scaleHO.isSelected()) { 690 scale = Setup.HO_SCALE; 691 } 692 if (scaleSn3.isSelected()) { 693 scale = Setup.Sn3_SCALE; 694 } 695 if (scaleS.isSelected()) { 696 scale = Setup.S_SCALE; 697 } 698 if (scaleOn3.isSelected()) { 699 scale = Setup.On3_SCALE; 700 } 701 if (scaleO.isSelected()) { 702 scale = Setup.O_SCALE; 703 } 704 if (scaleG.isSelected()) { 705 scale = Setup.G_SCALE; 706 } 707 return scale; 708 } 709 710 private void setCarTypes() { 711 typeDesc.setSelected(Setup.getCarTypes().equals(Setup.DESCRIPTIVE)); 712 typeAAR.setSelected(Setup.getCarTypes().equals(Setup.AAR)); 713 } 714 715 private void setDirectionCheckBox(int direction) { 716 eastCheckBox.setSelected((direction & Setup.EAST) == Setup.EAST); 717 textIconEast.setVisible((direction & Setup.EAST) == Setup.EAST); 718 eastComboBox.setVisible((direction & Setup.EAST) == Setup.EAST); 719 textIconWest.setVisible((direction & Setup.EAST) == Setup.EAST); 720 westComboBox.setVisible((direction & Setup.EAST) == Setup.EAST); 721 northCheckBox.setSelected((direction & Setup.NORTH) == Setup.NORTH); 722 textIconNorth.setVisible((direction & Setup.NORTH) == Setup.NORTH); 723 northComboBox.setVisible((direction & Setup.NORTH) == Setup.NORTH); 724 textIconSouth.setVisible((direction & Setup.NORTH) == Setup.NORTH); 725 southComboBox.setVisible((direction & Setup.NORTH) == Setup.NORTH); 726 } 727 728 private void setLengthUnit() { 729 feetUnit.setSelected(Setup.getLengthUnit().equals(Setup.FEET)); 730 meterUnit.setSelected(Setup.getLengthUnit().equals(Setup.METER)); 731 } 732 733 private void loadIconComboBox(JComboBox<String> comboBox) { 734 for (String color : LocoIcon.getLocoColors()) { 735 comboBox.addItem(color); 736 } 737 } 738 739 @Override 740 public void propertyChange(java.beans.PropertyChangeEvent e) { 741 log.debug("propertyChange ({}), new: ({})", e.getPropertyName(), e.getNewValue()); 742 } 743 744 @Override 745 public String getTabbedPreferencesTitle() { 746 return Bundle.getMessage("TitleOperationsSetup"); 747 } 748 749 @Override 750 public String getPreferencesTooltip() { 751 return null; 752 } 753 754 @Override 755 public void savePreferences() { 756 this.save(); 757 } 758 759 @Override 760 public boolean isDirty() { 761 if (// set car types 762 (typeDesc.isSelected() && !Setup.getCarTypes().equals(Setup.DESCRIPTIVE)) || 763 (typeAAR.isSelected() && !Setup.getCarTypes().equals(Setup.AAR)) 764 // main menu enabled? 765 || 766 Setup.isMainMenuEnabled() != mainMenuCheckBox.isSelected() || 767 Setup.isCloseWindowOnSaveEnabled() != closeOnSaveCheckBox.isSelected() || 768 Setup.isAutoSaveEnabled() != autoSaveCheckBox.isSelected() || 769 Setup.isAutoBackupEnabled() != autoBackupCheckBox.isSelected() 770 // add panel name to setup 771 || 772 !Setup.getPanelName().equals(panelTextField.getText()) 773 // train Icon X&Y 774 || 775 Setup.isTrainIconCordEnabled() != iconCheckBox.isSelected() || 776 Setup.isTrainIconAppendEnabled() != appendCheckBox.isSelected() 777 // train Icon X&Y 778 || 779 Setup.isTrainIconCordEnabled() != iconCheckBox.isSelected() || 780 Setup.isTrainIconAppendEnabled() != appendCheckBox.isSelected() 781 // save train icon colors 782 || 783 !Setup.getTrainIconColorNorth().equals(northComboBox.getSelectedItem()) || 784 !Setup.getTrainIconColorSouth().equals(southComboBox.getSelectedItem()) || 785 !Setup.getTrainIconColorEast().equals(eastComboBox.getSelectedItem()) || 786 !Setup.getTrainIconColorWest().equals(westComboBox.getSelectedItem()) || 787 !Setup.getTrainIconColorLocal().equals(localComboBox.getSelectedItem()) || 788 !Setup.getTrainIconColorTerminate().equals(terminateComboBox.getSelectedItem()) || 789 Setup.getMaxNumberEngines() != Integer.parseInt(maxEngineSizeTextField.getText()) || 790 Setup.getHorsePowerPerTon() != Integer.parseInt(hptTextField.getText()) 791 // switch time 792 || 793 Setup.getSwitchTime() != Integer.parseInt(switchTimeTextField.getText()) 794 // travel time 795 || 796 Setup.getTravelTime() != Integer.parseInt(travelTimeTextField.getText()) || 797 !Setup.getYearModeled().equals(yearTextField.getText().trim()) || 798 Setup.getMaxTrainLength() != Integer.parseInt(maxLengthTextField.getText()) || 799 !Setup.getComment().equals(this.commentTextArea.getText())) { 800 return true; 801 } 802 803 // set train direction 804 int direction = 0; 805 if (eastCheckBox.isSelected()) { 806 direction = Setup.EAST + Setup.WEST; 807 } 808 if (northCheckBox.isSelected()) { 809 direction += Setup.NORTH + Setup.SOUTH; 810 } 811 // get scale 812 int scale = getSelectedScale(); 813 String lengthUnit = ""; 814 // Set Unit of Length 815 if (feetUnit.isSelected()) { 816 lengthUnit = Setup.FEET; 817 } 818 if (meterUnit.isSelected()) { 819 lengthUnit = Setup.METER; 820 } 821 return (Setup.getTrainDirection() != direction || 822 Setup.getScale() != scale || 823 !Setup.getRailroadName().equals(this.railroadNameTextField.getText()) || 824 !Setup.getLengthUnit().equals(lengthUnit)); 825 } 826}