001package jmri.jmrit.dispatcher; 002 003import java.awt.BorderLayout; 004import java.awt.Component; 005import java.awt.Container; 006import java.awt.Dimension; 007import java.awt.FlowLayout; 008import java.awt.event.ActionEvent; 009import java.awt.event.ActionListener; 010import java.awt.event.ItemEvent; 011import java.awt.event.ItemListener; 012import java.util.ArrayList; 013import java.util.HashSet; 014import java.util.List; 015import java.util.Set; 016 017import javax.swing.BorderFactory; 018import javax.swing.BoxLayout; 019import javax.swing.ButtonGroup; 020import javax.swing.JButton; 021import javax.swing.JCheckBox; 022import javax.swing.JComboBox; 023import javax.swing.JLabel; 024import javax.swing.JPanel; 025import javax.swing.JRadioButton; 026import javax.swing.JScrollPane; 027import javax.swing.JSeparator; 028import javax.swing.JSpinner; 029import javax.swing.JTextField; 030import javax.swing.ScrollPaneConstants; 031import javax.swing.SpinnerNumberModel; 032import javax.swing.event.ChangeEvent; 033import javax.swing.event.ChangeListener; 034import javax.swing.table.DefaultTableModel; 035import javax.swing.table.TableCellRenderer; 036import javax.swing.table.TableColumnModel; 037 038import jmri.Block; 039import jmri.jmrit.display.layoutEditor.LayoutBlock; 040import jmri.jmrit.display.layoutEditor.LayoutBlockManager; 041import jmri.InstanceManager; 042import jmri.Sensor; 043import jmri.Transit; 044import jmri.TransitManager; 045import jmri.jmrit.dispatcher.ActiveTrain.TrainDetection; 046import jmri.jmrit.dispatcher.ActiveTrain.TrainLengthUnits; 047import jmri.jmrit.dispatcher.DispatcherFrame.TrainsFrom; 048import jmri.jmrit.operations.trains.Train; 049import jmri.jmrit.operations.trains.TrainManager; 050import jmri.jmrit.roster.RosterEntry; 051import jmri.jmrit.roster.swing.RosterEntryComboBox; 052import jmri.swing.NamedBeanComboBox; 053import jmri.util.JmriJFrame; 054import jmri.util.swing.JComboBoxUtil; 055import jmri.util.swing.JmriJOptionPane; 056import javax.swing.JTable; 057/** 058 * Displays the Activate New Train dialog and processes information entered 059 * there. 060 * <p> 061 * This module works with Dispatcher, which initiates the display of the dialog. 062 * Dispatcher also creates the ActiveTrain. 063 * <p> 064 * This file is part of JMRI. 065 * <p> 066 * JMRI is open source software; you can redistribute it and/or modify it under 067 * the terms of version 2 of the GNU General Public License as published by the 068 * Free Software Foundation. See the "COPYING" file for a copy of this license. 069 * <p> 070 * JMRI is distributed in the hope that it will be useful, but WITHOUT ANY 071 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 072 * A PARTICULAR PURPOSE. See the GNU General Public License for more details. 073 * 074 * @author Dave Duchamp Copyright (C) 2009 075 */ 076public class ActivateTrainFrame extends JmriJFrame { 077 078 public ActivateTrainFrame(DispatcherFrame d) { 079 super(true,true); 080 _dispatcher = d; 081 _tiFile = new TrainInfoFile(); 082 } 083 084 // operational instance variables 085 private DispatcherFrame _dispatcher = null; 086 private TrainInfoFile _tiFile = null; 087 private final TransitManager _TransitManager = InstanceManager.getDefault(jmri.TransitManager.class); 088 private String _trainInfoName = ""; 089 090 // initiate train window variables 091 private Transit selectedTransit = null; 092 //private String selectedTrain = ""; 093 private JmriJFrame initiateFrame = null; 094 private Container initiatePane = null; 095 private final jmri.swing.NamedBeanComboBox<Transit> transitSelectBox = new jmri.swing.NamedBeanComboBox<>(_TransitManager); 096 private final JComboBox<Object> trainSelectBox = new JComboBox<>(); 097 // private final List<RosterEntry> trainBoxList = new ArrayList<>(); 098 private RosterEntryComboBox rosterComboBox = null; 099 private final JLabel trainFieldLabel = new JLabel(Bundle.getMessage("TrainBoxLabel") + ":"); 100 private final JTextField trainNameField = new JTextField(10); 101 private final JLabel dccAddressFieldLabel = new JLabel(" " + Bundle.getMessage("DccAddressFieldLabel") + ":"); 102 private final JSpinner dccAddressSpinner = new JSpinner(new SpinnerNumberModel(3, 1, 9999, 1)); 103 private final JCheckBox inTransitBox = new JCheckBox(Bundle.getMessage("TrainInTransit")); 104 private final JComboBox<String> startingBlockBox = new JComboBox<>(); 105 private final JComboBox<String> viaBlockBox = new JComboBox<>(); 106 private final JLabel viaBlockBoxLabel = new JLabel(Bundle.getMessage("ViaBlockBoxLabel")); 107 private List<Block> startingBlockBoxList = new ArrayList<>(); 108 private List<Block> viaBlockBoxList = new ArrayList<>(); 109 private List<Integer> startingBlockSeqList = new ArrayList<>(); 110 private final JComboBox<String> destinationBlockBox = new JComboBox<>(); 111 112 private List<Block> destinationBlockBoxList = new ArrayList<>(); 113 private List<Integer> destinationBlockSeqList = new ArrayList<>(); 114 private JButton addNewTrainButton = null; 115 private JButton loadButton = null; 116 private JButton saveButton = null; 117 private JButton saveAsTemplateButton = null; 118 private JButton deleteButton = null; 119 private final JCheckBox autoRunBox = new JCheckBox(Bundle.getMessage("AutoRun")); 120 private final JCheckBox loadAtStartupBox = new JCheckBox(Bundle.getMessage("LoadAtStartup")); 121 122 private final JRadioButton radioTrainsFromRoster = new JRadioButton(Bundle.getMessage("TrainsFromRoster")); 123 private final JRadioButton radioTrainsFromOps = new JRadioButton(Bundle.getMessage("TrainsFromTrains")); 124 private final JRadioButton radioTrainsFromUser = new JRadioButton(Bundle.getMessage("TrainsFromUser")); 125 private final JRadioButton radioTrainsFromSetLater = new JRadioButton(Bundle.getMessage("TrainsFromSetLater")); 126 private final ButtonGroup trainsFromButtonGroup = new ButtonGroup(); 127 128 private final JRadioButton radioTransitsPredefined = new JRadioButton(Bundle.getMessage("TransitsPredefined")); 129 private final JRadioButton radioTransitsAdHoc = new JRadioButton(Bundle.getMessage("TransitsAdHoc")); 130 private final ButtonGroup transitsFromButtonGroup = new ButtonGroup(); 131 //private final JCheckBox adHocCloseLoop = new JCheckBox(Bundle.getMessage("TransitCloseLoop")); 132 133 private final JRadioButton allocateBySafeRadioButton = new JRadioButton(Bundle.getMessage("ToSafeSections")); 134 private final JRadioButton allocateAllTheWayRadioButton = new JRadioButton(Bundle.getMessage("AsFarAsPos")); 135 private final JRadioButton allocateNumberOfBlocks = new JRadioButton(Bundle.getMessage("NumberOfBlocks") + ":"); 136 private final ButtonGroup allocateMethodButtonGroup = new ButtonGroup(); 137 private final JSpinner allocateCustomSpinner = new JSpinner(new SpinnerNumberModel(3, 1, 100, 1)); 138 private final JCheckBox terminateWhenDoneBox = new JCheckBox(Bundle.getMessage("TerminateWhenDone")); 139 private final JPanel terminateWhenDoneDetails = new JPanel(); 140 private final JComboBox<String> nextTrain = new JComboBox<>(); 141 private final JLabel nextTrainLabel = new JLabel(Bundle.getMessage("TerminateWhenDoneNextTrain")); 142 private final JSpinner prioritySpinner = new JSpinner(new SpinnerNumberModel(5, 0, 100, 1)); 143 private final JCheckBox resetWhenDoneBox = new JCheckBox(Bundle.getMessage("ResetWhenDone")); 144 private final JCheckBox reverseAtEndBox = new JCheckBox(Bundle.getMessage("ReverseAtEnd")); 145 146 int delayedStartInt[] = new int[]{ActiveTrain.NODELAY, ActiveTrain.TIMEDDELAY, ActiveTrain.SENSORDELAY}; 147 String delayedStartString[] = new String[]{Bundle.getMessage("DelayedStartNone"), Bundle.getMessage("DelayedStartTimed"), Bundle.getMessage("DelayedStartSensor")}; 148 149 private final JComboBox<String> reverseDelayedRestartType = new JComboBox<>(delayedStartString); 150 private final JLabel delayReverseReStartLabel = new JLabel(Bundle.getMessage("DelayRestart")); 151 private final JLabel delayReverseReStartSensorLabel = new JLabel(Bundle.getMessage("RestartSensor")); 152 private final JCheckBox delayReverseResetSensorBox = new JCheckBox(Bundle.getMessage("ResetRestartSensor")); 153 private final NamedBeanComboBox<Sensor> delayReverseReStartSensor = new NamedBeanComboBox<>(jmri.InstanceManager.sensorManagerInstance()); 154 private final JSpinner delayReverseMinSpinner = new JSpinner(new SpinnerNumberModel(0, 0, 1000, 1)); 155 private final JLabel delayReverseMinLabel = new JLabel(Bundle.getMessage("RestartTimed")); 156 157 private final JCheckBox resetStartSensorBox = new JCheckBox(Bundle.getMessage("ResetStartSensor")); 158 private final JComboBox<String> delayedStartBox = new JComboBox<>(delayedStartString); 159 private final JLabel delayedReStartLabel = new JLabel(Bundle.getMessage("DelayRestart")); 160 private final JLabel delayReStartSensorLabel = new JLabel(Bundle.getMessage("RestartSensor")); 161 private final JCheckBox resetRestartSensorBox = new JCheckBox(Bundle.getMessage("ResetRestartSensor")); 162 private final JComboBox<String> delayedReStartBox = new JComboBox<>(delayedStartString); 163 private final NamedBeanComboBox<Sensor> delaySensor = new NamedBeanComboBox<>(jmri.InstanceManager.sensorManagerInstance()); 164 private final NamedBeanComboBox<Sensor> delayReStartSensor = new NamedBeanComboBox<>(jmri.InstanceManager.sensorManagerInstance()); 165 166 private final JSpinner departureHrSpinner = new JSpinner(new SpinnerNumberModel(8, 0, 23, 1)); 167 private final JSpinner departureMinSpinner = new JSpinner(new SpinnerNumberModel(0, 0, 59, 1)); 168 private final JLabel departureTimeLabel = new JLabel(Bundle.getMessage("DepartureTime")); 169 private final JLabel departureSepLabel = new JLabel(":"); 170 171 private final JSpinner delayMinSpinner = new JSpinner(new SpinnerNumberModel(0, 0, 1000, 1)); 172 private final JLabel delayMinLabel = new JLabel(Bundle.getMessage("RestartTimed")); 173 174 private final JComboBox<String> trainTypeBox = new JComboBox<>(); 175 // Note: See also items related to automatically running trains near the end of this module 176 177 boolean transitsFromSpecificBlock = false; 178 179 private TrainInfo trainInfo; 180 181 private final String nameOfTemplateFile="TrainInfoDefaultTemplate.xml"; 182 // to be added and removed. 183 ActionListener viaBlockBoxListener = new ActionListener() { 184 @Override 185 public void actionPerformed(ActionEvent e) { 186 handleViaBlockSelectionChanged(e); 187 } 188 }; 189 190 /** 191 * Open up a new train window for a given roster entry located in a specific 192 * block. 193 * 194 * @param e the action event triggering the new window 195 * @param re the roster entry to open the new window for 196 * @param b the block where the train is located 197 */ 198 public void initiateTrain(ActionEvent e, RosterEntry re, Block b) { 199 initiateTrain(e); 200 if (trainInfo.getTrainsFrom() == TrainsFrom.TRAINSFROMROSTER && re != null) { 201 setRosterComboBox(rosterComboBox, re.getId()); 202 //Add in some bits of code as some point to filter down the transits that can be used. 203 } 204 if (b != null && selectedTransit != null) { 205 List<Transit> transitList = _TransitManager.getListUsingBlock(b); 206 List<Transit> transitEntryList = _TransitManager.getListEntryBlock(b); 207 for (Transit t : transitEntryList) { 208 if (!transitList.contains(t)) { 209 transitList.add(t); 210 } 211 } 212 transitsFromSpecificBlock = true; 213 initializeFreeTransitsCombo(transitList); 214 List<Block> tmpBlkList = new ArrayList<>(); 215 if (selectedTransit.getEntryBlocksList().contains(b)) { 216 tmpBlkList = selectedTransit.getEntryBlocksList(); 217 inTransitBox.setSelected(false); 218 } else if (selectedTransit.containsBlock(b)) { 219 tmpBlkList = selectedTransit.getInternalBlocksList(); 220 inTransitBox.setSelected(true); 221 } 222 List<Integer> tmpSeqList = selectedTransit.getBlockSeqList(); 223 for (int i = 0; i < tmpBlkList.size(); i++) { 224 if (tmpBlkList.get(i) == b) { 225 setComboBox(startingBlockBox, getBlockName(b) + "-" + tmpSeqList.get(i)); 226 break; 227 } 228 } 229 } 230 } 231 232 /** 233 * Displays a window that allows a new ActiveTrain to be activated. 234 * <p> 235 * Called by Dispatcher in response to the dispatcher clicking the New Train 236 * button. 237 * 238 * @param e the action event triggering the window display 239 */ 240 protected void initiateTrain(ActionEvent e) { 241 // set Dispatcher defaults 242 // create window if needed 243 // if template exists open it 244 try { 245 trainInfo = _tiFile.readTrainInfo(nameOfTemplateFile); 246 if (trainInfo == null) { 247 trainInfo = new TrainInfo(); 248 } 249 } catch (java.io.IOException ioe) { 250 log.error("IO Exception when reading train info file", ioe); 251 return; 252 } catch (org.jdom2.JDOMException jde) { 253 log.error("JDOM Exception when reading train info file", jde); 254 return; 255 } 256 257 if (initiateFrame == null) { 258 initiateFrame = this; 259 initiateFrame.setTitle(Bundle.getMessage("AddTrainTitle")); 260 initiateFrame.addHelpMenu("package.jmri.jmrit.dispatcher.NewTrain", true); 261 initiatePane = initiateFrame.getContentPane(); 262 initiatePane.setLayout(new BoxLayout(initiatePane, BoxLayout.Y_AXIS)); 263 264 // add buttons to load and save train information 265 JPanel hdr = new JPanel(); 266 hdr.add(loadButton = new JButton(Bundle.getMessage("LoadButton"))); 267 loadButton.addActionListener(new ActionListener() { 268 @Override 269 public void actionPerformed(ActionEvent e) { 270 loadTrainInfo(e); 271 } 272 }); 273 loadButton.setToolTipText(Bundle.getMessage("LoadButtonHint")); 274 hdr.add(saveButton = new JButton(Bundle.getMessage("SaveButton"))); 275 saveButton.addActionListener(new ActionListener() { 276 @Override 277 public void actionPerformed(ActionEvent e) { 278 saveTrainInfo(e); 279 } 280 }); 281 saveButton.setToolTipText(Bundle.getMessage("SaveButtonHint")); 282 hdr.add(saveAsTemplateButton = new JButton(Bundle.getMessage("SaveAsTemplateButton"))); 283 saveAsTemplateButton.addActionListener(new ActionListener() { 284 @Override 285 public void actionPerformed(ActionEvent e) { 286 saveTrainInfoAsTemplate(e); 287 } 288 }); 289 saveAsTemplateButton.setToolTipText(Bundle.getMessage("SaveAsTemplateButtonHint")); 290 hdr.add(deleteButton = new JButton(Bundle.getMessage("DeleteButton"))); 291 deleteButton.addActionListener(new ActionListener() { 292 @Override 293 public void actionPerformed(ActionEvent e) { 294 deleteTrainInfo(e); 295 } 296 }); 297 deleteButton.setToolTipText(Bundle.getMessage("DeleteButtonHint")); 298 299 // add items relating to both manually run and automatic trains. 300 301 // Trains From choices. 302 JPanel p1 = new JPanel(); 303 p1.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("TrainsFrom"))); 304 radioTrainsFromRoster.setActionCommand("TRAINSFROMROSTER"); 305 trainsFromButtonGroup.add(radioTrainsFromRoster); 306 radioTrainsFromOps.setActionCommand("TRAINSFROMOPS"); 307 trainsFromButtonGroup.add(radioTrainsFromOps); 308 radioTrainsFromUser.setActionCommand("TRAINSFROMUSER"); 309 trainsFromButtonGroup.add(radioTrainsFromUser); 310 radioTrainsFromSetLater.setActionCommand("TRAINSFROMSETLATER"); 311 trainsFromButtonGroup.add(radioTrainsFromSetLater); 312 p1.add(radioTrainsFromRoster); 313 radioTrainsFromRoster.setToolTipText(Bundle.getMessage("TrainsFromRosterHint")); 314 p1.add(radioTrainsFromOps); 315 radioTrainsFromOps.setToolTipText(Bundle.getMessage("TrainsFromTrainsHint")); 316 p1.add(radioTrainsFromUser); 317 radioTrainsFromUser.setToolTipText(Bundle.getMessage("TrainsFromUserHint")); 318 p1.add(radioTrainsFromSetLater); 319 radioTrainsFromSetLater.setToolTipText(Bundle.getMessage("TrainsFromSetLaterHint")); 320 321 radioTrainsFromOps.addItemListener(new ItemListener() { 322 @Override 323 public void itemStateChanged(ItemEvent e) { 324 if (e.getStateChange() == ItemEvent.SELECTED) { 325 setTrainsFromOptions(TrainsFrom.TRAINSFROMOPS); 326 } 327 } 328 }); 329 radioTrainsFromRoster.addItemListener(new ItemListener() { 330 @Override 331 public void itemStateChanged(ItemEvent e) { 332 if (e.getStateChange() == ItemEvent.SELECTED) { 333 setTrainsFromOptions(TrainsFrom.TRAINSFROMROSTER); 334 } 335 } 336 }); 337 radioTrainsFromUser.addItemListener(new ItemListener() { 338 @Override 339 public void itemStateChanged(ItemEvent e) { 340 if (e.getStateChange() == ItemEvent.SELECTED) { 341 setTrainsFromOptions(TrainsFrom.TRAINSFROMUSER); 342 } 343 } 344 }); 345 radioTrainsFromSetLater.addItemListener(new ItemListener() { 346 @Override 347 public void itemStateChanged(ItemEvent e) { 348 if (e.getStateChange() == ItemEvent.SELECTED) { 349 setTrainsFromOptions(TrainsFrom.TRAINSFROMSETLATER); 350 } 351 } 352 }); 353 initiatePane.add(p1); 354 355 // Select train 356 JPanel p2 = new JPanel(); 357 358 // Dispatcher train name 359 p2.add(trainFieldLabel); 360 p2.add(trainNameField); 361 trainNameField.setToolTipText(Bundle.getMessage("TrainFieldHint")); 362 363 // Roster combo box 364 rosterComboBox = new RosterEntryComboBox(); 365 initializeFreeRosterEntriesCombo(); 366 rosterComboBox.addActionListener(new ActionListener() { 367 @Override 368 public void actionPerformed(ActionEvent e) { 369 handleRosterSelectionChanged(e); 370 } 371 }); 372 p2.add(rosterComboBox); 373 374 // Operations combo box 375 p2.add(trainSelectBox); 376 trainSelectBox.addActionListener(new ActionListener() { 377 @Override 378 public void actionPerformed(ActionEvent e) { 379 handleTrainSelectionChanged(); 380 } 381 }); 382 trainSelectBox.setToolTipText(Bundle.getMessage("TrainBoxHint")); 383 384 // DCC address selector 385 p2.add(dccAddressFieldLabel); 386 p2.add(dccAddressSpinner); 387 dccAddressSpinner.setToolTipText(Bundle.getMessage("DccAddressFieldHint")); 388 389 initiatePane.add(p2); 390 391 // Select transit type 392 JPanel p3 = new JPanel(); 393 p3.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("TransitsFrom"))); 394 radioTransitsPredefined.setActionCommand("USETRANSITS"); 395 transitsFromButtonGroup.add(radioTransitsPredefined); 396 radioTransitsAdHoc.setActionCommand("USEADHOC"); 397 transitsFromButtonGroup.add(radioTransitsAdHoc); 398 p3.add(radioTransitsPredefined); 399 radioTransitsPredefined.setToolTipText(Bundle.getMessage("TransitsPredefinedHint")); 400 p3.add(radioTransitsAdHoc); 401 radioTransitsAdHoc.setToolTipText(Bundle.getMessage("TransitsAdHocHint")); 402 radioTransitsPredefined.addItemListener(new ItemListener() { 403 @Override 404 public void itemStateChanged(ItemEvent e) { 405 if (e.getStateChange() == ItemEvent.SELECTED) { 406 transitSelectBox.setEnabled(true); 407 //adHocCloseLoop.setEnabled(false); 408 inTransitBox.setEnabled(true); 409 handleInTransitClick(); 410 viaBlockBox.setVisible(false); 411 viaBlockBoxLabel.setVisible(false); 412 } 413 } 414 }); 415 radioTransitsAdHoc.addItemListener(new ItemListener() { 416 @Override 417 public void itemStateChanged(ItemEvent e) { 418 if (e.getStateChange() == ItemEvent.SELECTED) { 419 transitSelectBox.setEnabled(false); 420 //adHocCloseLoop.setEnabled(true); 421 inTransitBox.setEnabled(false); 422 inTransitBox.setSelected(true); 423 initializeStartingBlockComboDynamic(); 424 viaBlockBox.setVisible(true); 425 viaBlockBoxLabel.setVisible(true); 426 } 427 } 428 }); 429 430 //p3.add(adHocCloseLoop); 431 //adHocCloseLoop.setToolTipText(Bundle.getMessage("TransitCloseLoopHint")); 432 433 p3.add(new JLabel(Bundle.getMessage("TransitBoxLabel") + " :")); 434 p3.add(transitSelectBox); 435 transitSelectBox.addActionListener(new ActionListener() { 436 @Override 437 public void actionPerformed(ActionEvent e) { 438 handleTransitSelectionChanged(e); 439 } 440 }); 441 transitSelectBox.setToolTipText(Bundle.getMessage("TransitBoxHint")); 442 initiatePane.add(p3); 443 444 // Train in transit 445 JPanel p4 = new JPanel(); 446 p4.add(inTransitBox); 447 inTransitBox.addActionListener(new ActionListener() { 448 @Override 449 public void actionPerformed(ActionEvent e) { 450 handleInTransitClick(); 451 } 452 }); 453 inTransitBox.setToolTipText(Bundle.getMessage("InTransitBoxHint")); 454 initiatePane.add(p4); 455 456 // Starting block, add Via for adhoc transits 457 JPanel p5 = new JPanel(); 458 p5.add(new JLabel(Bundle.getMessage("StartingBlockBoxLabel") + " :")); 459 p5.add(startingBlockBox); 460 startingBlockBox.setToolTipText(Bundle.getMessage("StartingBlockBoxHint")); 461 startingBlockBox.addActionListener(new ActionListener() { 462 @Override 463 public void actionPerformed(ActionEvent e) { 464 handleStartingBlockSelectionChanged(e); 465 } 466 }); 467 p5.add(viaBlockBoxLabel); 468 p5.add(viaBlockBox); 469 viaBlockBox.setToolTipText(Bundle.getMessage("ViaBlockBoxHint")); 470 viaBlockBox.addActionListener(viaBlockBoxListener); 471 initiatePane.add(p5); 472 473 // Destination block 474 JPanel p6 = new JPanel(); 475 p6.add(new JLabel(Bundle.getMessage("DestinationBlockBoxLabel") + ":")); 476 p6.add(destinationBlockBox); 477 destinationBlockBox.setToolTipText(Bundle.getMessage("DestinationBlockBoxHint")); 478 initiatePane.add(p6); 479 480 // Train detection scope 481 JPanel p7 = new JPanel(); 482 p7.add(trainDetectionLabel); 483 initializeTrainDetectionBox(); 484 p7.add(trainDetectionComboBox); 485 trainDetectionComboBox.setToolTipText(Bundle.getMessage("TrainDetectionBoxHint")); 486 initiatePane.add(p7); 487 488 // Allocation method 489 JPanel p8 = new JPanel(); 490 p8.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("AllocateMethodLabel"))); 491 allocateMethodButtonGroup.add(allocateAllTheWayRadioButton); 492 allocateMethodButtonGroup.add(allocateBySafeRadioButton); 493 allocateMethodButtonGroup.add(allocateNumberOfBlocks); 494 p8.add(allocateAllTheWayRadioButton); 495 allocateAllTheWayRadioButton.setToolTipText(Bundle.getMessage("AllocateAllTheWayHint")); 496 p8.add(allocateBySafeRadioButton); 497 allocateBySafeRadioButton.setToolTipText(Bundle.getMessage("AllocateSafeHint")); 498 p8.add(allocateNumberOfBlocks); 499 allocateNumberOfBlocks.setToolTipText(Bundle.getMessage("AllocateMethodHint")); 500 allocateAllTheWayRadioButton.addActionListener(new ActionListener() { 501 @Override 502 public void actionPerformed(ActionEvent e) { 503 handleAllocateAllTheWayButtonChanged(e); 504 } 505 }); 506 allocateBySafeRadioButton.addActionListener(new ActionListener() { 507 @Override 508 public void actionPerformed(ActionEvent e) { 509 handleAllocateBySafeButtonChanged(e); 510 } 511 }); 512 allocateNumberOfBlocks.addActionListener(new ActionListener() { 513 @Override 514 public void actionPerformed(ActionEvent e) { 515 handleAllocateNumberOfBlocksButtonChanged(e); 516 } 517 }); 518 p8.add(allocateCustomSpinner); 519 allocateCustomSpinner.setToolTipText(Bundle.getMessage("AllocateMethodHint")); 520 initiatePane.add(p8); 521 522 // Restart at end 523 JPanel p9 = new JPanel(); 524 p9.add(resetWhenDoneBox); 525 resetWhenDoneBox.addActionListener(new ActionListener() { 526 @Override 527 public void actionPerformed(ActionEvent e) { 528 handleResetWhenDoneClick(e); 529 } 530 }); 531 resetWhenDoneBox.setToolTipText(Bundle.getMessage("ResetWhenDoneBoxHint")); 532 initiatePane.add(p9); 533 534 // Restart using sensor 535 JPanel p9a = new JPanel(); 536 ((FlowLayout) p9a.getLayout()).setVgap(1); 537 p9a.add(delayedReStartLabel); 538 p9a.add(delayedReStartBox); 539 p9a.add(resetRestartSensorBox); 540 resetRestartSensorBox.setToolTipText(Bundle.getMessage("ResetRestartSensorHint")); 541 resetRestartSensorBox.setSelected(true); 542 delayedReStartBox.addActionListener(new ActionListener() { 543 @Override 544 public void actionPerformed(ActionEvent e) { 545 handleResetWhenDoneClick(e); 546 } 547 }); 548 delayedReStartBox.setToolTipText(Bundle.getMessage("DelayedReStartHint")); 549 initiatePane.add(p9a); 550 551 // Restart using timer 552 JPanel p9b = new JPanel(); 553 ((FlowLayout) p9b.getLayout()).setVgap(1); 554 p9b.add(delayMinLabel); 555 p9b.add(delayMinSpinner); // already set to 0 556 delayMinSpinner.setToolTipText(Bundle.getMessage("RestartTimedHint")); 557 p9b.add(delayReStartSensorLabel); 558 p9b.add(delayReStartSensor); 559 delayReStartSensor.setAllowNull(true); 560 handleResetWhenDoneClick(null); 561 initiatePane.add(p9b); 562 563 initiatePane.add(new JSeparator()); 564 565 // Reverse at end 566 JPanel p10 = new JPanel(); 567 p10.add(reverseAtEndBox); 568 reverseAtEndBox.setToolTipText(Bundle.getMessage("ReverseAtEndBoxHint")); 569 initiatePane.add(p10); 570 reverseAtEndBox.addActionListener(new ActionListener() { 571 @Override 572 public void actionPerformed(ActionEvent e) { 573 handleReverseAtEndBoxClick(e); 574 } 575 }); 576 577 // Reverse using sensor 578 JPanel pDelayReverseRestartDetails = new JPanel(); 579 ((FlowLayout) pDelayReverseRestartDetails.getLayout()).setVgap(1); 580 pDelayReverseRestartDetails.add(delayReverseReStartLabel); 581 pDelayReverseRestartDetails.add(reverseDelayedRestartType); 582 pDelayReverseRestartDetails.add(delayReverseResetSensorBox); 583 delayReverseResetSensorBox.setToolTipText(Bundle.getMessage("ReverseResetRestartSensorHint")); 584 delayReverseResetSensorBox.setSelected(true); 585 reverseDelayedRestartType.addActionListener(new ActionListener() { 586 @Override 587 public void actionPerformed(ActionEvent e) { 588 handleReverseAtEndBoxClick(e); 589 } 590 }); 591 reverseDelayedRestartType.setToolTipText(Bundle.getMessage("ReverseDelayedReStartHint")); 592 initiatePane.add(pDelayReverseRestartDetails); 593 594 // Reverse using timer 595 JPanel pDelayReverseRestartDetails2 = new JPanel(); 596 ((FlowLayout) pDelayReverseRestartDetails2.getLayout()).setVgap(1); 597 pDelayReverseRestartDetails2.add(delayReverseMinLabel); 598 pDelayReverseRestartDetails2.add(delayReverseMinSpinner); // already set to 0 599 delayReverseMinSpinner.setToolTipText(Bundle.getMessage("ReverseRestartTimedHint")); 600 pDelayReverseRestartDetails2.add(delayReverseReStartSensorLabel); 601 pDelayReverseRestartDetails2.add(delayReverseReStartSensor); 602 delayReverseReStartSensor.setAllowNull(true); 603 handleReverseAtEndBoxClick(null); 604 initiatePane.add(pDelayReverseRestartDetails2); 605 606 initiatePane.add(new JSeparator()); 607 608 // Terminate when done option 609 JPanel p11 = new JPanel(); 610 p11.setLayout(new FlowLayout()); 611 p11.add(terminateWhenDoneBox); 612 terminateWhenDoneBox.addActionListener(new ActionListener() { 613 @Override 614 public void actionPerformed(ActionEvent e) { 615 handleTerminateWhenDoneBoxClick(e); 616 } 617 }); 618 initiatePane.add(p11); 619 620 // Optional next train, tied to terminate when done. 621 terminateWhenDoneDetails.setLayout(new FlowLayout()); 622 terminateWhenDoneDetails.add(nextTrainLabel); 623 terminateWhenDoneDetails.add(nextTrain); 624 nextTrain.setToolTipText(Bundle.getMessage("TerminateWhenDoneNextTrainHint")); 625 initiatePane.add(terminateWhenDoneDetails); 626 handleTerminateWhenDoneBoxClick(null); 627 628 initiatePane.add(new JSeparator()); 629 630 // Priority and train type. 631 JPanel p12 = new JPanel(); 632 p12.setLayout(new FlowLayout()); 633 p12.add(new JLabel(Bundle.getMessage("PriorityLabel") + ":")); 634 p12.add(prioritySpinner); // already set to 5 635 prioritySpinner.setToolTipText(Bundle.getMessage("PriorityHint")); 636 p12.add(new JLabel(" ")); 637 p12.add(new JLabel(Bundle.getMessage("TrainTypeBoxLabel"))); 638 initializeTrainTypeBox(); 639 p12.add(trainTypeBox); 640 trainTypeBox.setSelectedIndex(1); 641 trainTypeBox.setToolTipText(Bundle.getMessage("TrainTypeBoxHint")); 642 initiatePane.add(p12); 643 644 // Delayed start option 645 JPanel p13 = new JPanel(); 646 p13.add(new JLabel(Bundle.getMessage("DelayedStart"))); 647 p13.add(delayedStartBox); 648 delayedStartBox.setToolTipText(Bundle.getMessage("DelayedStartHint")); 649 delayedStartBox.addActionListener(new ActionListener() { 650 @Override 651 public void actionPerformed(ActionEvent e) { 652 handleDelayStartClick(e); 653 } 654 }); 655 p13.add(departureTimeLabel); 656 departureHrSpinner.setEditor(new JSpinner.NumberEditor(departureHrSpinner, "00")); 657 p13.add(departureHrSpinner); 658 departureHrSpinner.setValue(8); 659 departureHrSpinner.setToolTipText(Bundle.getMessage("DepartureTimeHrHint")); 660 p13.add(departureSepLabel); 661 departureMinSpinner.setEditor(new JSpinner.NumberEditor(departureMinSpinner, "00")); 662 p13.add(departureMinSpinner); 663 departureMinSpinner.setValue(0); 664 departureMinSpinner.setToolTipText(Bundle.getMessage("DepartureTimeMinHint")); 665 p13.add(delaySensor); 666 delaySensor.setAllowNull(true); 667 p13.add(resetStartSensorBox); 668 resetStartSensorBox.setToolTipText(Bundle.getMessage("ResetStartSensorHint")); 669 resetStartSensorBox.setSelected(true); 670 handleDelayStartClick(null); 671 initiatePane.add(p13); 672 673 // Load at startup option 674 JPanel p14 = new JPanel(); 675 p14.setLayout(new FlowLayout()); 676 p14.add(loadAtStartupBox); 677 loadAtStartupBox.setToolTipText(Bundle.getMessage("LoadAtStartupBoxHint")); 678 loadAtStartupBox.setSelected(false); 679 initiatePane.add(p14); 680 681 // Auto run option 682 initiatePane.add(new JSeparator()); 683 JPanel p15 = new JPanel(); 684 p15.add(autoRunBox); 685 autoRunBox.addActionListener(new ActionListener() { 686 @Override 687 public void actionPerformed(ActionEvent e) { 688 handleAutoRunClick(e); 689 } 690 }); 691 autoRunBox.setToolTipText(Bundle.getMessage("AutoRunBoxHint")); 692 autoRunBox.setSelected(false); 693 initiatePane.add(p15); 694 initializeAutoRunItems(); 695 696 // Footer buttons 697 JPanel ftr = new JPanel(); 698 JButton cancelButton = null; 699 ftr.add(cancelButton = new JButton(Bundle.getMessage("ButtonCancel"))); 700 cancelButton.addActionListener(new ActionListener() { 701 @Override 702 public void actionPerformed(ActionEvent e) { 703 cancelInitiateTrain(e); 704 } 705 }); 706 cancelButton.setToolTipText(Bundle.getMessage("CancelButtonHint")); 707 ftr.add(addNewTrainButton = new JButton(Bundle.getMessage("ButtonCreate"))); 708 addNewTrainButton.addActionListener(new ActionListener() { 709 @Override 710 public void actionPerformed(ActionEvent e) { 711 addNewTrain(e); 712 } 713 }); 714 addNewTrainButton.setToolTipText(Bundle.getMessage("AddNewTrainButtonHint")); 715 716 JPanel mainPane = new JPanel(new BorderLayout()); 717 JScrollPane scrPane = new JScrollPane(initiatePane); 718 mainPane.add(hdr, BorderLayout.NORTH); 719 mainPane.add(scrPane, BorderLayout.CENTER); 720 mainPane.add(ftr, BorderLayout.SOUTH); 721 initiateFrame.setContentPane(mainPane); 722 switch (trainInfo.getTrainsFrom()) { 723 case TRAINSFROMROSTER: 724 radioTrainsFromRoster.setSelected(true); 725 break; 726 case TRAINSFROMOPS: 727 radioTrainsFromOps.setSelected(true); 728 break; 729 case TRAINSFROMUSER: 730 radioTrainsFromUser.setSelected(true); 731 break; 732 case TRAINSFROMSETLATER: 733 default: 734 radioTrainsFromSetLater.setSelected(true); 735 } 736 737 } 738 autoRunBox.setSelected(false); 739 loadAtStartupBox.setSelected(false); 740 initializeFreeTransitsCombo(new ArrayList<Transit>()); 741 refreshNextTrainCombo(); 742 setTrainsFromOptions(trainInfo.getTrainsFrom()); 743 initiateFrame.pack(); 744 initiateFrame.setVisible(true); 745 746 trainInfoToDialog(trainInfo); 747 } 748 749 private void refreshNextTrainCombo() { 750 Object saveEntry = null; 751 if (nextTrain.getSelectedIndex() > 0) { 752 saveEntry=nextTrain.getSelectedItem(); 753 } 754 nextTrain.removeAllItems(); 755 nextTrain.addItem(" "); 756 for (String file: _tiFile.getTrainInfoFileNames()) { 757 nextTrain.addItem(file); 758 } 759 if (saveEntry != null) { 760 nextTrain.setSelectedItem(saveEntry); 761 } 762 } 763 private void setTrainsFromOptions(TrainsFrom transFrom) { 764 switch (transFrom) { 765 case TRAINSFROMROSTER: 766 initializeFreeRosterEntriesCombo(); 767 rosterComboBox.setVisible(true); 768 trainSelectBox.setVisible(false); 769 trainFieldLabel.setVisible(true); 770 trainNameField.setVisible(true); 771 dccAddressFieldLabel.setVisible(false); 772 dccAddressSpinner.setVisible(false); 773 break; 774 case TRAINSFROMOPS: 775 initializeFreeTrainsCombo(); 776 trainSelectBox.setVisible(true); 777 rosterComboBox.setVisible(false); 778 trainFieldLabel.setVisible(true); 779 trainNameField.setVisible(true); 780 dccAddressFieldLabel.setVisible(true); 781 dccAddressSpinner.setVisible(true); 782 setSpeedProfileOptions(trainInfo,false); 783 break; 784 case TRAINSFROMUSER: 785 trainNameField.setText(""); 786 trainSelectBox.setVisible(false); 787 rosterComboBox.setVisible(false); 788 trainFieldLabel.setVisible(true); 789 trainNameField.setVisible(true); 790 dccAddressFieldLabel.setVisible(true); 791 dccAddressSpinner.setVisible(true); 792 dccAddressSpinner.setEnabled(true); 793 setSpeedProfileOptions(trainInfo,false); 794 break; 795 case TRAINSFROMSETLATER: 796 default: 797 rosterComboBox.setVisible(false); 798 trainSelectBox.setVisible(false); 799 trainFieldLabel.setVisible(true); 800 trainNameField.setVisible(true); 801 dccAddressFieldLabel.setVisible(false); 802 dccAddressSpinner.setVisible(false); 803 } 804 } 805 806 private void initializeTrainTypeBox() { 807 trainTypeBox.removeAllItems(); 808 trainTypeBox.addItem("<" + Bundle.getMessage("None").toLowerCase() + ">"); // <none> 809 trainTypeBox.addItem(Bundle.getMessage("LOCAL_PASSENGER")); 810 trainTypeBox.addItem(Bundle.getMessage("LOCAL_FREIGHT")); 811 trainTypeBox.addItem(Bundle.getMessage("THROUGH_PASSENGER")); 812 trainTypeBox.addItem(Bundle.getMessage("THROUGH_FREIGHT")); 813 trainTypeBox.addItem(Bundle.getMessage("EXPRESS_PASSENGER")); 814 trainTypeBox.addItem(Bundle.getMessage("EXPRESS_FREIGHT")); 815 trainTypeBox.addItem(Bundle.getMessage("MOW")); 816 // NOTE: The above must correspond in order and name to definitions in ActiveTrain.java. 817 } 818 819 private void initializeTrainDetectionBox() { 820 trainDetectionComboBox.addItem(new TrainDetectionItem(Bundle.getMessage("TrainDetectionWholeTrain"),TrainDetection.TRAINDETECTION_WHOLETRAIN)); 821 trainDetectionComboBox.addItem(new TrainDetectionItem(Bundle.getMessage("TrainDetectionHeadAndTail"),TrainDetection.TRAINDETECTION_HEADANDTAIL)); 822 trainDetectionComboBox.addItem(new TrainDetectionItem(Bundle.getMessage("TrainDetectionHeadOnly"),TrainDetection.TRAINDETECTION_HEADONLY)); 823 } 824 825 private void initializeScaleLengthBox() { 826 trainLengthUnitsComboBox.addItem(new TrainLengthUnitsItem(Bundle.getMessage("TrainLengthInScaleFeet"), TrainLengthUnits.TRAINLENGTH_SCALEFEET)); 827 trainLengthUnitsComboBox.addItem(new TrainLengthUnitsItem(Bundle.getMessage("TrainLengthInScaleMeters"), TrainLengthUnits.TRAINLENGTH_SCALEMETERS)); 828 trainLengthUnitsComboBox.addItem(new TrainLengthUnitsItem(Bundle.getMessage("TrainLengthInActualInchs"), TrainLengthUnits.TRAINLENGTH_ACTUALINCHS)); 829 trainLengthUnitsComboBox.addItem(new TrainLengthUnitsItem(Bundle.getMessage("TrainLengthInActualcm"), TrainLengthUnits.TRAINLENGTH_ACTUALCM)); 830 } 831 832 private void handleTransitSelectionChanged(ActionEvent e) { 833 int index = transitSelectBox.getSelectedIndex(); 834 if (index < 0) { 835 return; 836 } 837 Transit t = transitSelectBox.getSelectedItem(); 838 if ((t != null) && (t != selectedTransit)) { 839 selectedTransit = t; 840 initializeStartingBlockCombo(); 841 initializeDestinationBlockCombo(); 842 initiateFrame.pack(); 843 } 844 } 845 846 private void handleInTransitClick() { 847 if (!inTransitBox.isSelected() && selectedTransit.getEntryBlocksList().isEmpty()) { 848 JmriJOptionPane.showMessageDialog(initiateFrame, Bundle 849 .getMessage("NoEntryBlocks"), Bundle.getMessage("MessageTitle"), 850 JmriJOptionPane.INFORMATION_MESSAGE); 851 inTransitBox.setSelected(true); 852 } 853 initializeStartingBlockCombo(); 854 initializeDestinationBlockCombo(); 855 initiateFrame.pack(); 856 } 857 858 private void handleTrainSelectionChanged() { 859 if (!trainsFromButtonGroup.getSelection().getActionCommand().equals("TRAINSFROMOPS")) { 860 return; 861 } 862 int ix = trainSelectBox.getSelectedIndex(); 863 if (ix < 1) { // no train selected 864 dccAddressSpinner.setEnabled(false); 865 return; 866 } 867 dccAddressSpinner.setEnabled(true); 868 int dccAddress; 869 try { 870 dccAddress = Integer.parseInt((((Train) trainSelectBox.getSelectedItem()).getLeadEngineDccAddress())); 871 } catch (NumberFormatException Ex) { 872 JmriJOptionPane.showMessageDialog(initiateFrame, Bundle.getMessage("Error43"), 873 Bundle.getMessage("ErrorTitle"), JmriJOptionPane.ERROR_MESSAGE); 874 return; 875 } 876 dccAddressSpinner.setValue (dccAddress); 877 trainNameField.setText(((Train) trainSelectBox.getSelectedItem()).getName()); 878 } 879 880 private void handleRosterSelectionChanged(ActionEvent e) { 881 if (!trainsFromButtonGroup.getSelection().getActionCommand().equals("TRAINSFROMROSTER")) { 882 return; 883 } 884 int ix = rosterComboBox.getSelectedIndex(); 885 if (ix > 0) { // first item is "Select Loco" string 886 RosterEntry r = (RosterEntry) rosterComboBox.getItemAt(ix); 887 // check to see if speed profile exists and is not empty 888 if (r.getSpeedProfile() == null || r.getSpeedProfile().getProfileSize() < 1) { 889 // disable profile boxes etc. 890 setSpeedProfileOptions(trainInfo,false); 891 } else { 892 // enable profile boxes 893 setSpeedProfileOptions(trainInfo,true); 894 } 895 maxSpeedSpinner.setValue(r.getMaxSpeedPCT()/100.0f); 896 trainNameField.setText(r.titleString()); 897 if (r.getAttribute("DispatcherTrainType") != null && !r.getAttribute("DispatcherTrainType").equals("")) { 898 trainTypeBox.setSelectedItem(r.getAttribute("DispatcherTrainType")); 899 } 900 } else { 901 setSpeedProfileOptions(trainInfo,false); 902 } 903 } 904 905 private void handleDelayStartClick(ActionEvent e) { 906 departureHrSpinner.setVisible(false); 907 departureMinSpinner.setVisible(false); 908 departureTimeLabel.setVisible(false); 909 departureSepLabel.setVisible(false); 910 delaySensor.setVisible(false); 911 resetStartSensorBox.setVisible(false); 912 if (delayedStartBox.getSelectedItem().equals(Bundle.getMessage("DelayedStartTimed"))) { 913 departureHrSpinner.setVisible(true); 914 departureMinSpinner.setVisible(true); 915 departureTimeLabel.setVisible(true); 916 departureSepLabel.setVisible(true); 917 } else if (delayedStartBox.getSelectedItem().equals(Bundle.getMessage("DelayedStartSensor"))) { 918 delaySensor.setVisible(true); 919 resetStartSensorBox.setVisible(true); 920 } 921 initiateFrame.pack(); // to fit extra hh:mm in window 922 } 923 924 private void handleResetWhenDoneClick(ActionEvent e) { 925 delayMinSpinner.setVisible(false); 926 delayMinLabel.setVisible(false); 927 delayedReStartLabel.setVisible(false); 928 delayedReStartBox.setVisible(false); 929 delayReStartSensorLabel.setVisible(false); 930 delayReStartSensor.setVisible(false); 931 resetRestartSensorBox.setVisible(false); 932 if (resetWhenDoneBox.isSelected()) { 933 delayedReStartLabel.setVisible(true); 934 delayedReStartBox.setVisible(true); 935 terminateWhenDoneBox.setSelected(false); 936 if (delayedReStartBox.getSelectedItem().equals(Bundle.getMessage("DelayedStartTimed"))) { 937 delayMinSpinner.setVisible(true); 938 delayMinLabel.setVisible(true); 939 } else if (delayedReStartBox.getSelectedItem().equals(Bundle.getMessage("DelayedStartSensor"))) { 940 delayReStartSensor.setVisible(true); 941 delayReStartSensorLabel.setVisible(true); 942 resetRestartSensorBox.setVisible(true); 943 } 944 } else { 945 terminateWhenDoneBox.setEnabled(true); 946 } 947 initiateFrame.pack(); 948 } 949 950 private void handleTerminateWhenDoneBoxClick(ActionEvent e) { 951 if (terminateWhenDoneBox.isSelected()) { 952 refreshNextTrainCombo(); 953 resetWhenDoneBox.setSelected(false); 954 terminateWhenDoneDetails.setVisible(true); 955 } else { 956 terminateWhenDoneDetails.setVisible(false); 957 } 958 } 959 960 private void handleReverseAtEndBoxClick(ActionEvent e) { 961 delayReverseMinSpinner.setVisible(false); 962 delayReverseMinLabel.setVisible(false); 963 delayReverseReStartLabel.setVisible(false); 964 reverseDelayedRestartType.setVisible(false); 965 delayReverseReStartSensorLabel.setVisible(false); 966 delayReverseReStartSensor.setVisible(false); 967 delayReverseResetSensorBox.setVisible(false); 968 if (reverseAtEndBox.isSelected()) { 969 delayReverseReStartLabel.setVisible(true); 970 reverseDelayedRestartType.setVisible(true); 971 if (reverseDelayedRestartType.getSelectedItem().equals(Bundle.getMessage("DelayedStartTimed"))) { 972 delayReverseMinSpinner.setVisible(true); 973 delayReverseMinLabel.setVisible(true); 974 } else if (reverseDelayedRestartType.getSelectedItem().equals(Bundle.getMessage("DelayedStartSensor"))) { 975 delayReverseReStartSensor.setVisible(true); 976 delayReStartSensorLabel.setVisible(true); 977 delayReverseResetSensorBox.setVisible(true); 978 } 979 } 980 initiateFrame.pack(); 981 982 if (resetWhenDoneBox.isSelected()) { 983 terminateWhenDoneBox.setSelected(false); 984 terminateWhenDoneBox.setEnabled(false); 985 } else { 986 terminateWhenDoneBox.setEnabled(true); 987 } 988 } 989 990 private void handleAutoRunClick(ActionEvent e) { 991 if (autoRunBox.isSelected()) { 992 showAutoRunItems(); 993 } else { 994 hideAutoRunItems(); 995 } 996 initiateFrame.pack(); 997 } 998 999 private void handleStartingBlockSelectionChanged(ActionEvent e) { 1000 if (radioTransitsAdHoc.isSelected() ) { 1001 initializeViaBlockDynamicCombo(); 1002 initializeDestinationBlockDynamicCombo(); 1003 } else { 1004 initializeDestinationBlockCombo(); 1005 } 1006 initiateFrame.pack(); 1007 } 1008 1009 private void handleViaBlockSelectionChanged(ActionEvent e) { 1010 if (radioTransitsAdHoc.isSelected() ) { 1011 initializeDestinationBlockDynamicCombo(); 1012 } else { 1013 initializeDestinationBlockCombo(); 1014 } 1015 initiateFrame.pack(); 1016 } 1017 1018 private void handleAllocateAllTheWayButtonChanged(ActionEvent e) { 1019 allocateCustomSpinner.setVisible(false); 1020 } 1021 1022 private void handleAllocateBySafeButtonChanged(ActionEvent e) { 1023 allocateCustomSpinner.setVisible(false); 1024 } 1025 1026 private void handleAllocateNumberOfBlocksButtonChanged(ActionEvent e) { 1027 allocateCustomSpinner.setVisible(true); 1028 } 1029 1030 private void cancelInitiateTrain(ActionEvent e) { 1031 _dispatcher.newTrainDone(null); 1032 } 1033 1034 /* 1035 * Handles press of "Add New Train" button. 1036 * Move data to TrainInfo validating basic information 1037 * Call dispatcher to start the train from traininfo which 1038 * completes validation. 1039 */ 1040 private void addNewTrain(ActionEvent e) { 1041 try { 1042 validateDialog(); 1043 if (radioTransitsAdHoc.isSelected()) { 1044 int ixStart, ixEnd, ixVia; 1045 ixStart = startingBlockBox.getSelectedIndex(); 1046 ixEnd = destinationBlockBox.getSelectedIndex(); 1047 ixVia = viaBlockBox.getSelectedIndex(); 1048 List<LayoutBlock>blockList = _dispatcher.getAdHocRoute(startingBlockBoxList.get(ixStart), 1049 destinationBlockBoxList.get(ixEnd), 1050 viaBlockBoxList.get(ixVia)); 1051 if (blockList == null ) { 1052 JmriJOptionPane.showMessageDialog(initiateFrame, "Invalid Transit", 1053 Bundle.getMessage("ErrorTitle"), JmriJOptionPane.ERROR_MESSAGE); 1054 return; 1055 } 1056 } 1057 dialogToTrainInfo(trainInfo); 1058 _dispatcher.loadTrainFromTrainInfoThrowsException(trainInfo,"NONE",""); 1059 } catch (IllegalArgumentException ex) { 1060 JmriJOptionPane.showMessageDialog(initiateFrame, ex.getMessage(), 1061 Bundle.getMessage("ErrorTitle"), JmriJOptionPane.ERROR_MESSAGE); 1062 } 1063 } 1064 1065 private void initializeFreeTransitsCombo(List<Transit> transitList) { 1066 Set<Transit> excludeTransits = new HashSet<>(); 1067 for (Transit t : _TransitManager.getNamedBeanSet()) { 1068 if (t.getState() != Transit.IDLE) { 1069 excludeTransits.add(t); 1070 } 1071 } 1072 transitSelectBox.setExcludedItems(excludeTransits); 1073 JComboBoxUtil.setupComboBoxMaxRows(transitSelectBox); 1074 1075 if (transitSelectBox.getItemCount() > 0) { 1076 transitSelectBox.setSelectedIndex(0); 1077 selectedTransit = transitSelectBox.getItemAt(0); 1078 } else { 1079 selectedTransit = null; 1080 } 1081 } 1082 1083 private void initializeFreeRosterEntriesCombo() { 1084 rosterComboBox.update(); 1085 // remove used entries 1086 for (int ix = rosterComboBox.getItemCount() - 1; ix > 1; ix--) { // remove from back first item is the "select loco" message 1087 if ( !_dispatcher.isAddressFree( ((RosterEntry)rosterComboBox.getItemAt(ix)).getDccLocoAddress().getNumber() ) ) { 1088 rosterComboBox.removeItemAt(ix); 1089 } 1090 } 1091 } 1092 1093 private void initializeFreeTrainsCombo() { 1094 Train prevValue = null; 1095 if (trainSelectBox.getSelectedIndex() > -1) { 1096 prevValue = (Train)trainSelectBox.getSelectedItem(); 1097 } 1098 ActionListener[] als = trainSelectBox.getActionListeners(); 1099 for ( ActionListener al: als) { 1100 trainSelectBox.removeActionListener(al); 1101 } 1102 trainSelectBox.removeAllItems(); 1103 trainSelectBox.addItem("Select Train"); 1104 // initialize free trains from operations 1105 List<Train> trains = jmri.InstanceManager.getDefault(TrainManager.class).getTrainsByNameList(); 1106 if (trains.size() > 0) { 1107 for (int i = 0; i < trains.size(); i++) { 1108 Train t = trains.get(i); 1109 if (t != null) { 1110 String tName = t.getName(); 1111 if (_dispatcher.isTrainFree(tName)) { 1112 trainSelectBox.addItem(t); 1113 } 1114 } 1115 } 1116 } 1117 if (prevValue != null) { 1118 trainSelectBox.setSelectedItem(prevValue); 1119 } 1120 for ( ActionListener al: als) { 1121 trainSelectBox.addActionListener(al); 1122 } 1123 } 1124 1125 /** 1126 * Sets the labels and inputs for speed profile running 1127 * @param b True if the roster entry has valid speed profile else false 1128 */ 1129 private void setSpeedProfileOptions(TrainInfo info,boolean b) { 1130 useSpeedProfileLabel.setEnabled(b); 1131 useSpeedProfileCheckBox.setEnabled(b); 1132 stopBySpeedProfileLabel.setEnabled(b); 1133 stopBySpeedProfileCheckBox.setEnabled(b); 1134 stopBySpeedProfileAdjustLabel.setEnabled(b); 1135 stopBySpeedProfileAdjustSpinner.setEnabled(b); 1136 if (!b) { 1137 useSpeedProfileCheckBox.setSelected(false); 1138 stopBySpeedProfileCheckBox.setSelected(false); 1139 1140 } 1141 } 1142 1143 private void initializeStartingBlockCombo() { 1144 String prevValue = (String)startingBlockBox.getSelectedItem(); 1145 startingBlockBox.removeAllItems(); 1146 startingBlockBoxList.clear(); 1147 if (!inTransitBox.isSelected() && selectedTransit.getEntryBlocksList().isEmpty()) { 1148 inTransitBox.setSelected(true); 1149 } 1150 if (inTransitBox.isSelected()) { 1151 startingBlockBoxList = selectedTransit.getInternalBlocksList(); 1152 } else { 1153 startingBlockBoxList = selectedTransit.getEntryBlocksList(); 1154 } 1155 startingBlockSeqList = selectedTransit.getBlockSeqList(); 1156 boolean found = false; 1157 for (int i = 0; i < startingBlockBoxList.size(); i++) { 1158 Block b = startingBlockBoxList.get(i); 1159 int seq = startingBlockSeqList.get(i).intValue(); 1160 startingBlockBox.addItem(getBlockName(b) + "-" + seq); 1161 if (!found && b.getState() == Block.OCCUPIED) { 1162 startingBlockBox.setSelectedItem(getBlockName(b) + "-" + seq); 1163 found = true; 1164 } 1165 } 1166 if (prevValue != null) { 1167 startingBlockBox.setSelectedItem(prevValue); 1168 } 1169 JComboBoxUtil.setupComboBoxMaxRows(startingBlockBox); 1170 } 1171 1172 private void initializeDestinationBlockCombo() { 1173 String prevValue = (String)destinationBlockBox.getSelectedItem(); 1174 destinationBlockBox.removeAllItems(); 1175 destinationBlockBoxList.clear(); 1176 int index = startingBlockBox.getSelectedIndex(); 1177 if (index < 0) { 1178 return; 1179 } 1180 Block startBlock = startingBlockBoxList.get(index); 1181 destinationBlockBoxList = selectedTransit.getDestinationBlocksList( 1182 startBlock, inTransitBox.isSelected()); 1183 destinationBlockSeqList = selectedTransit.getDestBlocksSeqList(); 1184 for (int i = 0; i < destinationBlockBoxList.size(); i++) { 1185 Block b = destinationBlockBoxList.get(i); 1186 String bName = getBlockName(b); 1187 if (selectedTransit.getBlockCount(b) > 1) { 1188 int seq = destinationBlockSeqList.get(i).intValue(); 1189 bName = bName + "-" + seq; 1190 } 1191 destinationBlockBox.addItem(bName); 1192 } 1193 if (prevValue != null) { 1194 destinationBlockBox.setSelectedItem(prevValue); 1195 } 1196 JComboBoxUtil.setupComboBoxMaxRows(destinationBlockBox); 1197 } 1198 1199 private String getBlockName(Block b) { 1200 if (b != null) { 1201 return b.getDisplayName(); 1202 } 1203 return " "; 1204 } 1205 1206 protected void showActivateFrame() { 1207 if (initiateFrame != null) { 1208 initializeFreeTransitsCombo(new ArrayList<Transit>()); 1209 initiateFrame.setVisible(true); 1210 } else { 1211 _dispatcher.newTrainDone(null); 1212 } 1213 } 1214 1215 public void showActivateFrame(RosterEntry re) { 1216 showActivateFrame(); 1217 } 1218 1219 protected void loadTrainInfo(ActionEvent e) { 1220 List<TrainInfoFileSummary> names = _tiFile.getTrainInfoFileSummaries(); 1221 if (names.size() > 0) { 1222 JTable table = new JTable(){ 1223 @Override 1224 public Dimension getPreferredScrollableViewportSize() { 1225 return new Dimension(super.getPreferredSize().width, 1226 super.getPreferredScrollableViewportSize().height); 1227 } 1228 }; 1229 DefaultTableModel tm = new DefaultTableModel( 1230 new Object[]{ 1231 Bundle.getMessage("FileNameColumnTitle"), 1232 Bundle.getMessage("TrainColumnTitle"), 1233 Bundle.getMessage("TransitColumnTitle"), 1234 Bundle.getMessage("StartBlockColumnTitle"), 1235 Bundle.getMessage("EndBlockColumnTitle"), 1236 Bundle.getMessage("DccColumnTitleColumnTitle") 1237 }, 0) { 1238 @Override 1239 public boolean isCellEditable(int row, int column) { 1240 //all cells false 1241 return false; 1242 } 1243 }; 1244 1245 table.setModel(tm); 1246 for (TrainInfoFileSummary fs: names) { 1247 tm.addRow(new Object[] {fs.getFileName(),fs.getTrainName(), 1248 fs.getTransitName(),fs.getStartBlockName() 1249 ,fs.getEndBlockName(),fs.getDccAddress()}); 1250 } 1251 JPanel jp = new JPanel(new BorderLayout()); 1252 TableColumnModel columnModel = table.getColumnModel(); 1253 table.setAutoResizeMode( JTable.AUTO_RESIZE_OFF ); 1254 for (int column = 0; column < table.getColumnCount(); column++) { 1255 int width = 30; // Min width 1256 for (int row = 0; row < table.getRowCount(); row++) { 1257 TableCellRenderer renderer = table.getCellRenderer(row, column); 1258 Component comp = table.prepareRenderer(renderer, row, column); 1259 width = Math.max(comp.getPreferredSize().width +1 , width); 1260 } 1261 if(width > 300) 1262 width=300; 1263 columnModel.getColumn(column).setPreferredWidth(width); 1264 } 1265 //jp.setPreferredSize(table.getPreferredSize()); 1266 jp.add(table); 1267 JScrollPane sp = new JScrollPane(table, 1268 ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, 1269 ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); 1270 int optionSelected = JmriJOptionPane.showOptionDialog(initiateFrame, 1271 sp, Bundle.getMessage("LoadTrainTitle"), JmriJOptionPane.OK_CANCEL_OPTION, JmriJOptionPane.PLAIN_MESSAGE, 1272 null,null,null); 1273 if (optionSelected != JmriJOptionPane.OK_OPTION) { 1274 //Canceled 1275 return; 1276 } 1277 if (table.getSelectedRow() < 0) { 1278 return; 1279 } 1280 String selName = (String)table.getModel().getValueAt(table.getSelectedRow(),0); 1281 if ((selName == null) || (selName.isEmpty())) { 1282 return; 1283 } 1284 //read xml data from selected filename and move it into the new train dialog box 1285 _trainInfoName = selName; 1286 try { 1287 trainInfo = _tiFile.readTrainInfo( selName); 1288 if (trainInfo != null) { 1289 // process the information just read 1290 trainInfoToDialog(trainInfo); 1291 } 1292 } catch (java.io.IOException ioe) { 1293 log.error("IO Exception when reading train info file", ioe); 1294 } catch (org.jdom2.JDOMException jde) { 1295 log.error("JDOM Exception when reading train info file", jde); 1296 } 1297 handleDelayStartClick(null); 1298 handleReverseAtEndBoxClick(null); 1299 } 1300 } 1301 1302 private void saveTrainInfo(ActionEvent e) { 1303 saveTrainInfo(false); 1304 refreshNextTrainCombo(); 1305 } 1306 1307 private void saveTrainInfoAsTemplate(ActionEvent e) { 1308 saveTrainInfo(true); 1309 } 1310 1311 private void saveTrainInfo(boolean asTemplate) { 1312 try { 1313 dialogToTrainInfo(trainInfo); 1314 } catch (IllegalArgumentException ide) { 1315 JmriJOptionPane.showMessageDialog(initiateFrame, ide.getMessage(), 1316 Bundle.getMessage("ErrorTitle"), JmriJOptionPane.ERROR_MESSAGE); 1317 return; 1318 } 1319 // get file name 1320 String fileName; 1321 if (asTemplate) { 1322 fileName = normalizeXmlFileName(nameOfTemplateFile); 1323 } else { 1324 String eName = ""; 1325 eName = JmriJOptionPane.showInputDialog(initiateFrame, 1326 Bundle.getMessage("EnterFileName") + " :", _trainInfoName); 1327 if (eName == null) { //Cancel pressed 1328 return; 1329 } 1330 if (eName.length() < 1) { 1331 JmriJOptionPane.showMessageDialog(initiateFrame, Bundle.getMessage("Error25"), 1332 Bundle.getMessage("ErrorTitle"), JmriJOptionPane.ERROR_MESSAGE); 1333 return; 1334 } 1335 fileName = normalizeXmlFileName(eName); 1336 _trainInfoName = fileName; 1337 } 1338 // check if train info file name is in use 1339 String[] names = _tiFile.getTrainInfoFileNames(); 1340 if (names.length > 0) { 1341 boolean found = false; 1342 for (int i = 0; i < names.length; i++) { 1343 if (fileName.equals(names[i])) { 1344 found = true; 1345 } 1346 } 1347 if (found) { 1348 // file by that name is already present 1349 int selectedValue = JmriJOptionPane.showOptionDialog(initiateFrame, 1350 Bundle.getMessage("Question3", fileName), 1351 Bundle.getMessage("WarningTitle"), JmriJOptionPane.DEFAULT_OPTION, 1352 JmriJOptionPane.QUESTION_MESSAGE, null, 1353 new Object[]{Bundle.getMessage("ButtonReplace"),Bundle.getMessage("ButtonNo")}, 1354 Bundle.getMessage("ButtonNo")); 1355 if (selectedValue != 0 ) { // array position 0 , replace not selected 1356 return; // return without writing if "No" response 1357 } 1358 } 1359 } 1360 // write the Train Info file 1361 try { 1362 _tiFile.writeTrainInfo(trainInfo, fileName); 1363 } //catch (org.jdom2.JDOMException jde) { 1364 // log.error("JDOM exception writing Train Info: "+jde); 1365 //} 1366 catch (java.io.IOException ioe) { 1367 log.error("IO exception writing Train Info", ioe); 1368 } 1369 } 1370 1371 private void deleteTrainInfo(ActionEvent e) { 1372 String[] names = _tiFile.getTrainInfoFileNames(); 1373 if (names.length > 0) { 1374 Object selName = JmriJOptionPane.showInputDialog(initiateFrame, 1375 Bundle.getMessage("DeleteTrainChoice"), Bundle.getMessage("DeleteTrainTitle"), 1376 JmriJOptionPane.QUESTION_MESSAGE, null, names, names[0]); 1377 if ((selName == null) || (((String) selName).equals(""))) { 1378 return; 1379 } 1380 _tiFile.deleteTrainInfoFile((String) selName); 1381 } 1382 } 1383 1384 private void trainInfoToDialog(TrainInfo info) { 1385 if (!info.getDynamicTransit()) { 1386 radioTransitsPredefined.setSelected(true); 1387 if (!info.getTransitName().isEmpty()) { 1388 try { 1389 transitSelectBox.setSelectedItemByName(info.getTransitName()); 1390 } catch (Exception ex) { 1391 log.warn("Transit {} from file not in Transit menu", info.getTransitName()); 1392 JmriJOptionPane.showMessageDialog(initiateFrame, 1393 Bundle.getMessage("TransitWarn", info.getTransitName()), 1394 null, JmriJOptionPane.WARNING_MESSAGE); 1395 } 1396 } 1397 } else { 1398 radioTransitsAdHoc.setSelected(true); 1399 } 1400 switch (info.getTrainsFrom()) { 1401 case TRAINSFROMROSTER: 1402 radioTrainsFromRoster.setSelected(true); 1403 if (!info.getRosterId().isEmpty()) { 1404 if (!setRosterComboBox(rosterComboBox, info.getRosterId())) { 1405 log.warn("Roster {} from file not in Roster Combo", info.getRosterId()); 1406 JmriJOptionPane.showMessageDialog(initiateFrame, 1407 Bundle.getMessage("TrainWarn", info.getRosterId()), 1408 null, JmriJOptionPane.WARNING_MESSAGE); 1409 } 1410 } 1411 break; 1412 case TRAINSFROMOPS: 1413 radioTrainsFromOps.setSelected(true); 1414 if (!info.getTrainName().isEmpty()) { 1415 if (!setTrainComboBox(trainSelectBox, info.getTrainName())) { 1416 log.warn("Train {} from file not in Train Combo", info.getTrainName()); 1417 JmriJOptionPane.showMessageDialog(initiateFrame, 1418 Bundle.getMessage("TrainWarn", info.getTrainName()), 1419 null, JmriJOptionPane.WARNING_MESSAGE); 1420 } 1421 } 1422 break; 1423 case TRAINSFROMUSER: 1424 radioTrainsFromUser.setSelected(true); 1425 dccAddressSpinner.setValue(Integer.parseInt(info.getDccAddress())); 1426 break; 1427 case TRAINSFROMSETLATER: 1428 default: 1429 radioTrainsFromSetLater.setSelected(true); 1430 } 1431 trainNameField.setText(info.getTrainUserName()); 1432 trainDetectionComboBox.setSelectedItemByValue(info.getTrainDetection()); 1433 inTransitBox.setSelected(info.getTrainInTransit()); 1434 if (radioTransitsAdHoc.isSelected()) { 1435 initializeStartingBlockComboDynamic(); 1436 } else { 1437 initializeStartingBlockCombo(); 1438 } 1439 setComboBox(startingBlockBox, info.getStartBlockName()); 1440 if (radioTransitsAdHoc.isSelected()) { 1441 initializeViaBlockDynamicCombo(); 1442 setComboBox(viaBlockBox, info.getViaBlockName()); 1443 } 1444 if (radioTransitsAdHoc.isSelected()) { 1445 initializeDestinationBlockDynamicCombo(); 1446 } else { 1447 initializeDestinationBlockCombo(); 1448 } 1449 setComboBox(destinationBlockBox, info.getDestinationBlockName()); 1450 1451 setAllocateMethodButtons(info.getAllocationMethod()); 1452 prioritySpinner.setValue(info.getPriority()); 1453 resetWhenDoneBox.setSelected(info.getResetWhenDone()); 1454 reverseAtEndBox.setSelected(info.getReverseAtEnd()); 1455 setDelayModeBox(info.getDelayedStart(), delayedStartBox); 1456 //delayedStartBox.setSelected(info.getDelayedStart()); 1457 departureHrSpinner.setValue(info.getDepartureTimeHr()); 1458 departureMinSpinner.setValue(info.getDepartureTimeMin()); 1459 delaySensor.setSelectedItem(info.getDelaySensor()); 1460 resetStartSensorBox.setSelected(info.getResetStartSensor()); 1461 setDelayModeBox(info.getDelayedRestart(), delayedReStartBox); 1462 delayMinSpinner.setValue(info.getRestartDelayMin()); 1463 delayReStartSensor.setSelectedItem(info.getRestartSensor()); 1464 resetRestartSensorBox.setSelected(info.getResetRestartSensor()); 1465 1466 resetStartSensorBox.setSelected(info.getResetStartSensor()); 1467 setDelayModeBox(info.getReverseDelayedRestart(), reverseDelayedRestartType); 1468 delayReverseMinSpinner.setValue(info.getReverseRestartDelayMin()); 1469 delayReverseReStartSensor.setSelectedItem(info.getReverseRestartSensor()); 1470 delayReverseResetSensorBox.setSelected(info.getReverseResetRestartSensor()); 1471 1472 terminateWhenDoneBox.setSelected(info.getTerminateWhenDone()); 1473 nextTrain.setSelectedIndex(-1); 1474 try { 1475 nextTrain.setSelectedItem(info.getNextTrain()); 1476 } catch (Exception ex){ 1477 nextTrain.setSelectedIndex(-1); 1478 } 1479 handleTerminateWhenDoneBoxClick(null); 1480 setComboBox(trainTypeBox, info.getTrainType()); 1481 autoRunBox.setSelected(info.getAutoRun()); 1482 loadAtStartupBox.setSelected(info.getLoadAtStartup()); 1483 setAllocateMethodButtons(info.getAllocationMethod()); 1484 autoTrainInfoToDialog(info); 1485 } 1486 1487 private boolean validateDialog() throws IllegalArgumentException { 1488 int index = transitSelectBox.getSelectedIndex(); 1489 if (index < 0) { 1490 throw new IllegalArgumentException(Bundle.getMessage("Error44")); 1491 } 1492 switch (trainsFromButtonGroup.getSelection().getActionCommand()) { 1493 case "TRAINSFROMROSTER": 1494 if (rosterComboBox.getSelectedIndex() < 1 ) { 1495 throw new IllegalArgumentException(Bundle.getMessage("Error41")); 1496 } 1497 break; 1498 case "TRAINSFROMOPS": 1499 if (trainSelectBox.getSelectedIndex() < 1) { 1500 throw new IllegalArgumentException(Bundle.getMessage("Error42")); 1501 } 1502 break; 1503 case "TRAINSFROMUSER": 1504 if (trainNameField.getText().isEmpty()) { 1505 throw new IllegalArgumentException(Bundle.getMessage("Error22")); 1506 } 1507 break; 1508 case "TRAINSFROMSETLATER": 1509 default: 1510 } 1511 index = startingBlockBox.getSelectedIndex(); 1512 if (index < 0) { 1513 throw new IllegalArgumentException(Bundle.getMessage("Error13")); 1514 } 1515 index = destinationBlockBox.getSelectedIndex(); 1516 if (index < 0) { 1517 throw new IllegalArgumentException(Bundle.getMessage("Error8")); 1518 } 1519 if (radioTransitsAdHoc.isSelected()) { 1520 index = viaBlockBox.getSelectedIndex(); 1521 if (index < 0) { 1522 throw new IllegalArgumentException(Bundle.getMessage("Error8")); 1523 } 1524 } 1525 if ((!reverseAtEndBox.isSelected()) && resetWhenDoneBox.isSelected() 1526 && (!selectedTransit.canBeResetWhenDone())) { 1527 resetWhenDoneBox.setSelected(false); 1528 throw new IllegalArgumentException(Bundle.getMessage("NoResetMessage")); 1529 } 1530 int max = Math.round((float) maxSpeedSpinner.getValue()*100.0f); 1531 int min = Math.round((float) minReliableOperatingSpeedSpinner.getValue()*100.0f); 1532 if ((max-min) < 10) { 1533 throw new IllegalArgumentException(Bundle.getMessage("Error49", 1534 maxSpeedSpinner.getValue(), minReliableOperatingSpeedSpinner.getValue())); 1535 } 1536 return true; 1537 } 1538 1539 private boolean dialogToTrainInfo(TrainInfo info) { 1540 int index = transitSelectBox.getSelectedIndex(); 1541 info.setDynamicTransit(radioTransitsAdHoc.isSelected()); 1542 if (!info.getDynamicTransit() && index >= 0 ) { 1543 info.setTransitName(transitSelectBox.getSelectedItem().getDisplayName()); 1544 info.setTransitId(transitSelectBox.getSelectedItem().getDisplayName()); 1545 } 1546 switch (trainsFromButtonGroup.getSelection().getActionCommand()) { 1547 case "TRAINSFROMROSTER": 1548 info.setRosterId(((RosterEntry) rosterComboBox.getSelectedItem()).getId()); 1549 info.setDccAddress(((RosterEntry) rosterComboBox.getSelectedItem()).getDccAddress()); 1550 trainInfo.setTrainsFrom(TrainsFrom.TRAINSFROMROSTER); 1551 setTrainsFromOptions(trainInfo.getTrainsFrom()); 1552 break; 1553 case "TRAINSFROMOPS": 1554 info.setTrainName(((Train) trainSelectBox.getSelectedItem()).toString()); 1555 info.setDccAddress(String.valueOf(dccAddressSpinner.getValue())); 1556 trainInfo.setTrainsFrom(TrainsFrom.TRAINSFROMOPS); 1557 setTrainsFromOptions(trainInfo.getTrainsFrom()); 1558 break; 1559 case "TRAINSFROMUSER": 1560 trainInfo.setTrainsFrom(TrainsFrom.TRAINSFROMUSER); 1561 info.setDccAddress(String.valueOf(dccAddressSpinner.getValue())); 1562 break; 1563 case "TRAINSFROMSETLATER": 1564 default: 1565 trainInfo.setTrainsFrom(TrainsFrom.TRAINSFROMSETLATER); 1566 info.setTrainName(""); 1567 info.setDccAddress(""); 1568 } 1569 info.setTrainUserName(trainNameField.getText()); 1570 info.setTrainInTransit(inTransitBox.isSelected()); 1571 info.setStartBlockName((String) startingBlockBox.getSelectedItem()); 1572 index = startingBlockBox.getSelectedIndex(); 1573 info.setStartBlockId(startingBlockBoxList.get(index).getDisplayName()); 1574 if (info.getDynamicTransit()) { 1575 info.setStartBlockSeq(1); 1576 } else { 1577 info.setStartBlockSeq(startingBlockSeqList.get(index).intValue()); 1578 } 1579 index = destinationBlockBox.getSelectedIndex(); 1580 info.setDestinationBlockId(destinationBlockBoxList.get(index).getDisplayName()); 1581 info.setDestinationBlockName(destinationBlockBoxList.get(index).getDisplayName()); 1582 if (info.getDynamicTransit()) { 1583 info.setViaBlockName(viaBlockBoxList.get(viaBlockBox.getSelectedIndex()).getDisplayName()); 1584 } else { 1585 info.setDestinationBlockSeq(destinationBlockSeqList.get(index).intValue()); 1586 } 1587 info.setPriority((Integer) prioritySpinner.getValue()); 1588 info.setTrainDetection(((TrainDetectionItem)trainDetectionComboBox.getSelectedItem()).value); 1589 info.setResetWhenDone(resetWhenDoneBox.isSelected()); 1590 info.setReverseAtEnd(reverseAtEndBox.isSelected()); 1591 info.setDelayedStart(delayModeFromBox(delayedStartBox)); 1592 info.setDelaySensorName(delaySensor.getSelectedItemDisplayName()); 1593 info.setResetStartSensor(resetStartSensorBox.isSelected()); 1594 info.setDepartureTimeHr((Integer) departureHrSpinner.getValue()); 1595 info.setDepartureTimeMin((Integer) departureMinSpinner.getValue()); 1596 info.setTrainType((String) trainTypeBox.getSelectedItem()); 1597 info.setAutoRun(autoRunBox.isSelected()); 1598 info.setLoadAtStartup(loadAtStartupBox.isSelected()); 1599 info.setAllocateAllTheWay(false); // force to false next field is now used. 1600 if (allocateAllTheWayRadioButton.isSelected()) { 1601 info.setAllocationMethod(ActiveTrain.ALLOCATE_AS_FAR_AS_IT_CAN); 1602 } else if (allocateBySafeRadioButton.isSelected()) { 1603 info.setAllocationMethod(ActiveTrain.ALLOCATE_BY_SAFE_SECTIONS); 1604 } else { 1605 info.setAllocationMethod((Integer) allocateCustomSpinner.getValue()); 1606 } 1607 info.setDelayedRestart(delayModeFromBox(delayedReStartBox)); 1608 info.setRestartSensorName(delayReStartSensor.getSelectedItemDisplayName()); 1609 info.setResetRestartSensor(resetRestartSensorBox.isSelected()); 1610 info.setRestartDelayMin((Integer) delayMinSpinner.getValue()); 1611 1612 info.setReverseDelayedRestart(delayModeFromBox(reverseDelayedRestartType)); 1613 info.setReverseRestartSensorName(delayReverseReStartSensor.getSelectedItemDisplayName()); 1614 info.setReverseResetRestartSensor(delayReverseResetSensorBox.isSelected()); 1615 info.setReverseRestartDelayMin((Integer) delayReverseMinSpinner.getValue()); 1616 1617 info.setTerminateWhenDone(terminateWhenDoneBox.isSelected()); 1618 if (nextTrain.getSelectedIndex() > 0 ) { 1619 info.setNextTrain((String)nextTrain.getSelectedItem()); 1620 } else { 1621 info.setNextTrain("None"); 1622 } 1623 autoRunItemsToTrainInfo(info); 1624 return true; 1625 } 1626 1627 private boolean setRosterComboBox(RosterEntryComboBox box, String txt) { 1628 boolean found = false; 1629 for (int i = 1; i < box.getItemCount(); i++) { 1630 if (txt.equals(((RosterEntry) box.getItemAt(i)).getId())) { 1631 box.setSelectedIndex(i); 1632 found = true; 1633 break; 1634 } 1635 } 1636 if (!found && box.getItemCount() > 0) { 1637 box.setSelectedIndex(0); 1638 } 1639 return found; 1640 } 1641 1642 // Normalizes a suggested xml file name. Returns null string if a valid name cannot be assembled 1643 private String normalizeXmlFileName(String name) { 1644 if (name.length() < 1) { 1645 return ""; 1646 } 1647 String newName = name; 1648 // strip off .xml or .XML if present 1649 if ((name.endsWith(".xml")) || (name.endsWith(".XML"))) { 1650 newName = name.substring(0, name.length() - 4); 1651 if (newName.length() < 1) { 1652 return ""; 1653 } 1654 } 1655 // replace all non-alphanumeric characters with underscore 1656 newName = newName.replaceAll("[\\W]", "_"); 1657 return (newName + ".xml"); 1658 } 1659 1660 private boolean setTrainComboBox(JComboBox<Object> box, String txt) { 1661 boolean found = false; 1662 for (int i = 1; i < box.getItemCount(); i++) { //skip the select train item 1663 if (txt.equals(box.getItemAt(i).toString())) { 1664 box.setSelectedIndex(i); 1665 found = true; 1666 break; 1667 } 1668 } 1669 if (!found && box.getItemCount() > 0) { 1670 box.setSelectedIndex(0); 1671 } 1672 return found; 1673 } 1674 1675 private boolean setComboBox(JComboBox<String> box, String txt) { 1676 boolean found = false; 1677 for (int i = 0; i < box.getItemCount(); i++) { 1678 if (txt.equals(box.getItemAt(i))) { 1679 box.setSelectedIndex(i); 1680 found = true; 1681 break; 1682 } 1683 } 1684 if (!found && box.getItemCount() > 0) { 1685 box.setSelectedIndex(0); 1686 } 1687 return found; 1688 } 1689 1690 int delayModeFromBox(JComboBox<String> box) { 1691 String mode = (String) box.getSelectedItem(); 1692 int result = jmri.util.StringUtil.getStateFromName(mode, delayedStartInt, delayedStartString); 1693 1694 if (result < 0) { 1695 log.warn("unexpected mode string in turnoutMode: {}", mode); 1696 throw new IllegalArgumentException(); 1697 } 1698 return result; 1699 } 1700 1701 void setDelayModeBox(int mode, JComboBox<String> box) { 1702 String result = jmri.util.StringUtil.getNameFromState(mode, delayedStartInt, delayedStartString); 1703 box.setSelectedItem(result); 1704 } 1705 1706 /** 1707 * The following are for items that are only for automatic running of 1708 * ActiveTrains They are isolated here to simplify changing them in the 1709 * future. 1710 * <ul> 1711 * <li>initializeAutoRunItems - initializes the display of auto run items in 1712 * this window 1713 * <li>initializeAutoRunValues - initializes the values of auto run items 1714 * from values in a saved train info file hideAutoRunItems - hides all auto 1715 * run items in this window showAutoRunItems - shows all auto run items in 1716 * this window 1717 * <li>autoTrainInfoToDialog - gets auto run items from a train info, puts 1718 * values in items, and initializes auto run dialog items 1719 * <li>autoTrainItemsToTrainInfo - copies values of auto run items to train 1720 * info for saving to a file 1721 * <li>readAutoRunItems - reads and checks values of all auto run items. 1722 * returns true if OK, sends appropriate messages and returns false if not 1723 * OK 1724 * <li>setAutoRunItems - sets the user entered auto run items in the new 1725 * AutoActiveTrain 1726 * </ul> 1727 */ 1728 // auto run items in ActivateTrainFrame 1729 private final JPanel pa1 = new JPanel(); 1730 private final JLabel speedFactorLabel = new JLabel(Bundle.getMessage("SpeedFactorLabel")); 1731 private final JSpinner speedFactorSpinner = new JSpinner(); 1732 private final JLabel minReliableOperatingSpeedLabel = new JLabel(Bundle.getMessage("MinReliableOperatingSpeedLabel")); 1733 private final JSpinner minReliableOperatingSpeedSpinner = new JSpinner(); 1734 private final JLabel maxSpeedLabel = new JLabel(Bundle.getMessage("MaxSpeedLabel")); 1735 private final JSpinner maxSpeedSpinner = new JSpinner(); 1736 private final JPanel pa2 = new JPanel(); 1737 private final JLabel rampRateLabel = new JLabel(Bundle.getMessage("RampRateBoxLabel")); 1738 private final JComboBox<String> rampRateBox = new JComboBox<>(); 1739 private final JPanel pa2a = new JPanel(); 1740 private final JLabel useSpeedProfileLabel = new JLabel(Bundle.getMessage("UseSpeedProfileLabel")); 1741 private final JCheckBox useSpeedProfileCheckBox = new JCheckBox( ); 1742 private final JLabel stopBySpeedProfileLabel = new JLabel(Bundle.getMessage("StopBySpeedProfileLabel")); 1743 private final JCheckBox stopBySpeedProfileCheckBox = new JCheckBox( ); 1744 private final JLabel stopBySpeedProfileAdjustLabel = new JLabel(Bundle.getMessage("StopBySpeedProfileAdjustLabel")); 1745 private final JSpinner stopBySpeedProfileAdjustSpinner = new JSpinner(); 1746 private final JPanel pa3 = new JPanel(); 1747 private final JCheckBox soundDecoderBox = new JCheckBox(Bundle.getMessage("SoundDecoder")); 1748 private final JCheckBox runInReverseBox = new JCheckBox(Bundle.getMessage("RunInReverse")); 1749 private final JPanel pa4 = new JPanel(); 1750 1751 protected static class TrainDetectionJCombo extends JComboBox<TrainDetectionItem> { 1752 public void setSelectedItemByValue(TrainDetection var) { 1753 for ( int ix = 0; ix < getItemCount() ; ix ++ ) { 1754 if (getItemAt(ix).value == var) { 1755 this.setSelectedIndex(ix); 1756 break; 1757 } 1758 } 1759 } 1760 } 1761 private final JLabel trainDetectionLabel = new JLabel(Bundle.getMessage("TrainDetection")); 1762 public final TrainDetectionJCombo trainDetectionComboBox 1763 = new TrainDetectionJCombo(); 1764 1765 protected static class TrainLengthUnitsJCombo extends JComboBox<TrainLengthUnitsItem> { 1766 public void setSelectedItemByValue(TrainLengthUnits var) { 1767 for ( int ix = 0; ix < getItemCount() ; ix ++ ) { 1768 if (getItemAt(ix).value == var) { 1769 this.setSelectedIndex(ix); 1770 break; 1771 } 1772 } 1773 } 1774 } 1775 public final TrainLengthUnitsJCombo trainLengthUnitsComboBox = new TrainLengthUnitsJCombo(); 1776 private final JLabel trainLengthLabel = new JLabel(Bundle.getMessage("MaxTrainLengthLabel")); 1777 private JLabel trainLengthAltLengthLabel; 1778 private final JSpinner maxTrainLengthSpinner = new JSpinner(); // initialized later 1779 1780 private void initializeAutoRunItems() { 1781 initializeRampCombo(); 1782 initializeScaleLengthBox(); 1783 pa1.setLayout(new FlowLayout()); 1784 pa1.add(speedFactorLabel); 1785 speedFactorSpinner.setModel(new SpinnerNumberModel(Float.valueOf(1.0f), Float.valueOf(0.1f), Float.valueOf(2.0f), Float.valueOf(0.01f))); 1786 speedFactorSpinner.setEditor(new JSpinner.NumberEditor(speedFactorSpinner, "# %")); 1787 pa1.add(speedFactorSpinner); 1788 speedFactorSpinner.setToolTipText(Bundle.getMessage("SpeedFactorHint")); 1789 pa1.add(new JLabel(" ")); 1790 pa1.add(maxSpeedLabel); 1791 maxSpeedSpinner.setModel(new SpinnerNumberModel(Float.valueOf(1.0f), Float.valueOf(0.1f), Float.valueOf(1.0f), Float.valueOf(0.01f))); 1792 maxSpeedSpinner.setEditor(new JSpinner.NumberEditor(maxSpeedSpinner, "# %")); 1793 pa1.add(maxSpeedSpinner); 1794 maxSpeedSpinner.setToolTipText(Bundle.getMessage("MaxSpeedHint")); 1795 pa1.add(minReliableOperatingSpeedLabel); 1796 minReliableOperatingSpeedSpinner.setModel(new SpinnerNumberModel(Float.valueOf(0.0f), Float.valueOf(0.0f), Float.valueOf(1.0f), Float.valueOf(0.01f))); 1797 minReliableOperatingSpeedSpinner.setEditor(new JSpinner.NumberEditor(minReliableOperatingSpeedSpinner, "# %")); 1798 pa1.add(minReliableOperatingSpeedSpinner); 1799 minReliableOperatingSpeedSpinner.setToolTipText(Bundle.getMessage("MinReliableOperatingSpeedHint")); 1800 initiatePane.add(pa1); 1801 pa2.setLayout(new FlowLayout()); 1802 pa2.add(rampRateLabel); 1803 pa2.add(rampRateBox); 1804 rampRateBox.setToolTipText(Bundle.getMessage("RampRateBoxHint")); 1805 pa2.add(useSpeedProfileLabel); 1806 pa2.add(useSpeedProfileCheckBox); 1807 useSpeedProfileCheckBox.setToolTipText(Bundle.getMessage("UseSpeedProfileHint")); 1808 initiatePane.add(pa2); 1809 pa2a.setLayout(new FlowLayout()); 1810 pa2a.add(stopBySpeedProfileLabel); 1811 pa2a.add(stopBySpeedProfileCheckBox); 1812 stopBySpeedProfileCheckBox.setToolTipText(Bundle.getMessage("UseSpeedProfileHint")); // reuse identical hint for Stop 1813 pa2a.add(stopBySpeedProfileAdjustLabel); 1814 stopBySpeedProfileAdjustSpinner.setModel(new SpinnerNumberModel( Float.valueOf(1.0f), Float.valueOf(0.1f), Float.valueOf(5.0f), Float.valueOf(0.01f))); 1815 stopBySpeedProfileAdjustSpinner.setEditor(new JSpinner.NumberEditor(stopBySpeedProfileAdjustSpinner, "# %")); 1816 pa2a.add(stopBySpeedProfileAdjustSpinner); 1817 stopBySpeedProfileAdjustSpinner.setToolTipText(Bundle.getMessage("StopBySpeedProfileAdjustHint")); 1818 initiatePane.add(pa2a); 1819 pa3.setLayout(new FlowLayout()); 1820 pa3.add(soundDecoderBox); 1821 soundDecoderBox.setToolTipText(Bundle.getMessage("SoundDecoderBoxHint")); 1822 pa3.add(new JLabel(" ")); 1823 pa3.add(runInReverseBox); 1824 runInReverseBox.setToolTipText(Bundle.getMessage("RunInReverseBoxHint")); 1825 initiatePane.add(pa3); 1826 maxTrainLengthSpinner.setModel(new SpinnerNumberModel(Float.valueOf(18.0f), Float.valueOf(0.0f), Float.valueOf(10000.0f), Float.valueOf(0.5f))); 1827 maxTrainLengthSpinner.setEditor(new JSpinner.NumberEditor(maxTrainLengthSpinner, "###0.0")); 1828 maxTrainLengthSpinner.setToolTipText(Bundle.getMessage("MaxTrainLengthHint")); // won't be updated while Dispatcher is open 1829 maxTrainLengthSpinner.addChangeListener(new ChangeListener() { 1830 @Override 1831 public void stateChanged(ChangeEvent e) { 1832 handlemaxTrainLengthChangeUnitsLength(e); 1833 } 1834 }); 1835 trainLengthUnitsComboBox.addActionListener(new ActionListener() { 1836 @Override 1837 public void actionPerformed(ActionEvent e) { 1838 handlemaxTrainLengthChangeUnitsLength(e); 1839 } 1840 }); 1841 trainLengthAltLengthLabel=new JLabel(); 1842 pa4.setLayout(new FlowLayout()); 1843 pa4.add(trainLengthLabel); 1844 pa4.add(maxTrainLengthSpinner); 1845 pa4.add(trainLengthUnitsComboBox); 1846 pa4.add(trainLengthAltLengthLabel); 1847 initiatePane.add(pa4); 1848 hideAutoRunItems(); // initialize with auto run items hidden 1849 } 1850 1851 private void handlemaxTrainLengthChangeUnitsLength(Object e) { 1852 trainLengthAltLengthLabel.setText(maxTrainLengthCalculateAltFormatted( 1853 ((TrainLengthUnitsItem) trainLengthUnitsComboBox.getSelectedItem()).getValue(), 1854 (float) maxTrainLengthSpinner.getValue())); 1855 } 1856 1857 private String maxTrainLengthCalculateAltFormatted(TrainLengthUnits fromUnits, float fromValue) { 1858 float value = maxTrainLengthCalculateAlt(fromUnits, fromValue); 1859 switch (fromUnits) { 1860 case TRAINLENGTH_ACTUALINCHS: 1861 return String.format("%.2f %s", value, Bundle.getMessage("TrainLengthInScaleFeet")); 1862 case TRAINLENGTH_ACTUALCM: 1863 return String.format("%.1f %s", value, Bundle.getMessage("TrainLengthInScaleMeters")); 1864 case TRAINLENGTH_SCALEFEET: 1865 return String.format("%.1f %s", value, Bundle.getMessage("TrainLengthInActualInchs")); 1866 case TRAINLENGTH_SCALEMETERS: 1867 return String.format("%.0f %s", value, Bundle.getMessage("TrainLengthInActualcm")); 1868 default: 1869 log.error("Invalid TrainLengthUnits must have been updated, fix maxTrainLengthCalculateAltFormatted"); 1870 } 1871 return ""; 1872 } 1873 1874 private float maxTrainLengthToScaleMeters(TrainLengthUnits fromUnits, float fromValue) { 1875 float value; 1876 // convert to meters. 1877 switch (fromUnits) { 1878 case TRAINLENGTH_ACTUALINCHS: 1879 value = fromValue / 12.0f * (float) _dispatcher.getScale().getScaleRatio(); 1880 value = value / 3.28084f; 1881 break; 1882 case TRAINLENGTH_ACTUALCM: 1883 value = fromValue / 100.0f * (float) _dispatcher.getScale().getScaleRatio(); 1884 break; 1885 case TRAINLENGTH_SCALEFEET: 1886 value = fromValue / 3.28084f; 1887 break; 1888 case TRAINLENGTH_SCALEMETERS: 1889 value = fromValue; 1890 break; 1891 default: 1892 value = 0; 1893 log.error("Invalid TrainLengthUnits has been updated, fix me"); 1894 } 1895 return value; 1896 } 1897 1898 /* 1899 * Calculates the reciprocal unit. Actual to Scale and vice versa 1900 */ 1901 private float maxTrainLengthCalculateAlt(TrainLengthUnits fromUnits, float fromValue) { 1902 switch (fromUnits) { 1903 case TRAINLENGTH_ACTUALINCHS: 1904 // calc scale feet 1905 return (float) jmri.util.MathUtil.granulize(fromValue / 12 * (float) _dispatcher.getScale().getScaleRatio(),0.1f); 1906 case TRAINLENGTH_ACTUALCM: 1907 // calc scale meter 1908 return fromValue / 100 * (float) _dispatcher.getScale().getScaleRatio(); 1909 case TRAINLENGTH_SCALEFEET: 1910 // calc actual inchs 1911 return fromValue * 12 * (float) _dispatcher.getScale().getScaleFactor(); 1912 case TRAINLENGTH_SCALEMETERS: 1913 // calc actual cm. 1914 return fromValue * 100 * (float) _dispatcher.getScale().getScaleFactor(); 1915 default: 1916 log.error("Invalid TrainLengthUnits has been updated, fix me"); 1917 } 1918 return 0; 1919 } 1920 1921 private void hideAutoRunItems() { 1922 pa1.setVisible(false); 1923 pa2.setVisible(false); 1924 pa2a.setVisible(false); 1925 pa3.setVisible(false); 1926 pa4.setVisible(false); 1927 } 1928 1929 private void showAutoRunItems() { 1930 pa1.setVisible(true); 1931 pa2.setVisible(true); 1932 pa2a.setVisible(true); 1933 pa3.setVisible(true); 1934 pa4.setVisible(true); 1935 } 1936 1937 private void autoTrainInfoToDialog(TrainInfo info) { 1938 speedFactorSpinner.setValue(info.getSpeedFactor()); 1939 maxSpeedSpinner.setValue(info.getMaxSpeed()); 1940 minReliableOperatingSpeedSpinner.setValue(info.getMinReliableOperatingSpeed()); 1941 setComboBox(rampRateBox, info.getRampRate()); 1942 trainDetectionComboBox.setSelectedItemByValue(info.getTrainDetection()); 1943 runInReverseBox.setSelected(info.getRunInReverse()); 1944 soundDecoderBox.setSelected(info.getSoundDecoder()); 1945 trainLengthUnitsComboBox.setSelectedItemByValue(info.getTrainLengthUnits()); 1946 switch (info.getTrainLengthUnits()) { 1947 case TRAINLENGTH_SCALEFEET: 1948 maxTrainLengthSpinner.setValue(info.getMaxTrainLengthScaleFeet()); 1949 break; 1950 case TRAINLENGTH_SCALEMETERS: 1951 maxTrainLengthSpinner.setValue(info.getMaxTrainLengthScaleMeters()); 1952 break; 1953 case TRAINLENGTH_ACTUALINCHS: 1954 maxTrainLengthSpinner.setValue(info.getMaxTrainLengthScaleFeet() * 12.0f * (float)_dispatcher.getScale().getScaleFactor()); 1955 break; 1956 case TRAINLENGTH_ACTUALCM: 1957 maxTrainLengthSpinner.setValue(info.getMaxTrainLengthScaleMeters() * 100.0f * (float)_dispatcher.getScale().getScaleFactor()); 1958 break; 1959 default: 1960 maxTrainLengthSpinner.setValue(0.0f); 1961 } 1962 useSpeedProfileCheckBox.setSelected(info.getUseSpeedProfile()); 1963 stopBySpeedProfileCheckBox.setSelected(info.getStopBySpeedProfile()); 1964 stopBySpeedProfileAdjustSpinner.setValue(info.getStopBySpeedProfileAdjust()); 1965 if (autoRunBox.isSelected()) { 1966 showAutoRunItems(); 1967 } else { 1968 hideAutoRunItems(); 1969 } 1970 initiateFrame.pack(); 1971 } 1972 1973 private void autoRunItemsToTrainInfo(TrainInfo info) { 1974 info.setSpeedFactor((float) speedFactorSpinner.getValue()); 1975 info.setMaxSpeed((float) maxSpeedSpinner.getValue()); 1976 info.setMinReliableOperatingSpeed((float) minReliableOperatingSpeedSpinner.getValue()); 1977 info.setRampRate((String) rampRateBox.getSelectedItem()); 1978 info.setRunInReverse(runInReverseBox.isSelected()); 1979 info.setSoundDecoder(soundDecoderBox.isSelected()); 1980 info.setTrainLengthUnits(((TrainLengthUnitsItem) trainLengthUnitsComboBox.getSelectedItem()).getValue()); 1981 info.setMaxTrainLengthScaleMeters(maxTrainLengthToScaleMeters( info.getTrainLengthUnits(), (float) maxTrainLengthSpinner.getValue())); 1982 1983 // Only use speed profile values if enabled 1984 if (useSpeedProfileCheckBox.isEnabled()) { 1985 info.setUseSpeedProfile(useSpeedProfileCheckBox.isSelected()); 1986 info.setStopBySpeedProfile(stopBySpeedProfileCheckBox.isSelected()); 1987 info.setStopBySpeedProfileAdjust((float) stopBySpeedProfileAdjustSpinner.getValue()); 1988 } else { 1989 info.setUseSpeedProfile(false); 1990 info.setStopBySpeedProfile(false); 1991 info.setStopBySpeedProfileAdjust(1.0f); 1992 } 1993 } 1994 1995 private void initializeRampCombo() { 1996 rampRateBox.removeAllItems(); 1997 rampRateBox.addItem(Bundle.getMessage("RAMP_NONE")); 1998 rampRateBox.addItem(Bundle.getMessage("RAMP_FAST")); 1999 rampRateBox.addItem(Bundle.getMessage("RAMP_MEDIUM")); 2000 rampRateBox.addItem(Bundle.getMessage("RAMP_MED_SLOW")); 2001 rampRateBox.addItem(Bundle.getMessage("RAMP_SLOW")); 2002 rampRateBox.addItem(Bundle.getMessage("RAMP_SPEEDPROFILE")); 2003 // Note: the order above must correspond to the numbers in AutoActiveTrain.java 2004 } 2005 2006 /** 2007 * Sets up the RadioButtons and visability of spinner for the allocation method 2008 * 2009 * @param value 0, Allocate by Safe spots, -1, allocate as far as possible Any 2010 * other value the number of sections to allocate 2011 */ 2012 private void setAllocateMethodButtons(int value) { 2013 switch (value) { 2014 case ActiveTrain.ALLOCATE_BY_SAFE_SECTIONS: 2015 allocateBySafeRadioButton.setSelected(true); 2016 allocateCustomSpinner.setVisible(false); 2017 break; 2018 case ActiveTrain.ALLOCATE_AS_FAR_AS_IT_CAN: 2019 allocateAllTheWayRadioButton.setSelected(true); 2020 allocateCustomSpinner.setVisible(false); 2021 break; 2022 default: 2023 allocateNumberOfBlocks.setSelected(true); 2024 allocateCustomSpinner.setVisible(true); 2025 allocateCustomSpinner.setValue(value); 2026 } 2027 } 2028 2029 /* 2030 * Layout block stuff 2031 */ 2032 private ArrayList<LayoutBlock> getOccupiedBlockList() { 2033 LayoutBlockManager lBM = jmri.InstanceManager.getDefault(LayoutBlockManager.class); 2034 ArrayList<LayoutBlock> lBlocks = new ArrayList<LayoutBlock>(); 2035 for (LayoutBlock lB : lBM.getNamedBeanSet()) { 2036 if (lB.getBlock().getState() == Block.OCCUPIED) { 2037 lBlocks.add(lB); 2038 } 2039 } 2040 return lBlocks; 2041 } 2042 2043 private void initializeStartingBlockComboDynamic() { 2044 startingBlockBox.removeAllItems(); 2045 startingBlockBoxList.clear(); 2046 for (LayoutBlock lB: getOccupiedBlockList()) { 2047 if (!startingBlockBoxList.contains(lB.getBlock())) { 2048 startingBlockBoxList.add(lB.getBlock()); 2049 startingBlockBox.addItem(getBlockName(lB.getBlock())); 2050 } 2051 } 2052 JComboBoxUtil.setupComboBoxMaxRows(startingBlockBox); 2053 } 2054 2055 private void initializeViaBlockDynamicCombo() { 2056 String prevValue = (String) viaBlockBox.getSelectedItem(); 2057 viaBlockBox.removeActionListener(viaBlockBoxListener); 2058 viaBlockBox.removeAllItems(); 2059 viaBlockBoxList.clear(); 2060 LayoutBlockManager lBM = jmri.InstanceManager.getDefault(LayoutBlockManager.class); 2061 if (startingBlockBox.getSelectedItem() != null) { 2062 LayoutBlock lBSrc = null; 2063 if (startingBlockBox.getSelectedIndex() >= 0) { 2064 lBSrc = lBM.getByUserName((String) startingBlockBox.getSelectedItem()); 2065 if (lBSrc != null) { 2066 int rX = lBSrc.getNumberOfNeighbours() - 1; 2067 for (; rX > -1; rX--) { 2068 viaBlockBox.addItem(lBSrc.getNeighbourAtIndex(rX).getDisplayName()); 2069 viaBlockBoxList.add(lBSrc.getNeighbourAtIndex(rX)); 2070 } 2071 } 2072 } 2073 } 2074 if (prevValue != null) { 2075 viaBlockBox.setSelectedItem(prevValue); 2076 } 2077 viaBlockBox.addActionListener(viaBlockBoxListener); 2078 } 2079 2080 private void initializeDestinationBlockDynamicCombo() { 2081 destinationBlockBox.removeAllItems(); 2082 destinationBlockBoxList.clear(); 2083 LayoutBlockManager lBM = jmri.InstanceManager.getDefault(LayoutBlockManager.class); 2084 if (startingBlockBox.getSelectedItem() != null) { 2085 LayoutBlock lBSrc = null; 2086 if (startingBlockBox.getSelectedIndex() >= 0 2087 && viaBlockBox.getSelectedIndex() >= 0) { 2088 lBSrc = lBM.getByUserName((String) startingBlockBox.getSelectedItem()); 2089 Block b = viaBlockBoxList.get(viaBlockBox.getSelectedIndex()); 2090 if (lBSrc != null) { 2091 int rX = lBSrc.getNumberOfRoutes() - 1; 2092 for (; rX > -1; rX--) { 2093 if (lBSrc.getRouteNextBlockAtIndex(rX) == b) { 2094 destinationBlockBox.addItem(lBSrc.getRouteDestBlockAtIndex(rX).getDisplayName()); 2095 destinationBlockBoxList.add(lBSrc.getRouteDestBlockAtIndex(rX)); 2096 } 2097 } 2098 } 2099 } 2100 } 2101 } 2102 /* 2103 * ComboBox item. 2104 */ 2105 protected static class TrainDetectionItem { 2106 private String key; 2107 private TrainDetection value; 2108 public TrainDetectionItem(String text, TrainDetection trainDetection ) { 2109 this.key = text; 2110 this.value = trainDetection; 2111 } 2112 @Override 2113 public String toString() 2114 { 2115 return key; 2116 } 2117 public String getKey() 2118 { 2119 return key; 2120 } 2121 public TrainDetection getValue() 2122 { 2123 return value; 2124 } 2125 } 2126 2127 /* 2128 * ComboBox item. 2129 */ 2130 protected static class TrainLengthUnitsItem { 2131 private String key; 2132 private TrainLengthUnits value; 2133 public TrainLengthUnitsItem(String text, TrainLengthUnits trainLength ) { 2134 this.key = text; 2135 this.value = trainLength; 2136 } 2137 @Override 2138 public String toString() 2139 { 2140 return key; 2141 } 2142 public String getKey() 2143 { 2144 return key; 2145 } 2146 public TrainLengthUnits getValue() 2147 { 2148 return value; 2149 } 2150 } 2151 2152 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ActivateTrainFrame.class); 2153 2154}