001package jmri.jmrit.dispatcher; 002 003import java.awt.Container; 004import java.awt.FlowLayout; 005import java.awt.event.ActionEvent; 006import java.awt.event.ActionListener; 007import java.awt.event.ItemEvent; 008import java.awt.event.ItemListener; 009import java.util.ArrayList; 010import java.util.HashSet; 011import java.util.List; 012import java.util.Set; 013 014import javax.swing.BorderFactory; 015import javax.swing.BoxLayout; 016import javax.swing.ButtonGroup; 017import javax.swing.JButton; 018import javax.swing.JCheckBox; 019import javax.swing.JComboBox; 020import javax.swing.JLabel; 021import javax.swing.JPanel; 022import javax.swing.JRadioButton; 023import javax.swing.JScrollPane; 024import javax.swing.JSeparator; 025import javax.swing.JSpinner; 026import javax.swing.JTextField; 027import javax.swing.SpinnerNumberModel; 028 029import jmri.Block; 030import jmri.InstanceManager; 031import jmri.Sensor; 032import jmri.Transit; 033import jmri.TransitManager; 034import jmri.jmrit.dispatcher.ActiveTrain.TrainDetection; 035import jmri.jmrit.dispatcher.DispatcherFrame.TrainsFrom; 036import jmri.jmrit.operations.trains.Train; 037import jmri.jmrit.operations.trains.TrainManager; 038import jmri.jmrit.roster.RosterEntry; 039import jmri.jmrit.roster.swing.RosterEntryComboBox; 040import jmri.swing.NamedBeanComboBox; 041import jmri.util.JmriJFrame; 042import jmri.util.swing.JComboBoxUtil; 043import jmri.util.swing.JmriJOptionPane; 044 045/** 046 * Displays the Activate New Train dialog and processes information entered 047 * there. 048 * <p> 049 * This module works with Dispatcher, which initiates the display of the dialog. 050 * Dispatcher also creates the ActiveTrain. 051 * <p> 052 * This file is part of JMRI. 053 * <p> 054 * JMRI is open source software; you can redistribute it and/or modify it under 055 * the terms of version 2 of the GNU General Public License as published by the 056 * Free Software Foundation. See the "COPYING" file for a copy of this license. 057 * <p> 058 * JMRI is distributed in the hope that it will be useful, but WITHOUT ANY 059 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 060 * A PARTICULAR PURPOSE. See the GNU General Public License for more details. 061 * 062 * @author Dave Duchamp Copyright (C) 2009 063 */ 064public class ActivateTrainFrame extends JmriJFrame { 065 066 public ActivateTrainFrame(DispatcherFrame d) { 067 super(true,true); 068 _dispatcher = d; 069 _tiFile = new TrainInfoFile(); 070 } 071 072 // operational instance variables 073 private DispatcherFrame _dispatcher = null; 074 private TrainInfoFile _tiFile = null; 075 private final TransitManager _TransitManager = InstanceManager.getDefault(jmri.TransitManager.class); 076 private String _trainInfoName = ""; 077 078 // initiate train window variables 079 private Transit selectedTransit = null; 080 //private String selectedTrain = ""; 081 private JmriJFrame initiateFrame = null; 082 private Container initiatePane = null; 083 private final jmri.swing.NamedBeanComboBox<Transit> transitSelectBox = new jmri.swing.NamedBeanComboBox<>(_TransitManager); 084 private final JLabel trainBoxLabel = new JLabel(" " + Bundle.getMessage("TrainBoxLabel") + ":"); 085 private final JComboBox<Object> trainSelectBox = new JComboBox<>(); 086 // private final List<RosterEntry> trainBoxList = new ArrayList<>(); 087 private RosterEntryComboBox rosterComboBox = null; 088 private final JLabel trainFieldLabel = new JLabel(Bundle.getMessage("TrainBoxLabel") + ":"); 089 private final JTextField trainNameField = new JTextField(10); 090 private final JLabel dccAddressFieldLabel = new JLabel(" " + Bundle.getMessage("DccAddressFieldLabel") + ":"); 091 private final JSpinner dccAddressSpinner = new JSpinner(new SpinnerNumberModel(3, 1, 9999, 1)); 092 private final JCheckBox inTransitBox = new JCheckBox(Bundle.getMessage("TrainInTransit")); 093 private final JComboBox<String> startingBlockBox = new JComboBox<>(); 094 private List<Block> startingBlockBoxList = new ArrayList<>(); 095 private List<Integer> startingBlockSeqList = new ArrayList<>(); 096 private final JComboBox<String> destinationBlockBox = new JComboBox<>(); 097 private List<Block> destinationBlockBoxList = new ArrayList<>(); 098 private List<Integer> destinationBlockSeqList = new ArrayList<>(); 099 private JButton addNewTrainButton = null; 100 private JButton loadButton = null; 101 private JButton saveButton = null; 102 private JButton deleteButton = null; 103 private final JCheckBox autoRunBox = new JCheckBox(Bundle.getMessage("AutoRun")); 104 private final JCheckBox loadAtStartupBox = new JCheckBox(Bundle.getMessage("LoadAtStartup")); 105 106 private final JRadioButton radioTrainsFromRoster = new JRadioButton(Bundle.getMessage("TrainsFromRoster")); 107 private final JRadioButton radioTrainsFromOps = new JRadioButton(Bundle.getMessage("TrainsFromTrains")); 108 private final JRadioButton radioTrainsFromUser = new JRadioButton(Bundle.getMessage("TrainsFromUser")); 109 private final JRadioButton radioTrainsFromSetLater = new JRadioButton(Bundle.getMessage("TrainsFromSetLater")); 110 private final ButtonGroup trainsFromButtonGroup = new ButtonGroup(); 111 112 private final JRadioButton allocateBySafeRadioButton = new JRadioButton(Bundle.getMessage("ToSafeSections")); 113 private final JRadioButton allocateAllTheWayRadioButton = new JRadioButton(Bundle.getMessage("AsFarAsPos")); 114 private final JRadioButton allocateNumberOfBlocks = new JRadioButton(Bundle.getMessage("NumberOfBlocks") + ":"); 115 private final ButtonGroup allocateMethodButtonGroup = new ButtonGroup(); 116 private final JSpinner allocateCustomSpinner = new JSpinner(new SpinnerNumberModel(3, 1, 100, 1)); 117 private final JCheckBox terminateWhenDoneBox = new JCheckBox(Bundle.getMessage("TerminateWhenDone")); 118 private final JPanel terminateWhenDoneDetails = new JPanel(); 119 private final JComboBox<String> nextTrain = new JComboBox<>(); 120 private final JLabel nextTrainLabel = new JLabel(Bundle.getMessage("TerminateWhenDoneNextTrain")); 121 private final JSpinner prioritySpinner = new JSpinner(new SpinnerNumberModel(5, 0, 100, 1)); 122 private final JCheckBox resetWhenDoneBox = new JCheckBox(Bundle.getMessage("ResetWhenDone")); 123 private final JCheckBox reverseAtEndBox = new JCheckBox(Bundle.getMessage("ReverseAtEnd")); 124 125 int delayedStartInt[] = new int[]{ActiveTrain.NODELAY, ActiveTrain.TIMEDDELAY, ActiveTrain.SENSORDELAY}; 126 String delayedStartString[] = new String[]{Bundle.getMessage("DelayedStartNone"), Bundle.getMessage("DelayedStartTimed"), Bundle.getMessage("DelayedStartSensor")}; 127 128 private final JComboBox<String> reverseDelayedRestartType = new JComboBox<>(delayedStartString); 129 private final JLabel delayReverseReStartLabel = new JLabel(Bundle.getMessage("DelayRestart")); 130 private final JLabel delayReverseReStartSensorLabel = new JLabel(Bundle.getMessage("RestartSensor")); 131 private final JCheckBox delayReverseResetSensorBox = new JCheckBox(Bundle.getMessage("ResetRestartSensor")); 132 private final NamedBeanComboBox<Sensor> delayReverseReStartSensor = new NamedBeanComboBox<>(jmri.InstanceManager.sensorManagerInstance()); 133 private final JSpinner delayReverseMinSpinner = new JSpinner(new SpinnerNumberModel(0, 0, 1000, 1)); 134 private final JLabel delayReverseMinLabel = new JLabel(Bundle.getMessage("RestartTimed")); 135 136 private final JCheckBox resetStartSensorBox = new JCheckBox(Bundle.getMessage("ResetStartSensor")); 137 private final JComboBox<String> delayedStartBox = new JComboBox<>(delayedStartString); 138 private final JLabel delayedReStartLabel = new JLabel(Bundle.getMessage("DelayRestart")); 139 private final JLabel delayReStartSensorLabel = new JLabel(Bundle.getMessage("RestartSensor")); 140 private final JCheckBox resetRestartSensorBox = new JCheckBox(Bundle.getMessage("ResetRestartSensor")); 141 private final JComboBox<String> delayedReStartBox = new JComboBox<>(delayedStartString); 142 private final NamedBeanComboBox<Sensor> delaySensor = new NamedBeanComboBox<>(jmri.InstanceManager.sensorManagerInstance()); 143 private final NamedBeanComboBox<Sensor> delayReStartSensor = new NamedBeanComboBox<>(jmri.InstanceManager.sensorManagerInstance()); 144 145 private final JSpinner departureHrSpinner = new JSpinner(new SpinnerNumberModel(8, 0, 23, 1)); 146 private final JSpinner departureMinSpinner = new JSpinner(new SpinnerNumberModel(0, 0, 59, 1)); 147 private final JLabel departureTimeLabel = new JLabel(Bundle.getMessage("DepartureTime")); 148 private final JLabel departureSepLabel = new JLabel(":"); 149 150 private final JSpinner delayMinSpinner = new JSpinner(new SpinnerNumberModel(0, 0, 1000, 1)); 151 private final JLabel delayMinLabel = new JLabel(Bundle.getMessage("RestartTimed")); 152 153 private final JComboBox<String> trainTypeBox = new JComboBox<>(); 154 // Note: See also items related to automatically running trains near the end of this module 155 156 boolean transitsFromSpecificBlock = false; 157 158 private TrainInfo trainInfo; 159 160 /** 161 * Open up a new train window for a given roster entry located in a specific 162 * block. 163 * 164 * @param e the action event triggering the new window 165 * @param re the roster entry to open the new window for 166 * @param b the block where the train is located 167 */ 168 public void initiateTrain(ActionEvent e, RosterEntry re, Block b) { 169 initiateTrain(e); 170 if (trainInfo.getTrainsFrom() == TrainsFrom.TRAINSFROMROSTER && re != null) { 171 setRosterComboBox(rosterComboBox, re.getId()); 172 //Add in some bits of code as some point to filter down the transits that can be used. 173 } 174 if (b != null && selectedTransit != null) { 175 List<Transit> transitList = _TransitManager.getListUsingBlock(b); 176 List<Transit> transitEntryList = _TransitManager.getListEntryBlock(b); 177 for (Transit t : transitEntryList) { 178 if (!transitList.contains(t)) { 179 transitList.add(t); 180 } 181 } 182 transitsFromSpecificBlock = true; 183 initializeFreeTransitsCombo(transitList); 184 List<Block> tmpBlkList = new ArrayList<>(); 185 if (selectedTransit.getEntryBlocksList().contains(b)) { 186 tmpBlkList = selectedTransit.getEntryBlocksList(); 187 inTransitBox.setSelected(false); 188 } else if (selectedTransit.containsBlock(b)) { 189 tmpBlkList = selectedTransit.getInternalBlocksList(); 190 inTransitBox.setSelected(true); 191 } 192 List<Integer> tmpSeqList = selectedTransit.getBlockSeqList(); 193 for (int i = 0; i < tmpBlkList.size(); i++) { 194 if (tmpBlkList.get(i) == b) { 195 setComboBox(startingBlockBox, getBlockName(b) + "-" + tmpSeqList.get(i)); 196 break; 197 } 198 } 199 } 200 } 201 202 /** 203 * Displays a window that allows a new ActiveTrain to be activated. 204 * <p> 205 * Called by Dispatcher in response to the dispatcher clicking the New Train 206 * button. 207 * 208 * @param e the action event triggering the window display 209 */ 210 protected void initiateTrain(ActionEvent e) { 211 // set Dispatcher defaults 212 // create window if needed 213 trainInfo = new TrainInfo(); 214 trainInfo.setTrainsFrom(_dispatcher.getTrainsFrom()); 215 216 if (initiateFrame == null) { 217 initiateFrame = this; 218 initiateFrame.setTitle(Bundle.getMessage("AddTrainTitle")); 219 initiateFrame.addHelpMenu("package.jmri.jmrit.dispatcher.NewTrain", true); 220 initiatePane = initiateFrame.getContentPane(); 221 initiatePane.setLayout(new BoxLayout(initiatePane, BoxLayout.Y_AXIS)); 222 223 // add buttons to load and save train information 224 JPanel p0 = new JPanel(); 225 p0.setLayout(new FlowLayout()); 226 p0.add(loadButton = new JButton(Bundle.getMessage("LoadButton"))); 227 loadButton.addActionListener(new ActionListener() { 228 @Override 229 public void actionPerformed(ActionEvent e) { 230 loadTrainInfo(e); 231 } 232 }); 233 loadButton.setToolTipText(Bundle.getMessage("LoadButtonHint")); 234 p0.add(saveButton = new JButton(Bundle.getMessage("SaveButton"))); 235 saveButton.addActionListener(new ActionListener() { 236 @Override 237 public void actionPerformed(ActionEvent e) { 238 saveTrainInfo(e); 239 } 240 }); 241 saveButton.setToolTipText(Bundle.getMessage("SaveButtonHint")); 242 p0.add(deleteButton = new JButton(Bundle.getMessage("DeleteButton"))); 243 deleteButton.addActionListener(new ActionListener() { 244 @Override 245 public void actionPerformed(ActionEvent e) { 246 deleteTrainInfo(e); 247 } 248 }); 249 deleteButton.setToolTipText(Bundle.getMessage("DeleteButtonHint")); 250 251 // add items relating to both manually run and automatic trains. 252 253 // Trains From choices. 254 JPanel p0a = new JPanel(); 255 p0a.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("TrainsFrom"))); 256 p0a.setLayout(new FlowLayout()); 257 radioTrainsFromRoster.setActionCommand("TRAINSFROMROSTER"); 258 trainsFromButtonGroup.add(radioTrainsFromRoster); 259 radioTrainsFromOps.setActionCommand("TRAINSFROMOPS"); 260 trainsFromButtonGroup.add(radioTrainsFromOps); 261 radioTrainsFromUser.setActionCommand("TRAINSFROMUSER"); 262 trainsFromButtonGroup.add(radioTrainsFromUser); 263 radioTrainsFromSetLater.setActionCommand("TRAINSFROMSETLATER"); 264 trainsFromButtonGroup.add(radioTrainsFromSetLater); 265 p0a.add(radioTrainsFromRoster); 266 radioTrainsFromRoster.setToolTipText(Bundle.getMessage("TrainsFromRosterHint")); 267 p0a.add(radioTrainsFromOps); 268 radioTrainsFromOps.setToolTipText(Bundle.getMessage("TrainsFromTrainsHint")); 269 p0a.add(radioTrainsFromUser); 270 radioTrainsFromUser.setToolTipText(Bundle.getMessage("TrainsFromUserHint")); 271 p0a.add(radioTrainsFromSetLater); 272 radioTrainsFromSetLater.setToolTipText(Bundle.getMessage("TrainsFromSetLaterHint")); 273 274 radioTrainsFromOps.addItemListener(new ItemListener() { 275 @Override 276 public void itemStateChanged(ItemEvent e) { 277 if (e.getStateChange() == ItemEvent.SELECTED) { 278 trainInfo.setTrainsFrom(TrainsFrom.TRAINSFROMOPS); 279 setTrainsFromOptions(trainInfo.getTrainsFrom()); 280 } 281 } 282 }); 283 284 radioTrainsFromRoster.addItemListener(new ItemListener() { 285 @Override 286 public void itemStateChanged(ItemEvent e) { 287 if (e.getStateChange() == ItemEvent.SELECTED) { 288 trainInfo.setTrainsFrom(TrainsFrom.TRAINSFROMROSTER); 289 setTrainsFromOptions(trainInfo.getTrainsFrom()); 290 } 291 } 292 }); 293 radioTrainsFromUser.addItemListener(new ItemListener() { 294 @Override 295 public void itemStateChanged(ItemEvent e) { 296 if (e.getStateChange() == ItemEvent.SELECTED) { 297 trainInfo.setTrainsFrom(TrainsFrom.TRAINSFROMUSER); 298 setTrainsFromOptions(trainInfo.getTrainsFrom()); 299 } 300 } 301 }); 302 radioTrainsFromSetLater.addItemListener(new ItemListener() { 303 @Override 304 public void itemStateChanged(ItemEvent e) { 305 if (e.getStateChange() == ItemEvent.SELECTED) { 306 trainInfo.setTrainsFrom(TrainsFrom.TRAINSFROMSETLATER); 307 setTrainsFromOptions(trainInfo.getTrainsFrom()); 308 } 309 } 310 }); 311 p0a.add(allocateCustomSpinner); 312 initiatePane.add(p0a); 313 314 JPanel p1 = new JPanel(); 315 p1.setLayout(new FlowLayout()); 316 p1.add(new JLabel(Bundle.getMessage("TransitBoxLabel") + " :")); 317 p1.add(transitSelectBox); 318 transitSelectBox.addActionListener(new ActionListener() { 319 @Override 320 public void actionPerformed(ActionEvent e) { 321 handleTransitSelectionChanged(e); 322 } 323 }); 324 transitSelectBox.setToolTipText(Bundle.getMessage("TransitBoxHint")); 325 p1.add(trainBoxLabel); 326 p1.add(trainSelectBox); 327 trainSelectBox.addActionListener(new ActionListener() { 328 @Override 329 public void actionPerformed(ActionEvent e) { 330 handleTrainSelectionChanged(); 331 } 332 }); 333 trainSelectBox.setToolTipText(Bundle.getMessage("TrainBoxHint")); 334 335 rosterComboBox = new RosterEntryComboBox(); 336 initializeFreeRosterEntriesCombo(); 337 rosterComboBox.addActionListener(new ActionListener() { 338 @Override 339 public void actionPerformed(ActionEvent e) { 340 handleRosterSelectionChanged(e); 341 } 342 }); 343 p1.add(rosterComboBox); 344 345 initiatePane.add(p1); 346 JPanel p1a = new JPanel(); 347 p1a.setLayout(new FlowLayout()); 348 p1a.add(trainFieldLabel); 349 p1a.add(trainNameField); 350 trainNameField.setToolTipText(Bundle.getMessage("TrainFieldHint")); 351 p1a.add(dccAddressFieldLabel); 352 p1a.add(dccAddressSpinner); 353 dccAddressSpinner.setToolTipText(Bundle.getMessage("DccAddressFieldHint")); 354 initiatePane.add(p1a); 355 JPanel p2 = new JPanel(); 356 p2.setLayout(new FlowLayout()); 357 p2.add(inTransitBox); 358 inTransitBox.addActionListener(new ActionListener() { 359 @Override 360 public void actionPerformed(ActionEvent e) { 361 handleInTransitClick(e); 362 } 363 }); 364 inTransitBox.setToolTipText(Bundle.getMessage("InTransitBoxHint")); 365 initiatePane.add(p2); 366 JPanel p3 = new JPanel(); 367 p3.setLayout(new FlowLayout()); 368 p3.add(new JLabel(Bundle.getMessage("StartingBlockBoxLabel") + " :")); 369 p3.add(startingBlockBox); 370 startingBlockBox.setToolTipText(Bundle.getMessage("StartingBlockBoxHint")); 371 startingBlockBox.addActionListener(new ActionListener() { 372 @Override 373 public void actionPerformed(ActionEvent e) { 374 handleStartingBlockSelectionChanged(e); 375 } 376 }); 377 initiatePane.add(p3); 378 JPanel p4 = new JPanel(); 379 p4.setLayout(new FlowLayout()); 380 p4.add(new JLabel(Bundle.getMessage("DestinationBlockBoxLabel") + ":")); 381 p4.add(destinationBlockBox); 382 destinationBlockBox.setToolTipText(Bundle.getMessage("DestinationBlockBoxHint")); 383 JPanel p4a = new JPanel(); 384 initiatePane.add(p4); 385 p4a.add(trainDetectionLabel); 386 initializeTrainDetectionBox(); 387 p4a.add(trainDetectionComboBox); 388 trainDetectionComboBox.setToolTipText(Bundle.getMessage("TrainDetectionBoxHint")); 389 initiatePane.add(p4a); 390 JPanel p4b = new JPanel(); 391 p4b.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("AllocateMethodLabel"))); 392 p4b.setLayout(new FlowLayout()); 393 allocateMethodButtonGroup.add(allocateAllTheWayRadioButton); 394 allocateMethodButtonGroup.add(allocateBySafeRadioButton); 395 allocateMethodButtonGroup.add(allocateNumberOfBlocks); 396 p4b.add(allocateAllTheWayRadioButton); 397 allocateAllTheWayRadioButton.setToolTipText(Bundle.getMessage("AllocateAllTheWayHint")); 398 p4b.add(allocateBySafeRadioButton); 399 allocateBySafeRadioButton.setToolTipText(Bundle.getMessage("AllocateSafeHint")); 400 p4b.add(allocateNumberOfBlocks); 401 allocateNumberOfBlocks.setToolTipText(Bundle.getMessage("AllocateMethodHint")); 402 allocateAllTheWayRadioButton.addActionListener(new ActionListener() { 403 @Override 404 public void actionPerformed(ActionEvent e) { 405 handleAllocateAllTheWayButtonChanged(e); 406 } 407 }); 408 allocateBySafeRadioButton.addActionListener(new ActionListener() { 409 @Override 410 public void actionPerformed(ActionEvent e) { 411 handleAllocateBySafeButtonChanged(e); 412 } 413 }); 414 allocateNumberOfBlocks.addActionListener(new ActionListener() { 415 @Override 416 public void actionPerformed(ActionEvent e) { 417 handleAllocateNumberOfBlocksButtonChanged(e); 418 } 419 }); 420 p4b.add(allocateCustomSpinner); 421 allocateCustomSpinner.setToolTipText(Bundle.getMessage("AllocateMethodHint")); 422 initiatePane.add(p4b); 423 JPanel p6 = new JPanel(); 424 p6.setLayout(new FlowLayout()); 425 p6.add(resetWhenDoneBox); 426 resetWhenDoneBox.addActionListener(new ActionListener() { 427 @Override 428 public void actionPerformed(ActionEvent e) { 429 handleResetWhenDoneClick(e); 430 } 431 }); 432 resetWhenDoneBox.setToolTipText(Bundle.getMessage("ResetWhenDoneBoxHint")); 433 initiatePane.add(p6); 434 JPanel p6a = new JPanel(); 435 p6a.setLayout(new FlowLayout()); 436 ((FlowLayout) p6a.getLayout()).setVgap(1); 437 p6a.add(delayedReStartLabel); 438 p6a.add(delayedReStartBox); 439 p6a.add(resetRestartSensorBox); 440 resetRestartSensorBox.setToolTipText(Bundle.getMessage("ResetRestartSensorHint")); 441 resetRestartSensorBox.setSelected(true); 442 delayedReStartBox.addActionListener(new ActionListener() { 443 @Override 444 public void actionPerformed(ActionEvent e) { 445 handleResetWhenDoneClick(e); 446 } 447 }); 448 delayedReStartBox.setToolTipText(Bundle.getMessage("DelayedReStartHint")); 449 initiatePane.add(p6a); 450 451 JPanel p6b = new JPanel(); 452 p6b.setLayout(new FlowLayout()); 453 ((FlowLayout) p6b.getLayout()).setVgap(1); 454 p6b.add(delayMinLabel); 455 p6b.add(delayMinSpinner); // already set to 0 456 delayMinSpinner.setToolTipText(Bundle.getMessage("RestartTimedHint")); 457 p6b.add(delayReStartSensorLabel); 458 p6b.add(delayReStartSensor); 459 delayReStartSensor.setAllowNull(true); 460 handleResetWhenDoneClick(null); 461 initiatePane.add(p6b); 462 463 initiatePane.add(new JSeparator()); 464 465 JPanel p10 = new JPanel(); 466 p10.setLayout(new FlowLayout()); 467 p10.add(reverseAtEndBox); 468 reverseAtEndBox.setToolTipText(Bundle.getMessage("ReverseAtEndBoxHint")); 469 initiatePane.add(p10); 470 reverseAtEndBox.addActionListener(new ActionListener() { 471 @Override 472 public void actionPerformed(ActionEvent e) { 473 handleReverseAtEndBoxClick(e); 474 } 475 }); 476 JPanel pDelayReverseRestartDetails = new JPanel(); 477 pDelayReverseRestartDetails.setLayout(new FlowLayout()); 478 ((FlowLayout) pDelayReverseRestartDetails.getLayout()).setVgap(1); 479 pDelayReverseRestartDetails.add(delayReverseReStartLabel); 480 pDelayReverseRestartDetails.add(reverseDelayedRestartType); 481 pDelayReverseRestartDetails.add(delayReverseResetSensorBox); 482 delayReverseResetSensorBox.setToolTipText(Bundle.getMessage("ReverseResetRestartSensorHint")); 483 delayReverseResetSensorBox.setSelected(true); 484 reverseDelayedRestartType.addActionListener(new ActionListener() { 485 @Override 486 public void actionPerformed(ActionEvent e) { 487 handleReverseAtEndBoxClick(e); 488 } 489 }); 490 reverseDelayedRestartType.setToolTipText(Bundle.getMessage("ReverseDelayedReStartHint")); 491 initiatePane.add(pDelayReverseRestartDetails); 492 493 JPanel pDelayReverseRestartDetails2 = new JPanel(); 494 pDelayReverseRestartDetails2.setLayout(new FlowLayout()); 495 ((FlowLayout) pDelayReverseRestartDetails2.getLayout()).setVgap(1); 496 pDelayReverseRestartDetails2.add(delayReverseMinLabel); 497 pDelayReverseRestartDetails2.add(delayReverseMinSpinner); // already set to 0 498 delayReverseMinSpinner.setToolTipText(Bundle.getMessage("ReverseRestartTimedHint")); 499 pDelayReverseRestartDetails2.add(delayReverseReStartSensorLabel); 500 pDelayReverseRestartDetails2.add(delayReverseReStartSensor); 501 delayReverseReStartSensor.setAllowNull(true); 502 handleReverseAtEndBoxClick(null); 503 initiatePane.add(pDelayReverseRestartDetails2); 504 505 initiatePane.add(new JSeparator()); 506 507 JPanel p10a = new JPanel(); 508 p10a.setLayout(new FlowLayout()); 509 p10a.add(terminateWhenDoneBox); 510 terminateWhenDoneBox.addActionListener(new ActionListener() { 511 @Override 512 public void actionPerformed(ActionEvent e) { 513 handleTerminateWhenDoneBoxClick(e); 514 } 515 }); 516 initiatePane.add(p10a); 517 terminateWhenDoneDetails.setLayout(new FlowLayout()); 518 terminateWhenDoneDetails.add(nextTrainLabel); 519 terminateWhenDoneDetails.add(nextTrain); 520 nextTrain.setToolTipText(Bundle.getMessage("TerminateWhenDoneNextTrainHint")); 521 initiatePane.add(terminateWhenDoneDetails); 522 handleTerminateWhenDoneBoxClick(null); 523 524 initiatePane.add(new JSeparator()); 525 526 JPanel p8 = new JPanel(); 527 p8.setLayout(new FlowLayout()); 528 p8.add(new JLabel(Bundle.getMessage("PriorityLabel") + ":")); 529 p8.add(prioritySpinner); // already set to 5 530 prioritySpinner.setToolTipText(Bundle.getMessage("PriorityHint")); 531 p8.add(new JLabel(" ")); 532 p8.add(new JLabel(Bundle.getMessage("TrainTypeBoxLabel"))); 533 initializeTrainTypeBox(); 534 p8.add(trainTypeBox); 535 trainTypeBox.setSelectedIndex(1); 536 trainTypeBox.setToolTipText(Bundle.getMessage("TrainTypeBoxHint")); 537 initiatePane.add(p8); 538 JPanel p9 = new JPanel(); 539 p9.setLayout(new FlowLayout()); 540 p9.add(new JLabel(Bundle.getMessage("DelayedStart"))); 541 p9.add(delayedStartBox); 542 delayedStartBox.setToolTipText(Bundle.getMessage("DelayedStartHint")); 543 delayedStartBox.addActionListener(new ActionListener() { 544 @Override 545 public void actionPerformed(ActionEvent e) { 546 handleDelayStartClick(e); 547 } 548 }); 549 p9.add(departureTimeLabel); 550 departureHrSpinner.setEditor(new JSpinner.NumberEditor(departureHrSpinner, "00")); 551 p9.add(departureHrSpinner); 552 departureHrSpinner.setValue(8); 553 departureHrSpinner.setToolTipText(Bundle.getMessage("DepartureTimeHrHint")); 554 p9.add(departureSepLabel); 555 departureMinSpinner.setEditor(new JSpinner.NumberEditor(departureMinSpinner, "00")); 556 p9.add(departureMinSpinner); 557 departureMinSpinner.setValue(0); 558 departureMinSpinner.setToolTipText(Bundle.getMessage("DepartureTimeMinHint")); 559 p9.add(delaySensor); 560 delaySensor.setAllowNull(true); 561 p9.add(resetStartSensorBox); 562 resetStartSensorBox.setToolTipText(Bundle.getMessage("ResetStartSensorHint")); 563 resetStartSensorBox.setSelected(true); 564 handleDelayStartClick(null); 565 initiatePane.add(p9); 566 567 JPanel p11 = new JPanel(); 568 p11.setLayout(new FlowLayout()); 569 p11.add(loadAtStartupBox); 570 loadAtStartupBox.setToolTipText(Bundle.getMessage("LoadAtStartupBoxHint")); 571 loadAtStartupBox.setSelected(false); 572 initiatePane.add(p11); 573 574 initiatePane.add(new JSeparator()); 575 JPanel p5 = new JPanel(); 576 p5.setLayout(new FlowLayout()); 577 p5.add(autoRunBox); 578 autoRunBox.addActionListener(new ActionListener() { 579 @Override 580 public void actionPerformed(ActionEvent e) { 581 handleAutoRunClick(e); 582 } 583 }); 584 autoRunBox.setToolTipText(Bundle.getMessage("AutoRunBoxHint")); 585 autoRunBox.setSelected(false); 586 initiatePane.add(p5); 587 588 initializeAutoRunItems(); 589 590 JPanel p7 = new JPanel(); 591 p7.setLayout(new FlowLayout()); 592 JButton cancelButton = null; 593 p7.add(cancelButton = new JButton(Bundle.getMessage("ButtonCancel"))); 594 cancelButton.addActionListener(new ActionListener() { 595 @Override 596 public void actionPerformed(ActionEvent e) { 597 cancelInitiateTrain(e); 598 } 599 }); 600 cancelButton.setToolTipText(Bundle.getMessage("CancelButtonHint")); 601 p7.add(addNewTrainButton = new JButton(Bundle.getMessage("ButtonCreate"))); 602 addNewTrainButton.addActionListener(new ActionListener() { 603 @Override 604 public void actionPerformed(ActionEvent e) { 605 addNewTrain(e); 606 } 607 }); 608 addNewTrainButton.setToolTipText(Bundle.getMessage("AddNewTrainButtonHint")); 609 610 JPanel mainPane = new JPanel(); 611 mainPane.setLayout(new BoxLayout(mainPane, BoxLayout.Y_AXIS)); 612 JScrollPane scrPane = new JScrollPane(initiatePane); 613 mainPane.add(p0); 614 mainPane.add(scrPane); 615 mainPane.add(p7); 616 initiateFrame.setContentPane(mainPane); 617 switch (trainInfo.getTrainsFrom()) { 618 case TRAINSFROMROSTER: 619 radioTrainsFromRoster.setSelected(true); 620 break; 621 case TRAINSFROMOPS: 622 radioTrainsFromOps.setSelected(true); 623 break; 624 case TRAINSFROMUSER: 625 radioTrainsFromUser.setSelected(true); 626 break; 627 case TRAINSFROMSETLATER: 628 default: 629 radioTrainsFromSetLater.setSelected(true); 630 } 631 632 } 633 autoRunBox.setSelected(false); 634 loadAtStartupBox.setSelected(false); 635 initializeFreeTransitsCombo(new ArrayList<Transit>()); 636 nextTrain.addItem(""); 637 refreshNextTrainCombo(); 638 setTrainsFromOptions(trainInfo.getTrainsFrom()); 639 initiateFrame.pack(); 640 initiateFrame.setVisible(true); 641 } 642 643 private void refreshNextTrainCombo() { 644 Object saveEntry = null; 645 if (nextTrain.getSelectedIndex() > 0) { 646 saveEntry=nextTrain.getSelectedItem(); 647 } 648 nextTrain.removeAll(); 649 for (String file: _tiFile.getTrainInfoFileNames()) { 650 nextTrain.addItem(file); 651 } 652 if (saveEntry != null) { 653 nextTrain.setSelectedItem(saveEntry); 654 } 655 } 656 private void setTrainsFromOptions(TrainsFrom transFrom) { 657 switch (transFrom) { 658 case TRAINSFROMROSTER: 659 initializeFreeRosterEntriesCombo(); 660 trainBoxLabel.setVisible(true); 661 rosterComboBox.setVisible(true); 662 trainSelectBox.setVisible(false); 663 trainFieldLabel.setVisible(true); 664 trainNameField.setVisible(true); 665 dccAddressFieldLabel.setVisible(false); 666 dccAddressSpinner.setVisible(false); 667 break; 668 case TRAINSFROMOPS: 669 initializeFreeTrainsCombo(); 670 trainBoxLabel.setVisible(true); 671 trainSelectBox.setVisible(true); 672 rosterComboBox.setVisible(false); 673 trainFieldLabel.setVisible(true); 674 trainNameField.setVisible(true); 675 dccAddressFieldLabel.setVisible(true); 676 dccAddressSpinner.setVisible(true); 677 setSpeedProfileOptions(trainInfo,false); 678 break; 679 case TRAINSFROMUSER: 680 trainNameField.setText(""); 681 trainBoxLabel.setVisible(false); 682 trainSelectBox.setVisible(false); 683 rosterComboBox.setVisible(false); 684 trainFieldLabel.setVisible(true); 685 trainNameField.setVisible(true); 686 dccAddressFieldLabel.setVisible(true); 687 dccAddressSpinner.setVisible(true); 688 dccAddressSpinner.setEnabled(true); 689 setSpeedProfileOptions(trainInfo,false); 690 break; 691 case TRAINSFROMSETLATER: 692 default: 693 trainBoxLabel.setVisible(false); 694 rosterComboBox.setVisible(false); 695 trainSelectBox.setVisible(false); 696 trainFieldLabel.setVisible(true); 697 trainNameField.setVisible(true); 698 dccAddressFieldLabel.setVisible(false); 699 dccAddressSpinner.setVisible(false); 700 } 701 } 702 703 private void initializeTrainTypeBox() { 704 trainTypeBox.removeAllItems(); 705 trainTypeBox.addItem("<" + Bundle.getMessage("None").toLowerCase() + ">"); // <none> 706 trainTypeBox.addItem(Bundle.getMessage("LOCAL_PASSENGER")); 707 trainTypeBox.addItem(Bundle.getMessage("LOCAL_FREIGHT")); 708 trainTypeBox.addItem(Bundle.getMessage("THROUGH_PASSENGER")); 709 trainTypeBox.addItem(Bundle.getMessage("THROUGH_FREIGHT")); 710 trainTypeBox.addItem(Bundle.getMessage("EXPRESS_PASSENGER")); 711 trainTypeBox.addItem(Bundle.getMessage("EXPRESS_FREIGHT")); 712 trainTypeBox.addItem(Bundle.getMessage("MOW")); 713 // NOTE: The above must correspond in order and name to definitions in ActiveTrain.java. 714 } 715 716 private void initializeTrainDetectionBox() { 717 trainDetectionComboBox.addItem(new TrainDetectionItem(Bundle.getMessage("TrainDetectionWholeTrain"),TrainDetection.TRAINDETECTION_WHOLETRAIN)); 718 trainDetectionComboBox.addItem(new TrainDetectionItem(Bundle.getMessage("TrainDetectionHeadAndTail"),TrainDetection.TRAINDETECTION_HEADANDTAIL)); 719 trainDetectionComboBox.addItem(new TrainDetectionItem(Bundle.getMessage("TrainDetectionHeadOnly"),TrainDetection.TRAINDETECTION_HEADONLY)); 720 } 721 722 private void handleTransitSelectionChanged(ActionEvent e) { 723 int index = transitSelectBox.getSelectedIndex(); 724 if (index < 0) { 725 return; 726 } 727 Transit t = transitSelectBox.getSelectedItem(); 728 if ((t != null) && (t != selectedTransit)) { 729 selectedTransit = t; 730 initializeStartingBlockCombo(); 731 initializeDestinationBlockCombo(); 732 initiateFrame.pack(); 733 } 734 } 735 736 private void handleInTransitClick(ActionEvent e) { 737 if (!inTransitBox.isSelected() && selectedTransit.getEntryBlocksList().isEmpty()) { 738 JmriJOptionPane.showMessageDialog(initiateFrame, Bundle 739 .getMessage("NoEntryBlocks"), Bundle.getMessage("MessageTitle"), 740 JmriJOptionPane.INFORMATION_MESSAGE); 741 inTransitBox.setSelected(true); 742 } 743 initializeStartingBlockCombo(); 744 initializeDestinationBlockCombo(); 745 initiateFrame.pack(); 746 } 747 748 // private void handleTrainSelectionChanged(ActionEvent e) { 749 private void handleTrainSelectionChanged() { 750 if (trainInfo.getTrainsFrom() != TrainsFrom.TRAINSFROMOPS) { 751 return; 752 } 753 int ix = trainSelectBox.getSelectedIndex(); 754 if (ix < 1) { // no train selected 755 dccAddressSpinner.setEnabled(false); 756 return; 757 } 758 dccAddressSpinner.setEnabled(true); 759 int dccAddress; 760 try { 761 dccAddress = Integer.parseInt((((Train) trainSelectBox.getSelectedItem()).getLeadEngineDccAddress())); 762 } catch (NumberFormatException Ex) { 763 JmriJOptionPane.showMessageDialog(initiateFrame, Bundle.getMessage("Error43"), 764 Bundle.getMessage("ErrorTitle"), JmriJOptionPane.ERROR_MESSAGE); 765 return; 766 } 767 dccAddressSpinner.setValue (dccAddress); 768 } 769 770 private void handleRosterSelectionChanged(ActionEvent e) { 771 if (trainInfo.getTrainsFrom() != TrainsFrom.TRAINSFROMROSTER) { 772 return; 773 } 774 int ix = rosterComboBox.getSelectedIndex(); 775 if (ix > 0) { // first item is "Select Loco" string 776 RosterEntry r = (RosterEntry) rosterComboBox.getItemAt(ix); 777 // check to see if speed profile exists and is not empty 778 if (r.getSpeedProfile() == null || r.getSpeedProfile().getProfileSize() < 1) { 779 // disable profile boxes etc. 780 setSpeedProfileOptions(trainInfo,false); 781 } else { 782 // enable profile boxes 783 setSpeedProfileOptions(trainInfo,true); 784 } 785 trainInfo.setMaxSpeed(r.getMaxSpeedPCT()/100.0f); 786 maxSpeedSpinner.setValue(trainInfo.getMaxSpeed()); 787 trainNameField.setText(r.titleString()); 788 if (r.getAttribute("DispatcherTrainType") != null && !r.getAttribute("DispatcherTrainType").equals("")) { 789 trainTypeBox.setSelectedItem(r.getAttribute("DispatcherTrainType")); 790 } 791 } else { 792 setSpeedProfileOptions(trainInfo,false); 793 } 794 } 795 796 private void checkResetWhenDone() { 797 if ((!reverseAtEndBox.isSelected()) && resetWhenDoneBox.isSelected() 798 && (!selectedTransit.canBeResetWhenDone())) { 799 resetWhenDoneBox.setSelected(false); 800 throw new IllegalArgumentException(Bundle.getMessage("NoResetMessage")); 801 } 802 } 803 804 private void handleDelayStartClick(ActionEvent e) { 805 departureHrSpinner.setVisible(false); 806 departureMinSpinner.setVisible(false); 807 departureTimeLabel.setVisible(false); 808 departureSepLabel.setVisible(false); 809 delaySensor.setVisible(false); 810 resetStartSensorBox.setVisible(false); 811 if (delayedStartBox.getSelectedItem().equals(Bundle.getMessage("DelayedStartTimed"))) { 812 departureHrSpinner.setVisible(true); 813 departureMinSpinner.setVisible(true); 814 departureTimeLabel.setVisible(true); 815 departureSepLabel.setVisible(true); 816 } else if (delayedStartBox.getSelectedItem().equals(Bundle.getMessage("DelayedStartSensor"))) { 817 delaySensor.setVisible(true); 818 resetStartSensorBox.setVisible(true); 819 } 820 initiateFrame.pack(); // to fit extra hh:mm in window 821 } 822 823 private void handleResetWhenDoneClick(ActionEvent e) { 824 delayMinSpinner.setVisible(false); 825 delayMinLabel.setVisible(false); 826 delayedReStartLabel.setVisible(false); 827 delayedReStartBox.setVisible(false); 828 delayReStartSensorLabel.setVisible(false); 829 delayReStartSensor.setVisible(false); 830 resetRestartSensorBox.setVisible(false); 831 if (resetWhenDoneBox.isSelected()) { 832 delayedReStartLabel.setVisible(true); 833 delayedReStartBox.setVisible(true); 834 terminateWhenDoneBox.setSelected(false); 835 if (delayedReStartBox.getSelectedItem().equals(Bundle.getMessage("DelayedStartTimed"))) { 836 delayMinSpinner.setVisible(true); 837 delayMinLabel.setVisible(true); 838 } else if (delayedReStartBox.getSelectedItem().equals(Bundle.getMessage("DelayedStartSensor"))) { 839 delayReStartSensor.setVisible(true); 840 delayReStartSensorLabel.setVisible(true); 841 resetRestartSensorBox.setVisible(true); 842 } 843 } else { 844 terminateWhenDoneBox.setEnabled(true); 845 } 846 initiateFrame.pack(); 847 } 848 849 private void handleTerminateWhenDoneBoxClick(ActionEvent e) { 850 if (terminateWhenDoneBox.isSelected()) { 851 refreshNextTrainCombo(); 852 resetWhenDoneBox.setSelected(false); 853 terminateWhenDoneDetails.setVisible(true); 854 } else { 855 terminateWhenDoneDetails.setVisible(false); 856 // leave it 857 //nextTrain.setSelectedItem(""); 858 } 859 } 860 private void handleReverseAtEndBoxClick(ActionEvent e) { 861 delayReverseMinSpinner.setVisible(false); 862 delayReverseMinLabel.setVisible(false); 863 delayReverseReStartLabel.setVisible(false); 864 reverseDelayedRestartType.setVisible(false); 865 delayReverseReStartSensorLabel.setVisible(false); 866 delayReverseReStartSensor.setVisible(false); 867 delayReverseResetSensorBox.setVisible(false); 868 if (reverseAtEndBox.isSelected()) { 869 delayReverseReStartLabel.setVisible(true); 870 reverseDelayedRestartType.setVisible(true); 871 if (reverseDelayedRestartType.getSelectedItem().equals(Bundle.getMessage("DelayedStartTimed"))) { 872 delayReverseMinSpinner.setVisible(true); 873 delayReverseMinLabel.setVisible(true); 874 } else if (reverseDelayedRestartType.getSelectedItem().equals(Bundle.getMessage("DelayedStartSensor"))) { 875 delayReverseReStartSensor.setVisible(true); 876 delayReStartSensorLabel.setVisible(true); 877 delayReverseResetSensorBox.setVisible(true); 878 } 879 } 880 initiateFrame.pack(); 881 882 if (resetWhenDoneBox.isSelected()) { 883 terminateWhenDoneBox.setSelected(false); 884 terminateWhenDoneBox.setEnabled(false); 885 } else { 886 terminateWhenDoneBox.setEnabled(true); 887 } 888 } 889 890 private void handleAutoRunClick(ActionEvent e) { 891 if (autoRunBox.isSelected()) { 892 showAutoRunItems(); 893 } else { 894 hideAutoRunItems(); 895 } 896 initiateFrame.pack(); 897 } 898 899 private void handleStartingBlockSelectionChanged(ActionEvent e) { 900 initializeDestinationBlockCombo(); 901 initiateFrame.pack(); 902 } 903 904 private void handleAllocateAllTheWayButtonChanged(ActionEvent e) { 905 allocateCustomSpinner.setVisible(false); 906 } 907 908 private void handleAllocateBySafeButtonChanged(ActionEvent e) { 909 allocateCustomSpinner.setVisible(false); 910 } 911 912 private void handleAllocateNumberOfBlocksButtonChanged(ActionEvent e) { 913 allocateCustomSpinner.setVisible(true); 914 } 915 916 private void cancelInitiateTrain(ActionEvent e) { 917 _dispatcher.newTrainDone(null); 918 } 919 920 /* 921 * Handles press of "Add New Train" button. 922 * Move data to TrainInfo validating basic information 923 * Call dispatcher to start the train from traininfo which 924 * completes validation. 925 */ 926 private void addNewTrain(ActionEvent e) { 927 try { 928 dialogToTrainInfo(trainInfo); 929 _dispatcher.loadTrainFromTrainInfoThrowsException(trainInfo,"NONE",""); 930 } catch (IllegalArgumentException ex) { 931 JmriJOptionPane.showMessageDialog(initiateFrame, ex.getMessage(), 932 Bundle.getMessage("ErrorTitle"), JmriJOptionPane.ERROR_MESSAGE); 933 } 934 } 935 936 private void initializeFreeTransitsCombo(List<Transit> transitList) { 937 Set<Transit> excludeTransits = new HashSet<>(); 938 for (Transit t : _TransitManager.getNamedBeanSet()) { 939 if (t.getState() != Transit.IDLE) { 940 excludeTransits.add(t); 941 } 942 } 943 transitSelectBox.setExcludedItems(excludeTransits); 944 JComboBoxUtil.setupComboBoxMaxRows(transitSelectBox); 945 946 if (transitSelectBox.getItemCount() > 0) { 947 transitSelectBox.setSelectedIndex(0); 948 selectedTransit = transitSelectBox.getItemAt(0); 949 } else { 950 selectedTransit = null; 951 } 952 } 953 954 private void initializeFreeRosterEntriesCombo() { 955 rosterComboBox.update(); 956 // remove used entries 957 for (int ix = rosterComboBox.getItemCount() - 1; ix > 1; ix--) { // remove from back first item is the "select loco" message 958 if ( !_dispatcher.isAddressFree( ((RosterEntry)rosterComboBox.getItemAt(ix)).getDccLocoAddress().getNumber() ) ) { 959 rosterComboBox.removeItemAt(ix); 960 } 961 } 962 } 963 964 private void initializeFreeTrainsCombo() { 965 ActionListener[] als = trainSelectBox.getActionListeners(); 966 for ( ActionListener al: als) { 967 trainSelectBox.removeActionListener(al); 968 } 969 trainSelectBox.removeAllItems(); 970 trainSelectBox.addItem("Select Train"); 971 // initialize free trains from operations 972 List<Train> trains = jmri.InstanceManager.getDefault(TrainManager.class).getTrainsByNameList(); 973 if (trains.size() > 0) { 974 for (int i = 0; i < trains.size(); i++) { 975 Train t = trains.get(i); 976 if (t != null) { 977 String tName = t.getName(); 978 if (_dispatcher.isTrainFree(tName)) { 979 trainSelectBox.addItem(t); 980 } 981 } 982 } 983 } 984 for ( ActionListener al: als) { 985 trainSelectBox.addActionListener(al); 986 } 987 } 988 989 /** 990 * Sets the labels and inputs for speed profile running 991 * @param b True if the roster entry has valid speed profile else false 992 */ 993 private void setSpeedProfileOptions(TrainInfo info,boolean b) { 994 useSpeedProfileLabel.setEnabled(b); 995 useSpeedProfileCheckBox.setEnabled(b); 996 stopBySpeedProfileLabel.setEnabled(b); 997 stopBySpeedProfileCheckBox.setEnabled(b); 998 stopBySpeedProfileAdjustLabel.setEnabled(b); 999 stopBySpeedProfileAdjustSpinner.setEnabled(b); 1000 if (!b) { 1001 useSpeedProfileCheckBox.setSelected(false); 1002 stopBySpeedProfileCheckBox.setSelected(false); 1003 info.setUseSpeedProfile(false); 1004 info.setStopBySpeedProfile(false); 1005 } 1006 } 1007 1008 1009 1010 private void initializeStartingBlockCombo() { 1011 startingBlockBox.removeAllItems(); 1012 startingBlockBoxList.clear(); 1013 if (!inTransitBox.isSelected() && selectedTransit.getEntryBlocksList().isEmpty()) { 1014 inTransitBox.setSelected(true); 1015 } 1016 if (inTransitBox.isSelected()) { 1017 startingBlockBoxList = selectedTransit.getInternalBlocksList(); 1018 } else { 1019 startingBlockBoxList = selectedTransit.getEntryBlocksList(); 1020 } 1021 startingBlockSeqList = selectedTransit.getBlockSeqList(); 1022 boolean found = false; 1023 for (int i = 0; i < startingBlockBoxList.size(); i++) { 1024 Block b = startingBlockBoxList.get(i); 1025 int seq = startingBlockSeqList.get(i).intValue(); 1026 startingBlockBox.addItem(getBlockName(b) + "-" + seq); 1027 if (!found && b.getState() == Block.OCCUPIED) { 1028 startingBlockBox.setSelectedItem(getBlockName(b) + "-" + seq); 1029 found = true; 1030 } 1031 } 1032 JComboBoxUtil.setupComboBoxMaxRows(startingBlockBox); 1033 } 1034 1035 private void initializeDestinationBlockCombo() { 1036 destinationBlockBox.removeAllItems(); 1037 destinationBlockBoxList.clear(); 1038 int index = startingBlockBox.getSelectedIndex(); 1039 if (index < 0) { 1040 return; 1041 } 1042 Block startBlock = startingBlockBoxList.get(index); 1043 destinationBlockBoxList = selectedTransit.getDestinationBlocksList( 1044 startBlock, inTransitBox.isSelected()); 1045 destinationBlockSeqList = selectedTransit.getDestBlocksSeqList(); 1046 for (int i = 0; i < destinationBlockBoxList.size(); i++) { 1047 Block b = destinationBlockBoxList.get(i); 1048 String bName = getBlockName(b); 1049 if (selectedTransit.getBlockCount(b) > 1) { 1050 int seq = destinationBlockSeqList.get(i).intValue(); 1051 bName = bName + "-" + seq; 1052 } 1053 destinationBlockBox.addItem(bName); 1054 } 1055 JComboBoxUtil.setupComboBoxMaxRows(destinationBlockBox); 1056 } 1057 1058 private String getBlockName(Block b) { 1059 if (b != null) { 1060 return b.getDisplayName(); 1061 } 1062 return " "; 1063 } 1064 1065 protected void showActivateFrame() { 1066 if (initiateFrame != null) { 1067 initializeFreeTransitsCombo(new ArrayList<Transit>()); 1068 initiateFrame.setVisible(true); 1069 } else { 1070 _dispatcher.newTrainDone(null); 1071 } 1072 } 1073 1074 public void showActivateFrame(RosterEntry re) { 1075 showActivateFrame(); 1076 } 1077 1078 private void loadTrainInfo(ActionEvent e) { 1079 String[] names = _tiFile.getTrainInfoFileNames(); 1080 TrainInfo info = null; 1081 if (names.length > 0) { 1082 //prompt user to select a single train info filename from directory list 1083 Object selName = JmriJOptionPane.showInputDialog(initiateFrame, 1084 Bundle.getMessage("LoadTrainChoice"), Bundle.getMessage("LoadTrainTitle"), 1085 JmriJOptionPane.QUESTION_MESSAGE, null, names, names[0]); 1086 if ((selName == null) || (((String) selName).equals(""))) { 1087 return; 1088 } 1089 //read xml data from selected filename and move it into the new train dialog box 1090 _trainInfoName = (String) selName; 1091 try { 1092 info = _tiFile.readTrainInfo((String) selName); 1093 if (info != null) { 1094 // process the information just read 1095 trainInfoToDialog(info); 1096 } 1097 } catch (java.io.IOException ioe) { 1098 log.error("IO Exception when reading train info file", ioe); 1099 } catch (org.jdom2.JDOMException jde) { 1100 log.error("JDOM Exception when reading train info file", jde); 1101 } 1102 } 1103 handleDelayStartClick(null); 1104 handleReverseAtEndBoxClick(null); 1105 } 1106 1107 private void saveTrainInfo(ActionEvent e) { 1108 trainInfo=new TrainInfo(); 1109 try { 1110 dialogToTrainInfo(trainInfo); 1111 } catch (IllegalArgumentException ide) { 1112 JmriJOptionPane.showMessageDialog(initiateFrame, ide.getMessage(), 1113 Bundle.getMessage("ErrorTitle"), JmriJOptionPane.ERROR_MESSAGE); 1114 return; 1115 } 1116 // get file name 1117 String eName = ""; 1118 eName = JmriJOptionPane.showInputDialog(initiateFrame, 1119 Bundle.getMessage("EnterFileName") + " :", _trainInfoName); 1120 if (eName == null) { //Cancel pressed 1121 return; 1122 } 1123 if (eName.length() < 1) { 1124 JmriJOptionPane.showMessageDialog(initiateFrame, Bundle.getMessage("Error25"), 1125 Bundle.getMessage("ErrorTitle"), JmriJOptionPane.ERROR_MESSAGE); 1126 return; 1127 } 1128 String fileName = normalizeXmlFileName(eName); 1129 _trainInfoName = fileName; 1130 // check if train info file name is in use 1131 String[] names = _tiFile.getTrainInfoFileNames(); 1132 if (names.length > 0) { 1133 boolean found = false; 1134 for (int i = 0; i < names.length; i++) { 1135 if (fileName.equals(names[i])) { 1136 found = true; 1137 } 1138 } 1139 if (found) { 1140 // file by that name is already present 1141 int selectedValue = JmriJOptionPane.showOptionDialog(initiateFrame, 1142 Bundle.getMessage("Question3", fileName), 1143 Bundle.getMessage("WarningTitle"), JmriJOptionPane.DEFAULT_OPTION, 1144 JmriJOptionPane.QUESTION_MESSAGE, null, 1145 new Object[]{Bundle.getMessage("ButtonReplace"),Bundle.getMessage("ButtonNo")}, 1146 Bundle.getMessage("ButtonNo")); 1147 if (selectedValue != 0 ) { // array position 0 , replace not selected 1148 return; // return without writing if "No" response 1149 } 1150 } 1151 } 1152 // write the Train Info file 1153 try { 1154 _tiFile.writeTrainInfo(trainInfo, fileName); 1155 } //catch (org.jdom2.JDOMException jde) { 1156 // log.error("JDOM exception writing Train Info: "+jde); 1157 //} 1158 catch (java.io.IOException ioe) { 1159 log.error("IO exception writing Train Info", ioe); 1160 } 1161 } 1162 1163 private void deleteTrainInfo(ActionEvent e) { 1164 String[] names = _tiFile.getTrainInfoFileNames(); 1165 if (names.length > 0) { 1166 Object selName = JmriJOptionPane.showInputDialog(initiateFrame, 1167 Bundle.getMessage("DeleteTrainChoice"), Bundle.getMessage("DeleteTrainTitle"), 1168 JmriJOptionPane.QUESTION_MESSAGE, null, names, names[0]); 1169 if ((selName == null) || (((String) selName).equals(""))) { 1170 return; 1171 } 1172 _tiFile.deleteTrainInfoFile((String) selName); 1173 } 1174 } 1175 1176 private void trainInfoToDialog(TrainInfo info) { 1177 try { 1178 transitSelectBox.setSelectedItemByName(info.getTransitName()); 1179 } catch (Exception ex) { 1180 log.warn("Transit {} from file not in Transit menu", info.getTransitName()); 1181 JmriJOptionPane.showMessageDialog(initiateFrame, 1182 Bundle.getMessage("TransitWarn", info.getTransitName()), 1183 null, JmriJOptionPane.WARNING_MESSAGE); 1184 } 1185 switch (info.getTrainsFrom()) { 1186 case TRAINSFROMROSTER: 1187 radioTrainsFromRoster.setSelected(true); 1188 if (!setRosterComboBox(rosterComboBox, info.getRosterId())) { 1189 log.warn("Roster {} from file not in Roster Combo", info.getRosterId()); 1190 JmriJOptionPane.showMessageDialog(initiateFrame, 1191 Bundle.getMessage("TrainWarn", info.getRosterId()), 1192 null, JmriJOptionPane.WARNING_MESSAGE); 1193 } 1194 break; 1195 case TRAINSFROMOPS: 1196 radioTrainsFromOps.setSelected(true); 1197 if (!setTrainComboBox(trainSelectBox, info.getTrainName())) { 1198 log.warn("Train {} from file not in Train Combo", info.getTrainName()); 1199 JmriJOptionPane.showMessageDialog(initiateFrame, 1200 Bundle.getMessage("TrainWarn", info.getTrainName()), 1201 null, JmriJOptionPane.WARNING_MESSAGE); 1202 } 1203 break; 1204 case TRAINSFROMUSER: 1205 radioTrainsFromUser.setSelected(true); 1206 dccAddressSpinner.setValue(Integer.parseInt(info.getDccAddress())); 1207 break; 1208 case TRAINSFROMSETLATER: 1209 default: 1210 radioTrainsFromSetLater.setSelected(true); 1211 } 1212 trainNameField.setText(info.getTrainUserName()); 1213 trainDetectionComboBox.setSelectedItemByValue(info.getTrainDetection()); 1214 inTransitBox.setSelected(info.getTrainInTransit()); 1215 initializeStartingBlockCombo(); 1216 initializeDestinationBlockCombo(); 1217 setComboBox(startingBlockBox, info.getStartBlockName()); 1218 setComboBox(destinationBlockBox, info.getDestinationBlockName()); 1219 setAllocateMethodButtons(info.getAllocationMethod()); 1220 prioritySpinner.setValue(info.getPriority()); 1221 resetWhenDoneBox.setSelected(info.getResetWhenDone()); 1222 reverseAtEndBox.setSelected(info.getReverseAtEnd()); 1223 setDelayModeBox(info.getDelayedStart(), delayedStartBox); 1224 //delayedStartBox.setSelected(info.getDelayedStart()); 1225 departureHrSpinner.setValue(info.getDepartureTimeHr()); 1226 departureMinSpinner.setValue(info.getDepartureTimeMin()); 1227 delaySensor.setSelectedItem(info.getDelaySensor()); 1228 resetStartSensorBox.setSelected(info.getResetStartSensor()); 1229 setDelayModeBox(info.getDelayedRestart(), delayedReStartBox); 1230 delayMinSpinner.setValue(info.getRestartDelayMin()); 1231 delayReStartSensor.setSelectedItem(info.getRestartSensor()); 1232 resetRestartSensorBox.setSelected(info.getResetRestartSensor()); 1233 1234 resetStartSensorBox.setSelected(info.getResetStartSensor()); 1235 setDelayModeBox(info.getReverseDelayedRestart(), reverseDelayedRestartType); 1236 delayReverseMinSpinner.setValue(info.getReverseRestartDelayMin()); 1237 delayReverseReStartSensor.setSelectedItem(info.getReverseRestartSensor()); 1238 delayReverseResetSensorBox.setSelected(info.getReverseResetRestartSensor()); 1239 1240 terminateWhenDoneBox.setSelected(info.getTerminateWhenDone()); 1241 nextTrain.setSelectedIndex(-1); 1242 1243 try { 1244 nextTrain.setSelectedItem(info.getNextTrain()); 1245 } catch (Exception ex){ 1246 nextTrain.setSelectedIndex(-1); 1247 } 1248 handleTerminateWhenDoneBoxClick(null); 1249 setComboBox(trainTypeBox, info.getTrainType()); 1250 autoRunBox.setSelected(info.getAutoRun()); 1251 loadAtStartupBox.setSelected(info.getLoadAtStartup()); 1252 setAllocateMethodButtons(info.getAllocationMethod()); 1253 autoTrainInfoToDialog(info); 1254 } 1255 1256 private boolean dialogToTrainInfo(TrainInfo info) throws IllegalArgumentException { 1257 int index = transitSelectBox.getSelectedIndex(); 1258 if (index < 0) { 1259 throw new IllegalArgumentException(Bundle.getMessage("Error44")); 1260 } else { 1261 info.setTransitName(transitSelectBox.getSelectedItem().getDisplayName()); 1262 info.setTransitId(transitSelectBox.getSelectedItem().getDisplayName()); 1263 } 1264 switch (trainsFromButtonGroup.getSelection().getActionCommand()) { 1265 case "TRAINSFROMROSTER": 1266 if (rosterComboBox.getSelectedIndex() < 1 ) { 1267 throw new IllegalArgumentException(Bundle.getMessage("Error41")); 1268 } 1269 info.setRosterId(((RosterEntry) rosterComboBox.getSelectedItem()).getId()); 1270 info.setDccAddress(((RosterEntry) rosterComboBox.getSelectedItem()).getDccAddress()); 1271 break; 1272 case "TRAINSFROMOPS": 1273 if (trainSelectBox.getSelectedIndex() < 1) { 1274 throw new IllegalArgumentException(Bundle.getMessage("Error42")); 1275 } 1276 info.setTrainName(((Train) trainSelectBox.getSelectedItem()).getId()); 1277 info.setDccAddress(String.valueOf(dccAddressSpinner.getValue())); 1278 break; 1279 case "TRAINSFROMUSER": 1280 if (trainNameField.getText().isEmpty()) { 1281 throw new IllegalArgumentException(Bundle.getMessage("Error22")); 1282 } 1283 info.setDccAddress(String.valueOf(dccAddressSpinner.getValue())); 1284 break; 1285 case "TRAINSFROMSETLATER": 1286 default: 1287 info.setTrainName(""); 1288 info.setDccAddress(""); 1289 } 1290 info.setTrainUserName(trainNameField.getText()); 1291 info.setTrainInTransit(inTransitBox.isSelected()); 1292 info.setStartBlockName((String) startingBlockBox.getSelectedItem()); 1293 index = startingBlockBox.getSelectedIndex(); 1294 if (index < 0) { 1295 throw new IllegalArgumentException(Bundle.getMessage("Error13")); 1296 } else { 1297 info.setStartBlockId(startingBlockBoxList.get(index).getDisplayName()); 1298 info.setStartBlockSeq(startingBlockSeqList.get(index).intValue()); 1299 } 1300 info.setDestinationBlockName((String) destinationBlockBox.getSelectedItem()); 1301 index = destinationBlockBox.getSelectedIndex(); 1302 if (index < 0) { 1303 throw new IllegalArgumentException(Bundle.getMessage("Error8")); 1304 } else { 1305 info.setDestinationBlockId(destinationBlockBoxList.get(index).getDisplayName()); 1306 info.setDestinationBlockSeq(destinationBlockSeqList.get(index).intValue()); 1307 } 1308 checkResetWhenDone(); 1309 info.setPriority((Integer) prioritySpinner.getValue()); 1310 info.setTrainDetection(((TrainDetectionItem)trainDetectionComboBox.getSelectedItem()).value); 1311 info.setResetWhenDone(resetWhenDoneBox.isSelected()); 1312 info.setReverseAtEnd(reverseAtEndBox.isSelected()); 1313 info.setDelayedStart(delayModeFromBox(delayedStartBox)); 1314 info.setDelaySensorName(delaySensor.getSelectedItemDisplayName()); 1315 info.setResetStartSensor(resetStartSensorBox.isSelected()); 1316 info.setDepartureTimeHr((Integer) departureHrSpinner.getValue()); 1317 info.setDepartureTimeMin((Integer) departureMinSpinner.getValue()); 1318 info.setTrainType((String) trainTypeBox.getSelectedItem()); 1319 info.setAutoRun(autoRunBox.isSelected()); 1320 info.setLoadAtStartup(loadAtStartupBox.isSelected()); 1321 info.setAllocateAllTheWay(false); // force to false next field is now used. 1322 if (allocateAllTheWayRadioButton.isSelected()) { 1323 info.setAllocationMethod(ActiveTrain.ALLOCATE_AS_FAR_AS_IT_CAN); 1324 } else if (allocateBySafeRadioButton.isSelected()) { 1325 info.setAllocationMethod(ActiveTrain.ALLOCATE_BY_SAFE_SECTIONS); 1326 } else { 1327 info.setAllocationMethod((Integer) allocateCustomSpinner.getValue()); 1328 } 1329 info.setDelayedRestart(delayModeFromBox(delayedReStartBox)); 1330 info.setRestartSensorName(delayReStartSensor.getSelectedItemDisplayName()); 1331 info.setResetRestartSensor(resetRestartSensorBox.isSelected()); 1332 info.setRestartDelayMin((Integer) delayMinSpinner.getValue()); 1333 1334 info.setReverseDelayedRestart(delayModeFromBox(reverseDelayedRestartType)); 1335 info.setReverseRestartSensorName(delayReverseReStartSensor.getSelectedItemDisplayName()); 1336 info.setReverseResetRestartSensor(delayReverseResetSensorBox.isSelected()); 1337 info.setReverseRestartDelayMin((Integer) delayReverseMinSpinner.getValue()); 1338 1339 info.setTerminateWhenDone(terminateWhenDoneBox.isSelected()); 1340 if (nextTrain.getSelectedIndex() > 0 ) { 1341 info.setNextTrain((String)nextTrain.getSelectedItem()); 1342 } else { 1343 info.setNextTrain("None"); 1344 } 1345 autoRunItemsToTrainInfo(info); 1346 return true; 1347 } 1348 1349 private boolean setRosterComboBox(RosterEntryComboBox box, String txt) { 1350 boolean found = false; 1351 for (int i = 1; i < box.getItemCount(); i++) { 1352 if (txt.equals(((RosterEntry) box.getItemAt(i)).getId())) { 1353 box.setSelectedIndex(i); 1354 found = true; 1355 break; 1356 } 1357 } 1358 if (!found && box.getItemCount() > 0) { 1359 box.setSelectedIndex(0); 1360 } 1361 return found; 1362 } 1363 1364 // Normalizes a suggested xml file name. Returns null string if a valid name cannot be assembled 1365 private String normalizeXmlFileName(String name) { 1366 if (name.length() < 1) { 1367 return ""; 1368 } 1369 String newName = name; 1370 // strip off .xml or .XML if present 1371 if ((name.endsWith(".xml")) || (name.endsWith(".XML"))) { 1372 newName = name.substring(0, name.length() - 4); 1373 if (newName.length() < 1) { 1374 return ""; 1375 } 1376 } 1377 // replace all non-alphanumeric characters with underscore 1378 newName = newName.replaceAll("[\\W]", "_"); 1379 return (newName + ".xml"); 1380 } 1381 1382 private boolean setTrainComboBox(JComboBox<Object> box, String txt) { 1383 boolean found = false; 1384 for (int i = 1; i < box.getItemCount(); i++) { //skip the select train item 1385 if (txt.equals(box.getItemAt(i).toString())) { 1386 box.setSelectedIndex(i); 1387 found = true; 1388 break; 1389 } 1390 } 1391 if (!found && box.getItemCount() > 0) { 1392 box.setSelectedIndex(0); 1393 } 1394 return found; 1395 } 1396 1397 private boolean setComboBox(JComboBox<String> box, String txt) { 1398 boolean found = false; 1399 for (int i = 0; i < box.getItemCount(); i++) { 1400 if (txt.equals(box.getItemAt(i))) { 1401 box.setSelectedIndex(i); 1402 found = true; 1403 break; 1404 } 1405 } 1406 if (!found && box.getItemCount() > 0) { 1407 box.setSelectedIndex(0); 1408 } 1409 return found; 1410 } 1411 1412 int delayModeFromBox(JComboBox<String> box) { 1413 String mode = (String) box.getSelectedItem(); 1414 int result = jmri.util.StringUtil.getStateFromName(mode, delayedStartInt, delayedStartString); 1415 1416 if (result < 0) { 1417 log.warn("unexpected mode string in turnoutMode: {}", mode); 1418 throw new IllegalArgumentException(); 1419 } 1420 return result; 1421 } 1422 1423 void setDelayModeBox(int mode, JComboBox<String> box) { 1424 String result = jmri.util.StringUtil.getNameFromState(mode, delayedStartInt, delayedStartString); 1425 box.setSelectedItem(result); 1426 } 1427 1428 /** 1429 * The following are for items that are only for automatic running of 1430 * ActiveTrains They are isolated here to simplify changing them in the 1431 * future. 1432 * <ul> 1433 * <li>initializeAutoRunItems - initializes the display of auto run items in 1434 * this window 1435 * <li>initializeAutoRunValues - initializes the values of auto run items 1436 * from values in a saved train info file hideAutoRunItems - hides all auto 1437 * run items in this window showAutoRunItems - shows all auto run items in 1438 * this window 1439 * <li>autoTrainInfoToDialog - gets auto run items from a train info, puts 1440 * values in items, and initializes auto run dialog items 1441 * <li>autoTrainItemsToTrainInfo - copies values of auto run items to train 1442 * info for saving to a file 1443 * <li>readAutoRunItems - reads and checks values of all auto run items. 1444 * returns true if OK, sends appropriate messages and returns false if not 1445 * OK 1446 * <li>setAutoRunItems - sets the user entered auto run items in the new 1447 * AutoActiveTrain 1448 * </ul> 1449 */ 1450 // auto run items in ActivateTrainFrame 1451 private final JPanel pa1 = new JPanel(); 1452 private final JLabel speedFactorLabel = new JLabel(Bundle.getMessage("SpeedFactorLabel")); 1453 private final JSpinner speedFactorSpinner = new JSpinner(); 1454 private final JLabel minReliableOperatingSpeedLabel = new JLabel(Bundle.getMessage("MinReliableOperatingSpeedLabel")); 1455 private final JSpinner minReliableOperatingSpeedSpinner = new JSpinner(); 1456 private final JLabel maxSpeedLabel = new JLabel(Bundle.getMessage("MaxSpeedLabel")); 1457 private final JSpinner maxSpeedSpinner = new JSpinner(); 1458 private final JPanel pa2 = new JPanel(); 1459 private final JLabel rampRateLabel = new JLabel(Bundle.getMessage("RampRateBoxLabel")); 1460 private final JComboBox<String> rampRateBox = new JComboBox<>(); 1461 private final JPanel pa2a = new JPanel(); 1462 private final JLabel useSpeedProfileLabel = new JLabel(Bundle.getMessage("UseSpeedProfileLabel")); 1463 private final JCheckBox useSpeedProfileCheckBox = new JCheckBox( ); 1464 private final JLabel stopBySpeedProfileLabel = new JLabel(Bundle.getMessage("StopBySpeedProfileLabel")); 1465 private final JCheckBox stopBySpeedProfileCheckBox = new JCheckBox( ); 1466 private final JLabel stopBySpeedProfileAdjustLabel = new JLabel(Bundle.getMessage("StopBySpeedProfileAdjustLabel")); 1467 private final JSpinner stopBySpeedProfileAdjustSpinner = new JSpinner(); 1468 private final JPanel pa3 = new JPanel(); 1469 private final JCheckBox soundDecoderBox = new JCheckBox(Bundle.getMessage("SoundDecoder")); 1470 private final JCheckBox runInReverseBox = new JCheckBox(Bundle.getMessage("RunInReverse")); 1471 private final JPanel pa4 = new JPanel(); 1472 protected static class TrainDetectionJCombo extends JComboBox<TrainDetectionItem> { 1473 public void setSelectedItemByValue(TrainDetection var) { 1474 for ( int ix = 0; ix < getItemCount() ; ix ++ ) { 1475 if (getItemAt(ix).value == var) { 1476 this.setSelectedIndex(ix); 1477 break; 1478 } 1479 } 1480 } 1481 } 1482 public final TrainDetectionJCombo trainDetectionComboBox 1483 = new TrainDetectionJCombo(); 1484 private final JLabel trainDetectionLabel = new JLabel(Bundle.getMessage("TrainDetection")); 1485 private final JLabel trainLengthLabel = new JLabel(Bundle.getMessage("MaxTrainLengthLabel")); 1486 private final JSpinner maxTrainLengthSpinner = new JSpinner(); // initialized later 1487 1488 private void initializeAutoRunItems() { 1489 initializeRampCombo(); 1490 pa1.setLayout(new FlowLayout()); 1491 pa1.add(speedFactorLabel); 1492 speedFactorSpinner.setModel(new SpinnerNumberModel(Float.valueOf(1.0f), Float.valueOf(0.1f), Float.valueOf(2.0f), Float.valueOf(0.01f))); 1493 speedFactorSpinner.setEditor(new JSpinner.NumberEditor(speedFactorSpinner, "# %")); 1494 pa1.add(speedFactorSpinner); 1495 speedFactorSpinner.setToolTipText(Bundle.getMessage("SpeedFactorHint")); 1496 pa1.add(new JLabel(" ")); 1497 pa1.add(maxSpeedLabel); 1498 maxSpeedSpinner.setModel(new SpinnerNumberModel(Float.valueOf(1.0f), Float.valueOf(0.1f), Float.valueOf(1.0f), Float.valueOf(0.01f))); 1499 maxSpeedSpinner.setEditor(new JSpinner.NumberEditor(maxSpeedSpinner, "# %")); 1500 pa1.add(maxSpeedSpinner); 1501 maxSpeedSpinner.setToolTipText(Bundle.getMessage("MaxSpeedHint")); 1502 pa1.add(minReliableOperatingSpeedLabel); 1503 minReliableOperatingSpeedSpinner.setModel(new SpinnerNumberModel(Float.valueOf(0.0f), Float.valueOf(0.0f), Float.valueOf(1.0f), Float.valueOf(0.01f))); 1504 minReliableOperatingSpeedSpinner.setEditor(new JSpinner.NumberEditor(minReliableOperatingSpeedSpinner, "# %")); 1505 pa1.add(minReliableOperatingSpeedSpinner); 1506 minReliableOperatingSpeedSpinner.setToolTipText(Bundle.getMessage("MinReliableOperatingSpeedHint")); 1507 initiatePane.add(pa1); 1508 pa2.setLayout(new FlowLayout()); 1509 pa2.add(rampRateLabel); 1510 pa2.add(rampRateBox); 1511 rampRateBox.setToolTipText(Bundle.getMessage("RampRateBoxHint")); 1512 pa2.add(useSpeedProfileLabel); 1513 pa2.add(useSpeedProfileCheckBox); 1514 useSpeedProfileCheckBox.setToolTipText(Bundle.getMessage("UseSpeedProfileHint")); 1515 initiatePane.add(pa2); 1516 pa2a.setLayout(new FlowLayout()); 1517 pa2a.add(stopBySpeedProfileLabel); 1518 pa2a.add(stopBySpeedProfileCheckBox); 1519 stopBySpeedProfileCheckBox.setToolTipText(Bundle.getMessage("UseSpeedProfileHint")); // reuse identical hint for Stop 1520 pa2a.add(stopBySpeedProfileAdjustLabel); 1521 stopBySpeedProfileAdjustSpinner.setModel(new SpinnerNumberModel( Float.valueOf(1.0f), Float.valueOf(0.1f), Float.valueOf(5.0f), Float.valueOf(0.01f))); 1522 stopBySpeedProfileAdjustSpinner.setEditor(new JSpinner.NumberEditor(stopBySpeedProfileAdjustSpinner, "# %")); 1523 pa2a.add(stopBySpeedProfileAdjustSpinner); 1524 stopBySpeedProfileAdjustSpinner.setToolTipText(Bundle.getMessage("StopBySpeedProfileAdjustHint")); 1525 initiatePane.add(pa2a); 1526 pa3.setLayout(new FlowLayout()); 1527 pa3.add(soundDecoderBox); 1528 soundDecoderBox.setToolTipText(Bundle.getMessage("SoundDecoderBoxHint")); 1529 pa3.add(new JLabel(" ")); 1530 pa3.add(runInReverseBox); 1531 runInReverseBox.setToolTipText(Bundle.getMessage("RunInReverseBoxHint")); 1532 initiatePane.add(pa3); 1533 pa4.setLayout(new FlowLayout()); 1534 pa4.add(trainLengthLabel); 1535 maxTrainLengthSpinner.setModel(new SpinnerNumberModel(Float.valueOf(18.0f), Float.valueOf(0.0f), Float.valueOf(10000.0f), Float.valueOf(0.5f))); 1536 maxTrainLengthSpinner.setEditor(new JSpinner.NumberEditor(maxTrainLengthSpinner, "###0.0")); 1537 pa4.add(maxTrainLengthSpinner); 1538 boolean unitIsMeter = InstanceManager.getDefault(DispatcherFrame.class).getUseScaleMeters(); // read from user setting 1539 maxTrainLengthSpinner.setToolTipText(Bundle.getMessage("MaxTrainLengthHint", 1540 (unitIsMeter ? Bundle.getMessage("ScaleMeters") : Bundle.getMessage("ScaleFeet")))); // won't be updated while Dispatcher is open 1541 initiatePane.add(pa4); 1542 hideAutoRunItems(); // initialize with auto run items hidden 1543 } 1544 1545 private void hideAutoRunItems() { 1546 pa1.setVisible(false); 1547 pa2.setVisible(false); 1548 pa2a.setVisible(false); 1549 pa3.setVisible(false); 1550 pa4.setVisible(false); 1551 } 1552 1553 private void showAutoRunItems() { 1554 pa1.setVisible(true); 1555 pa2.setVisible(true); 1556 pa2a.setVisible(true); 1557 pa3.setVisible(true); 1558 pa4.setVisible(true); 1559 } 1560 1561 private void autoTrainInfoToDialog(TrainInfo info) { 1562 speedFactorSpinner.setValue(info.getSpeedFactor()); 1563 maxSpeedSpinner.setValue(info.getMaxSpeed()); 1564 minReliableOperatingSpeedSpinner.setValue(info.getMinReliableOperatingSpeed()); 1565 setComboBox(rampRateBox, info.getRampRate()); 1566 trainDetectionComboBox.setSelectedItemByValue(info.getTrainDetection()); 1567 runInReverseBox.setSelected(info.getRunInReverse()); 1568 soundDecoderBox.setSelected(info.getSoundDecoder()); 1569 maxTrainLengthSpinner.setValue(info.getMaxTrainLength()); 1570 useSpeedProfileCheckBox.setSelected(info.getUseSpeedProfile()); 1571 stopBySpeedProfileCheckBox.setSelected(info.getStopBySpeedProfile()); 1572 stopBySpeedProfileAdjustSpinner.setValue(info.getStopBySpeedProfileAdjust()); 1573 if (autoRunBox.isSelected()) { 1574 showAutoRunItems(); 1575 } else { 1576 hideAutoRunItems(); 1577 } 1578 initiateFrame.pack(); 1579 } 1580 1581 private void autoRunItemsToTrainInfo(TrainInfo info) { 1582 info.setSpeedFactor((float) speedFactorSpinner.getValue()); 1583 int max = Math.round((float) maxSpeedSpinner.getValue()*100.0f); 1584 int min = Math.round((float) minReliableOperatingSpeedSpinner.getValue()*100.0f); 1585 if ((max-min) < 10) { 1586 throw new IllegalArgumentException(Bundle.getMessage("Error49", 1587 maxSpeedSpinner.getValue(), minReliableOperatingSpeedSpinner.getValue())); 1588 } 1589 info.setMaxSpeed((float) maxSpeedSpinner.getValue()); 1590 info.setMinReliableOperatingSpeed((float) minReliableOperatingSpeedSpinner.getValue()); 1591 info.setRampRate((String) rampRateBox.getSelectedItem()); 1592 info.setRunInReverse(runInReverseBox.isSelected()); 1593 info.setSoundDecoder(soundDecoderBox.isSelected()); 1594 info.setMaxTrainLength((float) maxTrainLengthSpinner.getValue()); 1595 // Only use speed profile values if enabled 1596 if (useSpeedProfileCheckBox.isEnabled()) { 1597 info.setUseSpeedProfile(useSpeedProfileCheckBox.isSelected()); 1598 info.setStopBySpeedProfile(stopBySpeedProfileCheckBox.isSelected()); 1599 info.setStopBySpeedProfileAdjust((float) stopBySpeedProfileAdjustSpinner.getValue()); 1600 } else { 1601 info.setUseSpeedProfile(false); 1602 info.setStopBySpeedProfile(false); 1603 info.setStopBySpeedProfileAdjust(1.0f); 1604 } 1605 } 1606 1607 private void initializeRampCombo() { 1608 rampRateBox.removeAllItems(); 1609 rampRateBox.addItem(Bundle.getMessage("RAMP_NONE")); 1610 rampRateBox.addItem(Bundle.getMessage("RAMP_FAST")); 1611 rampRateBox.addItem(Bundle.getMessage("RAMP_MEDIUM")); 1612 rampRateBox.addItem(Bundle.getMessage("RAMP_MED_SLOW")); 1613 rampRateBox.addItem(Bundle.getMessage("RAMP_SLOW")); 1614 rampRateBox.addItem(Bundle.getMessage("RAMP_SPEEDPROFILE")); 1615 // Note: the order above must correspond to the numbers in AutoActiveTrain.java 1616 } 1617 1618 /** 1619 * Sets up the RadioButtons and visability of spinner for the allocation method 1620 * 1621 * @param value 0, Allocate by Safe spots, -1, allocate as far as possible Any 1622 * other value the number of sections to allocate 1623 */ 1624 private void setAllocateMethodButtons(int value) { 1625 switch (value) { 1626 case ActiveTrain.ALLOCATE_BY_SAFE_SECTIONS: 1627 allocateBySafeRadioButton.setSelected(true); 1628 allocateCustomSpinner.setVisible(false); 1629 break; 1630 case ActiveTrain.ALLOCATE_AS_FAR_AS_IT_CAN: 1631 allocateAllTheWayRadioButton.setSelected(true); 1632 allocateCustomSpinner.setVisible(false); 1633 break; 1634 default: 1635 allocateNumberOfBlocks.setSelected(true); 1636 allocateCustomSpinner.setVisible(true); 1637 allocateCustomSpinner.setValue(value); 1638 } 1639 } 1640 1641 /* 1642 * ComboBox item. 1643 */ 1644 protected static class TrainDetectionItem { 1645 private String key; 1646 private TrainDetection value; 1647 public TrainDetectionItem(String text, TrainDetection trainDetection ) { 1648 this.key = text; 1649 this.value = trainDetection; 1650 } 1651 @Override 1652 public String toString() 1653 { 1654 return key; 1655 } 1656 public String getKey() 1657 { 1658 return key; 1659 } 1660 public TrainDetection getValue() 1661 { 1662 return value; 1663 } 1664 } 1665 1666 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ActivateTrainFrame.class); 1667 1668}