001package jmri.jmrit.dispatcher; 002 003import java.awt.BorderLayout; 004import java.awt.Dimension; 005import java.awt.FlowLayout; 006import java.awt.event.ActionEvent; 007import java.util.ArrayList; 008 009import javax.swing.BoxLayout; 010import javax.swing.ButtonGroup; 011import javax.swing.JButton; 012import javax.swing.JCheckBoxMenuItem; 013import javax.swing.JLabel; 014import javax.swing.JMenu; 015import javax.swing.JMenuBar; 016import javax.swing.JPanel; 017import javax.swing.JRadioButton; 018import javax.swing.JScrollPane; 019import javax.swing.JSeparator; 020import javax.swing.JSlider; 021import javax.swing.JTextField; 022 023import java.beans.PropertyChangeEvent; 024 025import javax.swing.JToolBar; 026import javax.swing.event.AncestorEvent; 027import javax.swing.event.AncestorListener; 028import javax.swing.plaf.basic.BasicToolBarUI; 029 030import jmri.Throttle; 031import jmri.jmrit.roster.RosterEntry; 032import jmri.util.JmriJFrame; 033import org.slf4j.Logger; 034import org.slf4j.LoggerFactory; 035 036/** 037 * AutoTrainsFrame provides a user interface to trains that are running 038 * automatically under Dispatcher. 039 * <p> 040 * There is only one AutoTrains window. AutoTrains are added and deleted from 041 * this window as they are added or terminated. 042 * <p> 043 * This file is part of JMRI. 044 * <p> 045 * JMRI is open source software; you can redistribute it and/or modify it under 046 * the terms of version 2 of the GNU General Public License as published by the 047 * Free Software Foundation. See the "COPYING" file for a copy of this license. 048 * <p> 049 * JMRI is distributed in the hope that it will be useful, but WITHOUT ANY 050 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 051 * A PARTICULAR PURPOSE. See the GNU General Public License for more details. 052 * 053 * @author Dave Duchamp Copyright (C) 2010 054 */ 055public class AutoTrainsFrame extends jmri.util.JmriJFrame { 056 057 public AutoTrainsFrame(DispatcherFrame disp) { 058 super(false, true); 059 initializeAutoTrainsWindow(); 060 } 061 062 // instance variables 063 private final ArrayList<AutoActiveTrain> _autoTrainsList = new ArrayList<>(); 064 //Keep track of throttle and listeners to update frame with their current state. 065 066 // accessor functions 067 public ArrayList<AutoActiveTrain> getAutoTrainsList() { 068 return _autoTrainsList; 069 } 070 071 /** 072 * Creates and initializes a new control of type AutoTrainControl 073 * @param autoActiveTrain the new train. 074 */ 075 public void addAutoActiveTrain(AutoActiveTrain autoActiveTrain) { 076 if (autoActiveTrain != null) { 077 log.debug("Adding ActiveTrain[{}]",autoActiveTrain.getActiveTrain().getActiveTrainName()); 078 AutoTrainControl atn = new AutoTrainControl(autoActiveTrain); 079 if (!trainsCanBeFloated.isSelected()) { 080 atn.componentJPanel.setFloatable(false); 081 } 082 trainsPanel.add(atn); 083 atn.addPropertyChangeListener("terminated", (PropertyChangeEvent e) -> { 084 AutoTrainControl atnn = (AutoTrainControl) e.getSource(); 085 // must be attached to make it really go away 086 ((BasicToolBarUI) atnn.componentJPanel.getUI()).setFloating(false,null); 087 trainsPanel.remove((AutoTrainControl) e.getSource()); 088 pack(); 089 }); 090 // bit of overkill for when a floater floats and comes back. 091 atn.componentJPanel.addAncestorListener ( new AncestorListener () 092 { 093 @Override 094 public void ancestorAdded ( AncestorEvent event ) 095 { 096 log.trace("ancestorAdded"); 097 pack(); 098 } 099 @Override 100 public void ancestorRemoved ( AncestorEvent event ) 101 { 102 log.trace("ancestorRemoved"); 103 pack(); 104 } 105 @Override 106 public void ancestorMoved ( AncestorEvent event ) 107 { 108 // blank. 109 } 110 } ); 111 pack(); 112 } 113 } 114 115 // variables for AutoTrains window 116 protected JmriJFrame autoTrainsFrame = null; 117 private JPanel trainsPanel; 118 private JScrollPane trainScrollPanel; 119 private JCheckBoxMenuItem frameHasScrollBars = new JCheckBoxMenuItem(Bundle.getMessage("AutoTrainsFrameUseScrollBars")); 120 private JCheckBoxMenuItem trainsCanBeFloated = new JCheckBoxMenuItem(Bundle.getMessage("AutoTrainsFrameAllowFloat")); 121 private JCheckBoxMenuItem frameAlwaysOnTop = new JCheckBoxMenuItem(Bundle.getMessage("AutoTrainsFrameAlwaysOnTop")); 122 private JCheckBoxMenuItem frameOnTopOnSpeedChange = new JCheckBoxMenuItem(Bundle.getMessage("AutoTrainsFrameOnTopOnSpeedChange")); 123 124 jmri.UserPreferencesManager prefMan; 125 126 private void initializeAutoTrainsWindow() { 127 128 prefMan = jmri.InstanceManager.getDefault(jmri.UserPreferencesManager.class); 129 frameHasScrollBars.setSelected(prefMan.getSimplePreferenceState(hasScrollBars)); 130 trainsCanBeFloated.setSelected(prefMan.getSimplePreferenceState(canFloat)); 131 frameAlwaysOnTop.setSelected(prefMan.getSimplePreferenceState(alWaysOnTop)); 132 frameOnTopOnSpeedChange.setSelected(prefMan.getSimplePreferenceState(onTopOnSpeedChange)); 133 134 135 autoTrainsFrame = this; 136 autoTrainsFrame.setTitle(Bundle.getMessage("TitleAutoTrains")); 137 trainsPanel = new JPanel(); 138 trainsPanel.setLayout(new BoxLayout(trainsPanel, BoxLayout.Y_AXIS)); 139 JMenuBar menuBar = new JMenuBar(); 140 JMenu optMenu = new JMenu(Bundle.getMessage("MenuOptions")); // NOI18N 141 optMenu.add(frameHasScrollBars); 142 frameHasScrollBars.addActionListener(e -> { 143 setScrollBars(); 144 }); 145 146 optMenu.add(trainsCanBeFloated); 147 trainsCanBeFloated.addActionListener(e -> { 148 for (Object ob : trainsPanel.getComponents()) { 149 if (ob instanceof AutoTrainControl) { 150 AutoTrainControl atnn = (AutoTrainControl) ob; 151 if (trainsCanBeFloated.isSelected()) { 152 atnn.componentJPanel.setFloatable(true); 153 } else { 154 // rejoin floating throttles before banning 155 // floating. 156 ((BasicToolBarUI) atnn.componentJPanel.getUI()).setFloating(false, null); 157 atnn.componentJPanel.setFloatable(false); 158 } 159 } 160 } 161 }); 162 163 optMenu.add(frameAlwaysOnTop); 164 frameAlwaysOnTop.addActionListener(e -> { 165 setAlwaysOnTop(frameAlwaysOnTop.isSelected()); 166 }); 167 168 optMenu.add(frameOnTopOnSpeedChange); 169 frameOnTopOnSpeedChange.addActionListener(e -> { 170 for (Object ob : trainsPanel.getComponents()) { 171 if (ob instanceof AutoTrainControl) { 172 AutoTrainControl atnn = (AutoTrainControl) ob; 173 atnn.setOnTopOnSpeedChange(frameOnTopOnSpeedChange.isSelected()); 174 } 175 } 176 }); 177 178 menuBar.add(optMenu); 179 180 setJMenuBar(menuBar); 181 autoTrainsFrame.addHelpMenu("package.jmri.jmrit.dispatcher.AutoTrains", true); 182 trainsPanel.setLayout(new BoxLayout(trainsPanel, BoxLayout.Y_AXIS)); 183 JPanel pB = new JPanel(); 184 pB.setLayout(new FlowLayout()); 185 JButton stopAllButton = new JButton(Bundle.getMessage("StopAll")); 186 pB.add(stopAllButton); 187 stopAllButton.addActionListener(this::stopAllPressed); 188 stopAllButton.setToolTipText(Bundle.getMessage("StopAllButtonHint")); 189 trainsPanel.add(pB); 190 trainsPanel.add(new JSeparator()); 191 trainsPanel.addComponentListener(this); 192 trainsPanel.setVisible(true); 193 trainsPanel.revalidate(); 194 trainScrollPanel = new JScrollPane(); 195 trainScrollPanel.getViewport().add(trainsPanel); 196 autoTrainsFrame.getContentPane().setLayout(new BoxLayout(autoTrainsFrame.getContentPane(), BoxLayout.Y_AXIS)); 197 autoTrainsFrame.getContentPane().add(trainScrollPanel); 198 setScrollBars(); 199 autoTrainsFrame.getContentPane().revalidate(); 200 autoTrainsFrame.pack(); 201 autoTrainsFrame.setVisible(true); 202 203 } 204 205 private void setScrollBars() { 206 if (frameHasScrollBars.isSelected()) { 207 trainScrollPanel.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); 208 trainScrollPanel.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); 209 autoTrainsFrame.getContentPane().revalidate(); 210 } else { 211 trainScrollPanel.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER); 212 trainScrollPanel.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); 213 autoTrainsFrame.getContentPane().revalidate(); 214 } 215 } 216 217 private void stopAllPressed(ActionEvent e) { 218 for (Object ob: trainsPanel.getComponents()) { 219 if (ob instanceof AutoTrainControl) { 220 ((AutoTrainControl) ob).stopAll(); 221 } 222 } 223 } 224 225 @Override 226 public void dispose() { 227 if (prefMan!=null) { 228 prefMan.setSimplePreferenceState(hasScrollBars, frameHasScrollBars.isSelected()); 229 prefMan.setSimplePreferenceState(canFloat, trainsCanBeFloated.isSelected()); 230 prefMan.setSimplePreferenceState(hasScrollBars, frameHasScrollBars.isSelected()); 231 prefMan.setSimplePreferenceState(canFloat, trainsCanBeFloated.isSelected()); 232 } 233 super.dispose(); 234 } 235 String hasScrollBars = this.getClass().getName() + ".HasScrollBars"; // NOI18N 236 String canFloat = this.getClass().getName() + ".CanFloat"; // NOI18N 237 String alWaysOnTop = this.getClass().getName() + ".AlWaysOnTop"; // NOI18N 238 String onTopOnSpeedChange = this.getClass().getName() + ".OnTopOnSpeedChange"; // NOI18N 239 class AutoTrainControl extends JPanel { 240 241 private boolean useOnTopOnSpeedChange; 242 243 public AutoTrainControl(AutoActiveTrain autoActiveTrain) { 244 this.autoActiveTrain = autoActiveTrain; 245 activeTrain = autoActiveTrain.getActiveTrain(); 246 activeTrain.addPropertyChangeListener(activeTrainListener = new java.beans.PropertyChangeListener() { 247 @Override 248 public void propertyChange(java.beans.PropertyChangeEvent e) { 249 handleActiveTrainListen(e); 250 } 251 }); 252 rosterEntry = autoActiveTrain.getRosterEntry(); 253 drawComponent(); 254 } 255 256 protected void setOnTopOnSpeedChange(boolean value) { 257 useOnTopOnSpeedChange = value; 258 } 259 260 protected void stopAll() { 261 if (activeTrain.getStatus() != ActiveTrain.STOPPED && 262 activeTrain.getStatus() != ActiveTrain.DONE) { 263 autoActiveTrain.saveSpeedAndDirection(); 264 autoActiveTrain.getAutoEngineer().setHalt(true); 265 autoActiveTrain.setSavedStatus(activeTrain.getStatus()); 266 activeTrain.setStatus(ActiveTrain.STOPPED); 267 } 268 } 269 270 private AutoActiveTrain autoActiveTrain = null; 271 private java.beans.PropertyChangeListener activeTrainListener = null; 272 private java.beans.PropertyChangeListener throttleListener = null; 273 private jmri.Throttle throttle = null; 274 private ActiveTrain activeTrain = null; 275 private RosterEntry rosterEntry = null; 276 277 private JLabel trainLabel; 278 private JLabel throttleStatus; 279 protected JButton stopButton; 280 private JButton resumeAutoRunningButton; 281 private JRadioButton forwardButton; 282 private JRadioButton reverseButton; 283 private JSlider speedSlider; 284 private JButton manualButton; 285 286 private void handleThrottleListen(java.beans.PropertyChangeEvent e) { 287 if (!e.getPropertyName().equals(Throttle.SPEEDSETTING) && !e.getPropertyName().equals(Throttle.ISFORWARD)) { 288 return; // ignore if not speed or direction 289 } 290 updateThrottleDisplay(e); 291 } 292 293 private float lastReportedSpeed; // for display purposes 294 295 /* 296 * Updates screen control throttle. 297 */ 298 private void primeThrottleDisplay() { 299 if (throttle != null) { 300 if (throttle.getIsForward()) { 301 forwardButton.setSelected(true); 302 } else { 303 reverseButton.setSelected(true); 304 } 305 lastReportedSpeed = throttle.getSpeedSetting(); 306 if (speedSlider.isVisible()) { 307 speedSlider.setValue(Math.round(lastReportedSpeed * 100.0f)); 308 } 309 } 310 updateThrottleStatus(); 311 } 312 313 /* 314 * Updates control from events 315 */ 316 private void updateThrottleDisplay(java.beans.PropertyChangeEvent e) { 317 if (throttle != null) { 318 if (e.getPropertyName().equals(Throttle.ISFORWARD)) { 319 if ((boolean) e.getNewValue()) { 320 forwardButton.setSelected(true); 321 } else { 322 reverseButton.setSelected(true); 323 } 324 } else { 325 lastReportedSpeed = (float) e.getNewValue(); 326 if (speedSlider.isVisible()) { 327 speedSlider.setValue(Math.round(lastReportedSpeed * 100.0f)); 328 } 329 } 330 } 331 updateThrottleStatus(); 332 } 333 334 /* 335 * Updates the status words. 336 */ 337 private void updateThrottleStatus() { 338 StringBuilder sb = new StringBuilder(); 339 if (throttle != null && throttleStatus.isVisible()) { 340 if (rosterEntry != null && autoActiveTrain.useSpeedProfile && rosterEntry.getSpeedProfile() != null) { 341 sb.append("" + 342 rosterEntry.getSpeedProfile().convertThrottleSettingToScaleSpeedWithUnits( 343 lastReportedSpeed, 344 forwardButton.isSelected())); 345 } else { 346 sb.append("" + Math.round(throttle.getSpeedSetting() * 100)); 347 sb.append("% "); 348 } 349 if (forwardButton.isSelected()) { 350 sb.append("(fwd)"); 351 } else { 352 sb.append("(rev)"); 353 } 354 throttleStatus.setText(sb.toString()); 355 if (useOnTopOnSpeedChange) { 356 // bring to front without getting focus 357 setAlwaysOnTop(true); 358 setAlwaysOnTop(false); 359 } 360 } else if (throttleStatus.isVisible()) { 361 throttleStatus.setText("No Throttle"); 362 } 363 } 364 365 private void handleActiveTrainListen(java.beans.PropertyChangeEvent e) { 366 if (e.getNewValue() != null) { 367 log.trace("Property[{}] newValue[{}]",e.getPropertyName(),e.getNewValue()); 368 } else { 369 log.trace("Property[{}] newValue[{}]",e.getPropertyName(),"NULL"); 370 } 371 if (e.getPropertyName().equals("mode")) { 372 int newValue = ((Integer) e.getNewValue()).intValue(); 373 if (newValue == ActiveTrain.DISPATCHED) { 374 stopButton.setVisible(false); 375 manualButton.setVisible(false); 376 resumeAutoRunningButton.setVisible(true); 377 forwardButton.setVisible(false); 378 reverseButton.setVisible(false); 379 speedSlider.setVisible(false); 380 throttleStatus.setVisible(false); 381 jmri.InstanceManager.throttleManagerInstance().removeListener(throttle.getLocoAddress(), 382 throttleListener); 383 } else if (newValue == ActiveTrain.AUTOMATIC) { 384 log.trace("[{}]:Set auto", autoActiveTrain.getActiveTrain().getActiveTrainName()); 385 if (throttle == null && autoActiveTrain.getThrottle() != null) { 386 log.trace("[{}]:Set new throttle", autoActiveTrain.getActiveTrain().getActiveTrainName()); 387 throttle = autoActiveTrain.getThrottle(); 388 throttleListener = new java.beans.PropertyChangeListener() { 389 @Override 390 public void propertyChange(java.beans.PropertyChangeEvent e) { 391 handleThrottleListen(e); 392 } 393 }; 394 jmri.InstanceManager.throttleManagerInstance().attachListener(throttle.getLocoAddress(), throttleListener); 395 rosterEntry = autoActiveTrain.getRosterEntry(); 396 setStatusLabelWidth(); 397 stopButton.setText(Bundle.getMessage("StopButton")); 398 stopButton.setToolTipText(Bundle.getMessage("StopButtonHint")); 399 stopButton.setVisible(true); 400 manualButton.setText(Bundle.getMessage("ToManualButton")); 401 manualButton.setToolTipText(Bundle.getMessage("ToManualButtonHint")); 402 manualButton.setVisible(true); 403 resumeAutoRunningButton.setVisible(false); 404 forwardButton.setVisible(false); 405 reverseButton.setVisible(false); 406 speedSlider.setVisible(false); 407 throttleStatus.setVisible(true); 408 primeThrottleDisplay(); 409 } 410 } else if ((int) e.getNewValue() == ActiveTrain.TERMINATED) { 411 if (throttle != null && throttleListener != null) { 412 throttle.removePropertyChangeListener(throttleListener); 413 throttle = null; 414 } 415 activeTrain.removePropertyChangeListener(activeTrainListener); 416 // please someone stop me before I do something silly 417 firePropertyChange("terminated", null, null); 418 } 419 } else if (e.getPropertyName().equals("status")) { 420 log.debug("NewStatus[{}]", e.getNewValue()); 421 if ((int) e.getNewValue() == ActiveTrain.STOPPED) { 422 stopButton.setText(Bundle.getMessage("ResumeButton")); 423 stopButton.setToolTipText(Bundle.getMessage("ResumeButtonHint")); 424 stopButton.setVisible(true); 425 } else if ((int) e.getNewValue() == ActiveTrain.RUNNING || 426 (int) e.getNewValue() == ActiveTrain.WAITING || 427 (int) e.getNewValue() == ActiveTrain.READY ) { 428 log.trace("[{}]:Set auto STATUS RUNNING", autoActiveTrain.getActiveTrain().getActiveTrainName()); 429 if (throttle == null && autoActiveTrain.getThrottle() != null) { 430 log.debug("[{}]:Set new throttle", autoActiveTrain.getActiveTrain().getActiveTrainName()); 431 throttle = autoActiveTrain.getThrottle(); 432 throttleListener = new java.beans.PropertyChangeListener() { 433 @Override 434 public void propertyChange(java.beans.PropertyChangeEvent e) { 435 handleThrottleListen(e); 436 } 437 }; 438 jmri.InstanceManager.throttleManagerInstance().attachListener(throttle.getLocoAddress(), throttleListener); 439 rosterEntry = autoActiveTrain.getRosterEntry(); 440 setStatusLabelWidth(); 441 } 442 stopButton.setText(Bundle.getMessage("StopButton")); 443 stopButton.setToolTipText(Bundle.getMessage("StopButtonHint")); 444 stopButton.setVisible(true); 445 manualButton.setText(Bundle.getMessage("ToManualButton")); 446 manualButton.setToolTipText(Bundle.getMessage("ToManualButtonHint")); 447 manualButton.setVisible(true); 448 resumeAutoRunningButton.setVisible(false); 449 forwardButton.setVisible(false); 450 reverseButton.setVisible(false); 451 speedSlider.setVisible(false); 452 throttleStatus.setVisible(true); 453 primeThrottleDisplay(); 454 } else if ((int) e.getNewValue() == ActiveTrain.DONE) { 455 stopButton.setText(Bundle.getMessage("RestartButton")); 456 stopButton.setToolTipText(Bundle.getMessage("RestartButtonHint")); 457 stopButton.setVisible(true); 458 } else { 459 log.debug("Ignored newstatus[{}]", e.getNewValue()); 460 } 461 } 462 pack(); 463 } 464 465 public void manualAutoTrain() { 466 if (activeTrain.getMode() == ActiveTrain.AUTOMATIC) { 467 activeTrain.setMode(ActiveTrain.MANUAL); 468 manualButton.setText(Bundle.getMessage("ToAutoButton")); 469 manualButton.setToolTipText(Bundle.getMessage("ToAutoButtonHint")); 470 forwardButton.setVisible(true); 471 reverseButton.setVisible(true); 472 speedSlider.setVisible(true); 473 if (autoActiveTrain.getAutoEngineer() != null) { 474 autoActiveTrain.saveSpeedAndDirection(); 475 autoActiveTrain.getAutoEngineer().setHalt(true); 476 autoActiveTrain.setTargetSpeed(0.0f); 477 autoActiveTrain.waitUntilStopped(); 478 autoActiveTrain.getAutoEngineer().setHalt(false); 479 if (throttle.getIsForward() ) { 480 forwardButton.setSelected(true); 481 } else { 482 reverseButton.setSelected(true); 483 } 484 } 485 486 } else if (activeTrain.getMode() == ActiveTrain.MANUAL) { 487 activeTrain.setMode(ActiveTrain.AUTOMATIC); 488 manualButton.setText(Bundle.getMessage("ToManualButton")); 489 manualButton.setToolTipText(Bundle.getMessage("ToManualButtonHint")); 490 manualButton.setVisible(true); 491 forwardButton.setVisible(false); 492 reverseButton.setVisible(false); 493 speedSlider.setVisible(false); 494 autoActiveTrain.restoreSavedSpeedAndDirection(); 495 // autoActiveTrain.setForward(!autoActiveTrain.getRunInReverse()); 496 if ((activeTrain.getStatus() == ActiveTrain.RUNNING) || 497 (activeTrain.getStatus() == ActiveTrain.WAITING)) { 498 autoActiveTrain.setSpeedBySignal(); 499 } 500 } 501 pack(); 502 } 503 504 private JToolBar componentJPanel; 505 506 private void drawComponent() { 507 508 componentJPanel = new JToolBar(); 509 componentJPanel.setLayout(new FlowLayout()); 510 componentJPanel.setFloatable(true); 511 trainLabel = new JLabel(autoActiveTrain.getActiveTrain().getTrainName()); 512 trainLabel.setVisible(true); 513 componentJPanel.add(trainLabel); 514 stopButton = new JButton(Bundle.getMessage("ResumeButton")); 515 componentJPanel.add(stopButton); 516 stopButton.addActionListener(e -> stopResume()); 517 manualButton = new JButton(Bundle.getMessage("ToManualButton")); 518 componentJPanel.add(manualButton); 519 manualButton.addActionListener(e -> manualAutoTrain()); 520 resumeAutoRunningButton = new JButton(Bundle.getMessage("ResumeAutoButton")); 521 componentJPanel.add(resumeAutoRunningButton); 522 resumeAutoRunningButton.addActionListener(e -> resumeAutoOperation()); 523 resumeAutoRunningButton.setVisible(false); 524 resumeAutoRunningButton.setToolTipText(Bundle.getMessage("ResumeAutoButtonHint")); 525 ButtonGroup directionGroup = new ButtonGroup(); 526 forwardButton = new JRadioButton(Bundle.getMessage("ForwardRadio")); 527 componentJPanel.add(forwardButton); 528 forwardButton.addActionListener(e -> directionButton()); 529 directionGroup.add(forwardButton); 530 reverseButton = new JRadioButton(Bundle.getMessage("ReverseRadio")); 531 componentJPanel.add(reverseButton); 532 reverseButton.addActionListener(e -> directionButton()); 533 directionGroup.add(reverseButton); 534 speedSlider = new JSlider(0, 100, 0); 535 speedSlider.setPreferredSize(new Dimension(100, 20)); 536 componentJPanel.add(speedSlider); 537 speedSlider.addChangeListener(e -> { 538 if (speedSlider.isVisible()) { 539 int val = ((JSlider) (e.getSource())).getValue(); 540 float speedValue = val * 0.01f; 541 // bypass auto-engineer limits, ramping etc 542 // when in manual. 543 autoActiveTrain.getThrottle().setSpeedSetting(speedValue); 544 } 545 }); 546 547 throttleStatus = new JLabel(); 548 // prevent JFrame to resize on each % change - temporary size for initialization 549 throttleStatus.setPreferredSize(new Dimension(100, 20)); 550 throttleStatus.setText("Speed Unknown"); 551 componentJPanel.add(throttleStatus); 552 componentJPanel.revalidate(); 553 add(componentJPanel, BorderLayout.EAST); 554 pack(); 555 } 556 557 /* 558 * Using dummy strings get max size of the statustext 559 */ 560 private void setStatusLabelWidth() { 561 if (rosterEntry!=null && autoActiveTrain.getUseSpeedProfile()) { 562 throttleStatus.setPreferredSize( 563 new JTextField(20).getPreferredSize()); 564 } else { 565 throttleStatus.setPreferredSize( 566 new JTextField(10).getPreferredSize()); 567 } 568 } 569 public void stopResume() { 570 if (autoActiveTrain.getAutoEngineer() != null) { 571 ActiveTrain at = autoActiveTrain.getActiveTrain(); 572 if (at.getStatus() == ActiveTrain.STOPPED) { 573 log.trace("Train Is Stopped - Resume"); 574 autoActiveTrain.setEngineDirection(); 575 autoActiveTrain.getAutoEngineer().setHalt(false); 576 autoActiveTrain.restoreSavedSpeedAndDirection(); 577 at.setStatus(autoActiveTrain.getSavedStatus()); 578 if ((at.getStatus() == ActiveTrain.RUNNING) || (at.getStatus() == ActiveTrain.WAITING)) { 579 autoActiveTrain.setSpeedBySignal(); 580 } 581 } else if (at.getStatus() == ActiveTrain.READY) { 582 handleActiveTrainListen(new java.beans.PropertyChangeEvent (this,"status", Integer.valueOf(0), Integer.valueOf(ActiveTrain.READY))); 583 } else if (at.getStatus() == ActiveTrain.DONE) { 584 log.trace("Train Is Done - Restart"); 585 // restart 586 at.allocateAFresh(); 587 at.restart(); 588 } else { 589 log.trace("Process As Stop"); 590 // stop 591 autoActiveTrain.saveSpeedAndDirection(); 592 autoActiveTrain.getAutoEngineer().setHalt(true); 593 autoActiveTrain.setSavedStatus(at.getStatus()); 594 at.setStatus(ActiveTrain.STOPPED); 595 speedSlider.setValue(0); 596 } 597 } else { 598 log.error("unexpected null autoEngineer"); 599 } 600 } 601 602 603 public void resumeAutoOperation() { 604 autoActiveTrain.resumeAutomaticRunning(); 605 } 606 607 public void directionButton() { 608 ActiveTrain at = autoActiveTrain.getActiveTrain(); 609 if (at.getMode() == ActiveTrain.MANUAL) { 610 autoActiveTrain.setForward(forwardButton.isSelected()); 611 } else { 612 log.debug(" {}:Ignored direction button change, not in manual mode", at.getTrainName()); 613 } 614 } 615 } 616 617 private final static Logger log = LoggerFactory.getLogger(AutoTrainsFrame.class); 618 619} 620 621