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