001package jmri.jmrit.logix; 002 003import java.awt.Color; 004import java.util.ArrayList; 005import java.util.Iterator; 006 007import javax.annotation.Nonnull; 008import javax.swing.ButtonGroup; 009import javax.swing.JButton; 010import javax.swing.JRadioButton; 011import javax.swing.JTable; 012import javax.swing.JTextField; 013 014import jmri.InstanceManager; 015import jmri.Manager; 016import jmri.jmrit.catalog.NamedIcon; 017import jmri.util.swing.JmriJOptionPane; 018import jmri.util.ThreadingUtil; 019 020/** 021 * Table Model for the Warrant List 022 * <br> 023 * <hr> 024 * This file is part of JMRI. 025 * <p> 026 * JMRI is free software; you can redistribute it and/or modify it under the 027 * terms of version 2 of the GNU General Public License as published by the Free 028 * Software Foundation. See the "COPYING" file for a copy of this license. 029 * <p> 030 * JMRI is distributed in the hope that it will be useful, but WITHOUT ANY 031 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 032 * A PARTICULAR PURPOSE. See the GNU General Public License for more details. 033 * 034 * @author Pete Cressman Copyright (C) 2009, 2010 035 */ 036 037class WarrantTableModel extends jmri.jmrit.beantable.BeanTableDataModel<Warrant> { 038 public static final int WARRANT_COLUMN = 0; 039 public static final int ROUTE_COLUMN = 1; 040 public static final int TRAIN_NAME_COLUMN = 2; 041 public static final int ADDRESS_COLUMN = 3; 042 public static final int ALLOCATE_COLUMN = 4; 043 public static final int DEALLOC_COLUMN = 5; 044 public static final int AUTO_RUN_COLUMN = 6; 045 public static final int MANUAL_RUN_COLUMN = 7; 046 public static final int CONTROL_COLUMN = 8; 047 public static final int EDIT_COLUMN = 9; 048 public static final int DELETE_COLUMN = 10; 049 public static final int NUMCOLS = 11; 050 051 WarrantManager _manager; 052 WarrantTableFrame _frame; 053 private ArrayList<Warrant> _warList; 054 private final ArrayList<Warrant> _warNX; // temporary warrants appended to table 055 static Color myGreen = new Color(0, 100, 0); 056 static Color myGold = new Color(200, 100, 0); 057 058 public WarrantTableModel(WarrantTableFrame frame) { 059 super(); 060 _frame = frame; 061 _manager = InstanceManager.getDefault(WarrantManager.class); 062 _manager.addPropertyChangeListener(WarrantTableModel.this); // for adds and deletes 063 _warList = new ArrayList<>(); 064 _warNX = new ArrayList<>(); 065 } 066 067 public void addHeaderListener(JTable table) { 068 addMouseListenerToHeader(table); 069 } 070 071 @Override 072 public Manager<Warrant> getManager() { 073 _manager = InstanceManager.getDefault(WarrantManager.class); 074 return _manager; 075 } 076 077 @Override 078 public Warrant getBySystemName(@Nonnull String name) { 079 return _manager.getBySystemName(name); 080 } 081 082 @Override 083 public String getValue(String name) { 084 Warrant w = _manager.getBySystemName(name); 085 if (w == null) { 086 return null; 087 } 088 return w.getDisplayName(); 089 } 090 091 @Override 092 public Warrant getByUserName(@Nonnull String name) { 093 return _manager.getByUserName(name); 094 } 095 096 @Override 097 protected String getBeanType() { 098 return "Warrant"; 099 } 100 101 @Override 102 public void clickOn(Warrant t) { 103 } 104 105 @Override 106 protected String getMasterClassName() { 107 return WarrantTableModel.class.getName(); 108 } 109 110 /** 111 * Preserve current listeners so that there is no gap to miss a 112 * propertyChange 113 */ 114 public synchronized void init() { 115 ArrayList<Warrant> tempList = new ArrayList<>(); 116 // copy over warrants still listed 117 for (Warrant w : _manager.getNamedBeanSet()) { 118 if (!_warList.contains(w)) { // new warrant 119 w.addPropertyChangeListener(this); 120 } else { 121 _warList.remove(w); 122 } 123 cleanBlockOrderList(w); // removes bad BlockOrders 124 tempList.add(w); // add old or any new warrants 125 } 126 // remove listeners from any deleted warrants 127 for (int i = 0; i < _warList.size(); i++) { 128 Warrant w = _warList.get(i); 129 if (!_warNX.contains(w)) { // don't touch current running NXWarrant 130 w.removePropertyChangeListener(this); 131 } 132 } 133 // add in current temporary NX warrants 134 for (int i = 0; i < _warNX.size(); i++) { 135 tempList.add(_warNX.get(i)); 136 } 137 _warList = tempList; 138 } 139 140 private void cleanBlockOrderList(Warrant warrant) { 141 ArrayList<BlockOrder> valid = new ArrayList<>(); 142 Iterator<BlockOrder> iter = warrant.getBlockOrders().iterator(); 143 while (iter.hasNext()) { 144 BlockOrder bo = iter.next(); 145 if (WarrantRoute.pathIsValid(bo.getBlock(), bo.getPathName()) == null) { 146 valid.add(bo); 147 } 148 } 149 warrant.setBlockOrders(valid); 150 } 151 152 protected void haltAllTrains() { 153 ArrayList<Warrant> abortList = new ArrayList<>(); 154 Iterator<Warrant> iter = _warList.iterator(); 155 while (iter.hasNext()) { 156 Warrant w = iter.next(); 157 if (w.getState() >= 0) { 158 abortList.add(w); 159 } 160 } 161 iter = abortList.iterator(); 162 while (iter.hasNext()) { 163 iter.next().controlRunTrain(Warrant.STOP); 164 } 165 fireTableUpdate(); 166 } 167 168 protected void addNXWarrant(Warrant w) { 169 _warList.add(w); 170 _warNX.add(w); 171 w.addPropertyChangeListener(this); 172 fireTableUpdate(); 173 } 174 175 /** 176 * Removes any warrant, not just NXWarrant 177 * @param w Warrant 178 * @param deregister deregister warrant 179 */ 180 public void removeWarrant(Warrant w, boolean deregister) { 181 log.debug("removeWarrant {}", w.getDisplayName()); 182 _warList.remove(w); 183 _warNX.remove(w); 184 if (deregister) { 185 _manager.deregister(w); 186 } 187 w.dispose(); 188 } 189 190 public Warrant getWarrantAt(int index) { 191 if (index >= _warList.size()) { 192 return null; 193 } 194 return _warList.get(index); 195 } 196 197 protected Warrant getWarrant(String name) { 198 if (name==null || name.length()==0) { 199 return null; 200 } 201 for (Warrant w: _warList) { 202 if (name.equals(w.getUserName()) || name.equals(w.getSystemName())) { 203 return w; 204 } 205 } 206 return null; 207 } 208 209 protected String checkAddressInUse(Warrant warrant) { 210 jmri.DccLocoAddress address = warrant.getSpeedUtil().getDccAddress(); 211 212 if (address ==null) { 213 return Bundle.getMessage("NoLoco"); 214 } 215 for (Warrant w :_warList) { 216 if (w.equals(warrant)) { 217 continue; 218 } 219 if (w._runMode != Warrant.MODE_NONE) { 220 if (address.equals(w.getSpeedUtil().getDccAddress())) { 221 return Bundle.getMessage("AddressInUse", address, w.getDisplayName(), w.getTrainName()); 222 } 223 } 224 } 225 return null; 226 } 227 228 @Override 229 public int getRowCount() { 230 return _warList.size(); 231 } 232 233 protected int getRow(Warrant w) { 234 int row = -1; 235 Iterator<Warrant> iter = _warList.iterator(); 236 while (iter.hasNext()) { 237 row++; 238 Warrant war = iter.next(); 239 if (war.equals(w)) { 240 return row; 241 } 242 } 243 return -1; 244 } 245 246 @Override 247 public int getColumnCount() { 248 return NUMCOLS; 249 } 250 251 @Override 252 public String getColumnName(int col) { 253 switch (col) { 254 case WARRANT_COLUMN: 255 return Bundle.getMessage("Warrant"); 256 case ROUTE_COLUMN: 257 return Bundle.getMessage("Route"); 258 case TRAIN_NAME_COLUMN: 259 return Bundle.getMessage("TrainName"); 260 case ADDRESS_COLUMN: 261 return Bundle.getMessage("DccAddress"); 262 case ALLOCATE_COLUMN: 263 return Bundle.getMessage("Allocate"); 264 case DEALLOC_COLUMN: 265 return Bundle.getMessage("Deallocate"); 266 case AUTO_RUN_COLUMN: 267 return Bundle.getMessage("ARun"); 268 case MANUAL_RUN_COLUMN: 269 return Bundle.getMessage("MRun"); 270 case CONTROL_COLUMN: 271 return Bundle.getMessage("Control"); 272 default: 273 // fall out 274 break; 275 } 276 return ""; 277 } 278 279 @Override 280 public boolean isCellEditable(int row, int col) { 281 switch (col) { 282 case WARRANT_COLUMN: 283 return false; 284 case TRAIN_NAME_COLUMN: 285 case ADDRESS_COLUMN: 286 case ROUTE_COLUMN: 287 case ALLOCATE_COLUMN: 288 case DEALLOC_COLUMN: 289 case AUTO_RUN_COLUMN: 290 case MANUAL_RUN_COLUMN: 291 case CONTROL_COLUMN: 292 case EDIT_COLUMN: 293 case DELETE_COLUMN: 294 return true; 295 default: 296 // fall out 297 break; 298 } 299 return false; 300 } 301 302 @Override 303 public Class<?> getColumnClass(int col) { 304 switch (col) { 305 case WARRANT_COLUMN: 306 return String.class; 307 case ROUTE_COLUMN: 308 return String.class; // JComboBox.class; 309 case TRAIN_NAME_COLUMN: 310 return String.class; 311 case ADDRESS_COLUMN: 312 return String.class; 313 case ALLOCATE_COLUMN: 314 return JButton.class; 315 case DEALLOC_COLUMN: 316 return JButton.class; 317 case AUTO_RUN_COLUMN: 318 return JButton.class; 319 case MANUAL_RUN_COLUMN: 320 return JButton.class; 321 case CONTROL_COLUMN: 322 return String.class; // JComboBox.class; 323 case EDIT_COLUMN: 324 return JButton.class; 325 case DELETE_COLUMN: 326 return JButton.class; 327 default: 328 // fall out 329 break; 330 } 331 return String.class; 332 } 333 334 @Override 335 public int getPreferredWidth(int col) { 336 switch (col) { 337 case WARRANT_COLUMN: 338 case TRAIN_NAME_COLUMN: 339 case ADDRESS_COLUMN: 340 return new JTextField(13).getPreferredSize().width; 341 case ROUTE_COLUMN: 342 return new JTextField(25).getPreferredSize().width; 343 case ALLOCATE_COLUMN: 344 case DEALLOC_COLUMN: 345 case AUTO_RUN_COLUMN: 346 case MANUAL_RUN_COLUMN: 347 return new JButton("Xxxx").getPreferredSize().width; 348 case CONTROL_COLUMN: 349 return new JTextField(60).getPreferredSize().width; 350 case EDIT_COLUMN: 351 return new JButton(Bundle.getMessage("ButtonEdit")).getPreferredSize().width; 352 case DELETE_COLUMN: 353 return new JButton(Bundle.getMessage("ButtonDelete")).getPreferredSize().width; 354 default: 355 // fall out 356 break; 357 } 358 return new JTextField(10).getPreferredSize().width; 359 } 360 361 static String GREEN_LED = "resources/icons/smallschematics/tracksegments/circuit-green.gif"; 362 static String YELLOW_LED = "resources/icons/smallschematics/tracksegments/circuit-occupied.gif"; 363 static String OFF_LED = "resources/icons/smallschematics/tracksegments/circuit-empty.gif"; 364 static String RED_LED = "resources/icons/smallschematics/tracksegments/circuit-error.gif"; 365 366 @Override 367 public Object getValueAt(int row, int col) { 368 Warrant w = getWarrantAt(row); 369 // some error checking 370 if (w == null) { // if NXWarrant is aborted while save/edit frame is open, closing frame causes update 371// log.warn("getValueAt row= {}, Warrant is null!", row); 372 return ""; 373 } 374 JRadioButton allocButton = new JRadioButton(); 375 JRadioButton deallocButton = new JRadioButton(); 376 ButtonGroup group = new ButtonGroup(); 377 group.add(allocButton); 378 group.add(deallocButton); 379 switch (col) { 380 case WARRANT_COLUMN: 381 return w.getDisplayName(); 382 case ROUTE_COLUMN: 383 BlockOrder bo0 = w.getfirstOrder(); 384 BlockOrder bo1 = w.getLastOrder(); 385 return Bundle.getMessage("WarrantRoute", 386 (bo0==null?"?":bo0.getBlock().getDisplayName()), 387 (bo1==null?"?":bo1.getBlock().getDisplayName())); 388 case TRAIN_NAME_COLUMN: 389 return w.getTrainName(); 390 case ADDRESS_COLUMN: 391 return w.getSpeedUtil().getRosterId(); 392 case ALLOCATE_COLUMN: 393 NamedIcon icon; 394 if (w.isTotalAllocated()) { 395 icon = new NamedIcon(GREEN_LED, "green"); 396 } else if (w.isAllocated()) { 397 icon = new NamedIcon(YELLOW_LED, "yellow"); 398 } else { 399 icon = new NamedIcon(OFF_LED, "off"); 400 } 401 return icon; 402 case DEALLOC_COLUMN: 403 if (w.isAllocated()) { 404 icon = new NamedIcon(OFF_LED, "off"); 405 } else { 406 icon = new NamedIcon(YELLOW_LED, "occupied"); 407 } 408 return icon; 409 case AUTO_RUN_COLUMN: 410 if (w.getRunMode() == Warrant.MODE_RUN) { 411 icon = new NamedIcon(RED_LED, "red"); 412 } else { 413 icon = new NamedIcon(OFF_LED, "off"); 414 } 415 return icon; 416 case MANUAL_RUN_COLUMN: 417 if (w.getRunMode() == Warrant.MODE_MANUAL) { 418 return new NamedIcon( 419 "resources/icons/smallschematics/tracksegments/circuit-error.gif", 420 "red"); 421 } 422 return new NamedIcon( 423 "resources/icons/smallschematics/tracksegments/circuit-empty.gif", 424 "off"); 425 case CONTROL_COLUMN: 426 String msg = w.getRunningMessage(); 427 return msg; 428 case EDIT_COLUMN: 429 if (w.isNXWarrant()) { 430 return Bundle.getMessage("ButtonSave"); 431 } else { 432 return Bundle.getMessage("ButtonEdit"); 433 } 434 case DELETE_COLUMN: 435 return Bundle.getMessage("ButtonDelete"); 436 default: 437 // fall out 438 break; 439 } 440 return ""; 441 } 442 443 @Override 444 public void setValueAt(Object value, int row, int col) { 445 Warrant w = getWarrantAt(row); 446 if (w == null) { 447 log.warn("setValueAt row= {}, Warrant is null!", row); 448 return; 449 } 450 String msg = null; 451 switch (col) { 452 case WARRANT_COLUMN: 453 case ROUTE_COLUMN: 454 return; 455 case TRAIN_NAME_COLUMN: 456 w.setTrainName((String) value); 457 break; 458 case ADDRESS_COLUMN: 459 if (w.getRunMode() == Warrant.MODE_NONE) { 460 String addr = (String) value; 461 if (!w.getSpeedUtil().setAddress(addr)) { 462 msg = Bundle.getMessage("BadDccAddress", addr); 463 } 464 } else { 465 msg = w.getRunModeMessage(); 466 msg = Bundle.getMessage("CannotChangeAddress", w.getDisplayName(), msg); 467 } 468 break; 469 case ALLOCATE_COLUMN: 470 if (w.getRunMode() == Warrant.MODE_NONE) { 471 msg = w.allocateRoute(true, null); 472 if (msg == null) { 473 setFrameStatusText( 474 Bundle.getMessage("completeAllocate", 475 w.getDisplayName()), myGreen, false); 476 } else { 477 setFrameStatusText(Bundle.getMessage("UnableToAllocate", 478 w.getDisplayName()) + msg, myGold, false); 479 msg = null; 480 } 481 this.fireTableRowsUpdated(row, row); 482 } 483 break; 484 case DEALLOC_COLUMN: 485 if (w.getRunMode() == Warrant.MODE_NONE) { 486 w.deAllocate(); 487 setFrameStatusText("", myGreen, false); 488 this.fireTableRowsUpdated(row, row); 489 } else { 490 setFrameStatusText(w.getRunModeMessage(), myGold, false); 491 } 492 break; 493 case AUTO_RUN_COLUMN: 494 msg = frameRunTrain(w, Warrant.MODE_RUN); 495 this.fireTableRowsUpdated(row, row); 496 break; 497 case MANUAL_RUN_COLUMN: 498 msg = frameRunTrain(w, Warrant.MODE_MANUAL); 499 this.fireTableRowsUpdated(row, row); 500 break; 501 case CONTROL_COLUMN: 502 // Message is set when propertyChangeEvent (below) is received from 503 // a warrant change. fireTableRows then causes getValueAt() which 504 // calls getRunningMessage() 505 int mode = w.getRunMode(); 506 if (log.isTraceEnabled()) { 507 log.debug("setValueAt({}) for warrant {}", value, w.getDisplayName()); 508 } 509 if (mode == Warrant.MODE_LEARN) { 510 msg = Bundle.getMessage("Learning", w.getCurrentBlockName()); 511 } else if (value!=null) { 512 String setting = (String) value; 513 if (mode == Warrant.MODE_RUN || mode == Warrant.MODE_MANUAL) { 514 int s = -1; 515 if (setting.equals(WarrantTableFrame.stop)) { 516 s = Warrant.STOP; 517 } else if (setting.equals(WarrantTableFrame.ramp)) { 518 s = Warrant.HALT; 519 } else if (setting.equals(WarrantTableFrame.resume)) { 520 s = Warrant.RESUME; 521 } else if (setting.equals(WarrantTableFrame.speedup)) { 522 s = Warrant.SPEED_UP; 523 } else if (setting.equals(WarrantTableFrame.retryfwd)) { 524 s = Warrant.RETRY_FWD; 525 } else if (setting.equals(WarrantTableFrame.estop)) { 526 s = Warrant.ESTOP; 527 } else if (setting.equals(WarrantTableFrame.abort)) { 528 s = Warrant.ABORT; 529 } else if (setting.isEmpty()) { 530 s = Warrant.DEBUG; 531 } else if (setting.equals(WarrantTableFrame.retrybkwd)) { 532 s = Warrant.RETRY_BKWD; 533 } 534 if (s >= 0) { 535 w.controlRunTrain(s); 536 } 537 } 538 } 539 break; 540 case EDIT_COLUMN: 541 if (w.isNXWarrant()) { 542 saveNXWarrant(w); 543 } else { 544 openWarrantFrame(w); 545 } 546 break; 547 case DELETE_COLUMN: 548 if (w.getRunMode() == Warrant.MODE_NONE) { 549 w.deAllocate(); 550 fireTableRowDeleted(w, row, true); 551 } else { 552 w.controlRunTrain(Warrant.ABORT); 553 if (_warNX.contains(w)) { // don't remove regular warrants 554 fireTableRowDeleted(w, row, false); 555 } 556 } 557 break; 558 default: 559 log.error("Invalid Column {} requested.", col); 560 throw new java.lang.IllegalArgumentException("Invalid Column " + col + " requested."); 561 } 562 if (msg != null) { 563 showMessageDialog(msg); 564 } 565 } 566 567 private void showMessageDialog(String msg) { 568 ThreadingUtil.runOnGUIEventually(() -> 569 JmriJOptionPane.showMessageDialog(_frame, msg, 570 Bundle.getMessage("WarningTitle"), 571 JmriJOptionPane.WARNING_MESSAGE)); 572 } 573 574 private void openWarrantFrame(Warrant warrant) { 575 for (Warrant w : _warList) { 576 if (warrant.equals(w)) { 577 WarrantTableAction.getDefault().editWarrantFrame(warrant); 578 break; 579 } 580 } 581 } 582 583 private void saveNXWarrant(Warrant warrant) { 584 for (Warrant w : _warNX) { 585 if (warrant.equals(w)) { 586 Warrant war = cloneWarrant(warrant); 587 WarrantTableAction.getDefault().makeWarrantFrame(war, null); 588 break; 589 } 590 } 591 } 592 593 private Warrant cloneWarrant(Warrant warrant) { 594 Warrant w = new Warrant(InstanceManager.getDefault(WarrantManager.class).getAutoSystemName(), null); 595 w.setTrainName(warrant.getTrainName()); 596 w.setRunBlind(warrant.getRunBlind()); 597 w.setShareRoute(warrant.getShareRoute()); 598 w.setAddTracker(warrant.getAddTracker()); 599 w.setNoRamp(warrant.getNoRamp()); 600 601 for (BlockOrder bo : warrant.getBlockOrders()) { 602 w.addBlockOrder(new BlockOrder(bo)); 603 } 604 w.setViaOrder(warrant.getViaOrder()); 605 w.setAvoidOrder(warrant.getAvoidOrder()); 606 for (ThrottleSetting ts : warrant.getThrottleCommands()) { 607 w.addThrottleCommand(ts); 608 } 609 SpeedUtil copySU = w.getSpeedUtil(); 610 SpeedUtil su = warrant.getSpeedUtil(); 611 copySU.setDccAddress(su.getDccAddress()); 612 copySU.setRosterId(su.getRosterId()); 613 return w; 614 } 615 616 private String frameRunTrain(Warrant w, int mode) { 617 return jmri.util.ThreadingUtil.runOnGUIwithReturn(() -> { 618 return ( _frame.runTrain(w, mode)); 619 }); 620 } 621 622 private void setFrameStatusText(String m, Color c, boolean save) { 623 ThreadingUtil.runOnGUIEventually(()-> _frame.setStatusText(m, c, true)); 624 } 625 626 private void fireCellUpdate(int row, int col) { 627 ThreadingUtil.runOnGUIEventually(()-> { 628 if (row < _warList.size()) { // when Aborted, row may be gone by now 629 fireTableCellUpdated(row, col); 630 } 631 }); 632 } 633 634 private void fireTableUpdate() { 635 ThreadingUtil.runOnGUIEventually(this::fireTableDataChanged); 636 } 637 638 private void fireTableRowDeleted(Warrant w, int row, boolean all) { 639 ThreadingUtil.runOnGUIEventually(()-> { 640 removeWarrant(w, all); // true any warrant, false NX only 641 if (row < _warList.size()) { 642 fireTableRowsDeleted(row, row); 643 } 644 }); 645 } 646 647 private void fireTableRowUpdated(Warrant w, int row) { 648 if (row < _warList.size()) { 649 ThreadingUtil.runOnGUIEventually(()-> fireTableRowsUpdated(row, row)); 650 } 651 } 652 653 private String _lastProperty; 654 private long _propertyTime; 655 656 @Override 657 public void propertyChange(java.beans.PropertyChangeEvent e) { 658 String property = e.getPropertyName(); 659 long time = _propertyTime; 660 _propertyTime = System.currentTimeMillis(); 661 if ((_propertyTime-time)<20 && property.equals(_lastProperty) && !property.equals("length")) { 662 return; 663 } 664 _lastProperty = property; 665 666 if (property.equals("length")) { 667 // a NamedBean added or deleted 668 init(); 669 fireTableUpdate(); 670 } else if (e.getSource() instanceof Warrant) { 671 // a value changed. Find it, to avoid complete redraw 672 Warrant bean = (Warrant) e.getSource(); 673 log.debug("source is warrant {}", bean.getDisplayName()); 674 int row = getRow(bean); 675 if (row < 0) { // warrant deleted 676 return; 677 } 678 fireTableRowUpdated(bean, row); 679 680 if (property.equals("blockChange")) { 681 OBlock oldBlock = (OBlock) e.getOldValue(); 682 OBlock newBlock = (OBlock) e.getNewValue(); 683 if (newBlock == null) { 684 setFrameStatusText(Bundle.getMessage("ChangedRoute", 685 bean.getTrainName(), oldBlock.getDisplayName(), 686 bean.getDisplayName()), Color.red, true); 687 } else { 688 setFrameStatusText(Bundle.getMessage("TrackerBlockEnter", 689 bean.getTrainName(), 690 newBlock.getDisplayName()), myGreen, true); 691 } 692 } else if (property.equals("SpeedChange")) { 693 fireCellUpdate(row, CONTROL_COLUMN); 694 } else if (property.equals("WaitForSync")) { 695 fireCellUpdate(row, CONTROL_COLUMN); 696 } else if (property.equals("cannotRun")) { 697 fireCellUpdate(row, CONTROL_COLUMN); 698 setFrameStatusText(Bundle.getMessage("trainWaiting", bean.getTrainName(), 699 e.getNewValue(), e.getOldValue()), Color.red, true); 700 } else if (property.equals("SignalOverrun")) { 701 String name = (String) e.getOldValue(); 702 String speed = (String) e.getNewValue(); 703 setFrameStatusText(Bundle.getMessage("SignalOverrun", 704 bean.getTrainName(), speed, name), Color.red, true); 705 } else if (property.equals("OccupyOverrun")) { 706 String blkName = (String) e.getOldValue(); 707 String occuppier = (String) e.getNewValue(); 708 setFrameStatusText(Bundle.getMessage("OccupyOverrun", 709 bean.getTrainName(), blkName, occuppier), Color.red, true); 710 } else if (property.equals("WarrantOverrun")) { 711 String blkName = (String) e.getOldValue(); 712 String warName = (String) e.getNewValue(); 713 setFrameStatusText(Bundle.getMessage("WarrantOverrun", 714 bean.getTrainName(), blkName, warName), Color.red, true); 715 } else if (property.equals("WarrantStart")) { 716 setFrameStatusText(Bundle.getMessage("warrantStart", 717 bean.getTrainName(), bean.getDisplayName(), 718 bean.getCurrentBlockName()), myGreen, true); 719 } else if (property.equals("StopWarrant")) { 720 String blkName = (String) e.getOldValue(); 721 String bundleKey = (String) e.getNewValue(); 722 if (blkName == null) { 723 setFrameStatusText(Bundle.getMessage(bundleKey, 724 bean.getTrainName(), bean.getDisplayName()), 725 myGreen, true); 726 } else { 727 setFrameStatusText(Bundle.getMessage(bundleKey, 728 bean.getTrainName(), bean.getDisplayName(), 729 blkName), myGold, true); 730 } 731 if (_warNX.contains(bean)) { 732 fireTableRowDeleted(bean, row, false); 733 } 734 } else if (property.equals("RampDone")) { 735 boolean halt = ((Boolean) e.getOldValue()); 736 String speed = (String) e.getNewValue(); 737 if (halt || speed.equals(Warrant.EStop)) { 738 setFrameStatusText(Bundle.getMessage("RampHalt", 739 bean.getTrainName(), bean.getCurrentBlockName()), myGreen, true); 740 } else { 741 setFrameStatusText(Bundle.getMessage("RampSpeed", bean.getTrainName(), 742 speed, bean.getCurrentBlockName()), myGreen, true); 743 } 744 fireCellUpdate(row, CONTROL_COLUMN); 745 } else if (property.equals("RampBegin")) { 746 String reason = (String) e.getOldValue(); 747 String blkName = (String) e.getNewValue(); 748 setFrameStatusText(Bundle.getMessage("RampBegin", bean.getTrainName(), 749 reason, blkName), myGreen, true); 750 } else if (property.equals("ReadyToRun")) { 751 setFrameStatusText(Bundle.getMessage("TrainReady", 752 bean.getTrainName(), bean.getCurrentBlockName()), myGreen, true); 753 } else if (property.equals("controlChange")) { 754 String blkName = bean.getCurrentBlockName(); 755 int newCntrl = ((Integer) e.getNewValue()); 756 setFrameStatusText(Bundle.getMessage("controlChange", bean.getTrainName(), 757 Bundle.getMessage(Warrant.CNTRL_CMDS[newCntrl]), blkName), 758 myGold, true); 759 fireCellUpdate(row, CONTROL_COLUMN); 760 } else if (property.equals("controlFailed")) { 761 String blkName = bean.getCurrentBlockName(); 762 String stateStr; 763 if (e.getOldValue()==null) { 764 stateStr = blkName; 765 } else { 766 stateStr = ((String) e.getOldValue()); 767 } 768 int newCntrl = ((Integer) e.getNewValue()); 769 setFrameStatusText(Bundle.getMessage("controlFailed", 770 bean.getTrainName(), stateStr, 771 Bundle.getMessage(Warrant.CNTRL_CMDS[newCntrl])), 772 Color.red, true); 773 fireCellUpdate(row, CONTROL_COLUMN); 774 } else if (property.equals("SensorSetCommand")) { 775 String action = (String) e.getOldValue(); 776 String sensorName = (String) e.getNewValue(); 777 setFrameStatusText(Bundle.getMessage("setSensor", 778 bean.getTrainName(), sensorName, action), myGreen, true); 779 } else if (property.equals("SensorWaitCommand")) { 780 String action = (String) e.getOldValue(); 781 String sensorName = (String) e.getNewValue(); 782 if (action != null) { 783 setFrameStatusText(Bundle.getMessage("waitSensor", 784 bean.getTrainName(), sensorName, action), myGreen, true); 785 } else { 786 setFrameStatusText(Bundle.getMessage("waitSensorChange", 787 bean.getTrainName(), sensorName), myGreen, true); 788 } 789 fireCellUpdate(row, CONTROL_COLUMN); 790 } else if (property.equals("throttleFail")) { 791 setFrameStatusText(Bundle.getMessage("ThrottleFail", 792 bean.getTrainName(), e.getNewValue()), Color.red, true); 793 } 794 if (log.isDebugEnabled()) { 795 log.debug("propertyChange of \"{}\" done for warrant \"{}\"", 796 property, bean.getDisplayName()); 797 } 798 } 799 } 800 801 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(WarrantTableModel.class); 802 803}