001package jmri.jmrit.operations.rollingstock.engines.gui; 002 003import java.beans.PropertyChangeEvent; 004import java.beans.PropertyChangeListener; 005import java.util.List; 006 007import javax.swing.*; 008import javax.swing.table.TableCellEditor; 009 010import org.slf4j.Logger; 011import org.slf4j.LoggerFactory; 012 013import jmri.InstanceManager; 014import jmri.jmrit.operations.OperationsTableModel; 015import jmri.jmrit.operations.rollingstock.RollingStock; 016import jmri.jmrit.operations.rollingstock.engines.*; 017import jmri.jmrit.operations.setup.Control; 018import jmri.jmrit.operations.setup.Setup; 019import jmri.util.swing.XTableColumnModel; 020import jmri.util.table.ButtonEditor; 021import jmri.util.table.ButtonRenderer; 022 023/** 024 * Table Model for edit of engines used by operations 025 * 026 * @author Daniel Boudreau Copyright (C) 2008, 2012, 2025 027 */ 028public class EnginesTableModel extends OperationsTableModel implements PropertyChangeListener { 029 030 EngineManager engineManager = InstanceManager.getDefault(EngineManager.class); // There is only one manager 031 032 // Defines the columns 033 private static final int SELECT_COLUMN = 0; 034 private static final int NUM_COLUMN = 1; 035 private static final int ROAD_COLUMN = 2; 036 private static final int MODEL_COLUMN = 3; 037 private static final int HP_COLUMN = 4; 038 private static final int WEIGHT_COLUMN = 5; 039 private static final int TYPE_COLUMN = 6; 040 private static final int LENGTH_COLUMN = 7; 041 private static final int CONSIST_COLUMN = 8; 042 private static final int LOCATION_COLUMN = 9; 043 private static final int RFID_WHERE_LAST_SEEN_COLUMN = 10; 044 private static final int RFID_WHEN_LAST_SEEN_COLUMN = 11; 045 private static final int DESTINATION_COLUMN = 12; 046 private static final int PREVIOUS_LOCATION_COLUMN = 13; 047 private static final int TRAIN_COLUMN = 14; 048 private static final int LAST_TRAIN_COLUMN = 15; 049 private static final int MOVES_COLUMN = 16; 050 private static final int BUILT_COLUMN = 17; 051 private static final int OWNER_COLUMN = 18; 052 private static final int VALUE_COLUMN = 19; 053 private static final int RFID_COLUMN = 20; 054 private static final int LAST_COLUMN = 21; 055 private static final int DCC_ADDRESS_COLUMN = 22; 056 private static final int PICKUP_COLUMN = 23; 057 private static final int SETOUT_COLUMN = 24; 058 private static final int COMMENT_COLUMN = 25; 059 private static final int SET_COLUMN = 26; 060 private static final int EDIT_COLUMN = 27; 061 062 private static final int HIGHEST_COLUMN = EDIT_COLUMN + 1; 063 064 public EnginesTableModel(boolean showAllLocos, String locationName, String trackName) { 065 super(); 066 showAll = showAllLocos; 067 this.locationName = locationName; 068 this.trackName = trackName; 069 engineManager.addPropertyChangeListener(this); 070 updateList(); 071 } 072 073 public final int SORTBY_NUMBER = 0; 074 public final int SORTBY_ROAD = 1; 075 public final int SORTBY_MODEL = 2; 076 public final int SORTBY_LOCATION = 3; 077 public final int SORTBY_DESTINATION = 4; 078 public final int SORTBY_TRAIN = 5; 079 public final int SORTBY_MOVES = 6; 080 public final int SORTBY_CONSIST = 7; 081 public final int SORTBY_BUILT = 8; 082 public final int SORTBY_OWNER = 9; 083 public final int SORTBY_VALUE = 10; 084 public final int SORTBY_RFID = 11; 085 public final int SORTBY_LAST = 12; 086 public final int SORTBY_HP = 13; 087 public final int SORTBY_DCC_ADDRESS = 14; 088 public final int SORTBY_PICKUP = 15; 089 public final int SORTBY_COMMENT = 16; 090 091 private int _sort = SORTBY_NUMBER; 092 093 /** 094 * Not all columns are visible at the same time. 095 * 096 * @param sort which sort is active 097 */ 098 public void setSort(int sort) { 099 _sort = sort; 100 updateList(); 101 if (sort == SORTBY_MOVES || 102 sort == SORTBY_BUILT || 103 sort == SORTBY_OWNER || 104 sort == SORTBY_VALUE || 105 sort == SORTBY_RFID || 106 sort == SORTBY_LAST || 107 sort == SORTBY_DCC_ADDRESS || 108 sort == SORTBY_PICKUP || 109 sort == SORTBY_COMMENT) { 110 XTableColumnModel tcm = (XTableColumnModel) _table.getColumnModel(); 111 tcm.setColumnVisible(tcm.getColumnByModelIndex(MOVES_COLUMN), sort == SORTBY_MOVES); 112 tcm.setColumnVisible(tcm.getColumnByModelIndex(BUILT_COLUMN), sort == SORTBY_BUILT); 113 tcm.setColumnVisible(tcm.getColumnByModelIndex(OWNER_COLUMN), sort == SORTBY_OWNER); 114 tcm.setColumnVisible(tcm.getColumnByModelIndex(VALUE_COLUMN), sort == SORTBY_VALUE); 115 tcm.setColumnVisible(tcm.getColumnByModelIndex(RFID_COLUMN), sort == SORTBY_RFID); 116 tcm.setColumnVisible(tcm.getColumnByModelIndex(RFID_WHEN_LAST_SEEN_COLUMN), sort == SORTBY_RFID); 117 tcm.setColumnVisible(tcm.getColumnByModelIndex(RFID_WHERE_LAST_SEEN_COLUMN), sort == SORTBY_RFID); 118 tcm.setColumnVisible(tcm.getColumnByModelIndex(PREVIOUS_LOCATION_COLUMN), sort == SORTBY_LAST); 119 tcm.setColumnVisible(tcm.getColumnByModelIndex(LAST_COLUMN), sort == SORTBY_LAST); 120 tcm.setColumnVisible(tcm.getColumnByModelIndex(LAST_TRAIN_COLUMN), sort == SORTBY_LAST); 121 tcm.setColumnVisible(tcm.getColumnByModelIndex(TRAIN_COLUMN), true); 122 tcm.setColumnVisible(tcm.getColumnByModelIndex(PICKUP_COLUMN), sort == SORTBY_PICKUP); 123 tcm.setColumnVisible(tcm.getColumnByModelIndex(SETOUT_COLUMN), sort == SORTBY_PICKUP); 124 tcm.setColumnVisible(tcm.getColumnByModelIndex(DCC_ADDRESS_COLUMN), sort == SORTBY_DCC_ADDRESS); 125 tcm.setColumnVisible(tcm.getColumnByModelIndex(COMMENT_COLUMN), sort == SORTBY_COMMENT); 126 } 127 fireTableDataChanged(); 128 } 129 130 public void toggleSelectVisible() { 131 XTableColumnModel tcm = (XTableColumnModel) _table.getColumnModel(); 132 tcm.setColumnVisible(tcm.getColumnByModelIndex(SELECT_COLUMN), 133 !tcm.isColumnVisible(tcm.getColumnByModelIndex(SELECT_COLUMN))); 134 } 135 136 public void resetCheckboxes() { 137 for (Engine engine : engineList) { 138 engine.setSelected(false); 139 } 140 } 141 142 public String getSortByName() { 143 return getSortByName(_sort); 144 } 145 146 public String getSortByName(int sort) { 147 switch (sort) { 148 case SORTBY_NUMBER: 149 return Bundle.getMessage("Number"); 150 case SORTBY_ROAD: 151 return Bundle.getMessage("Road"); 152 case SORTBY_MODEL: 153 return Bundle.getMessage("Model"); 154 case SORTBY_LOCATION: 155 return Bundle.getMessage("Location"); 156 case SORTBY_DESTINATION: 157 return Bundle.getMessage("Destination"); 158 case SORTBY_TRAIN: 159 return Bundle.getMessage("Train"); 160 case SORTBY_MOVES: 161 return Bundle.getMessage("Moves"); 162 case SORTBY_CONSIST: 163 return Bundle.getMessage("Consist"); 164 case SORTBY_BUILT: 165 return Bundle.getMessage("Built"); 166 case SORTBY_OWNER: 167 return Bundle.getMessage("Owner"); 168 case SORTBY_DCC_ADDRESS: 169 return Bundle.getMessage("DccAddress"); 170 case SORTBY_HP: 171 return Bundle.getMessage("HP"); 172 case SORTBY_VALUE: 173 return Setup.getValueLabel(); 174 case SORTBY_RFID: 175 return Setup.getRfidLabel(); 176 case SORTBY_LAST: 177 return Bundle.getMessage("Last"); 178 case SORTBY_COMMENT: 179 return Bundle.getMessage("Comment"); 180 default: 181 return Bundle.getMessage("ErrorTitle"); // NOI18N 182 } 183 } 184 185 /** 186 * Search for engine by road number 187 * 188 * @param roadNumber The string road number to search for. 189 * 190 * @return -1 if not found, table row number if found 191 */ 192 public int findEngineByRoadNumber(String roadNumber) { 193 return findRollingStockByRoadNumber(roadNumber, engineList); 194 } 195 196 public Engine getEngineAtIndex(int index) { 197 return engineList.get(index); 198 } 199 200 private void updateList() { 201 // first, remove listeners from the individual objects 202 removePropertyChangeEngines(); 203 engineList = getSelectedEngineList(); 204 // and add listeners back in 205 addPropertyChangeEngines(); 206 } 207 208 public List<Engine> getSelectedEngineList() { 209 return getEngineList(_sort); 210 } 211 212 public List<Engine> getEngineList(int sort) { 213 List<Engine> list; 214 switch (sort) { 215 case SORTBY_ROAD: 216 list = engineManager.getByRoadNameList(); 217 break; 218 case SORTBY_MODEL: 219 list = engineManager.getByModelList(); 220 break; 221 case SORTBY_LOCATION: 222 list = engineManager.getByLocationList(); 223 break; 224 case SORTBY_DESTINATION: 225 list = engineManager.getByDestinationList(); 226 break; 227 case SORTBY_TRAIN: 228 list = engineManager.getByTrainList(); 229 break; 230 case SORTBY_MOVES: 231 list = engineManager.getByMovesList(); 232 break; 233 case SORTBY_CONSIST: 234 list = engineManager.getByConsistList(); 235 break; 236 case SORTBY_OWNER: 237 list = engineManager.getByOwnerList(); 238 break; 239 case SORTBY_BUILT: 240 list = engineManager.getByBuiltList(); 241 break; 242 case SORTBY_VALUE: 243 list = engineManager.getByValueList(); 244 break; 245 case SORTBY_RFID: 246 list = engineManager.getByRfidList(); 247 break; 248 case SORTBY_LAST: 249 list = engineManager.getByLastDateList(); 250 break; 251 case SORTBY_PICKUP: 252 list = engineManager.getByPickupList(); 253 break; 254 case SORTBY_COMMENT: 255 list = engineManager.getByCommentList(); 256 break; 257 case SORTBY_NUMBER: 258 default: 259 list = engineManager.getByNumberList(); 260 } 261 filterList(list); 262 return list; 263 } 264 265 List<Engine> engineList = null; 266 267 EnginesTableFrame _frame; 268 269 void initTable(JTable table, EnginesTableFrame frame) { 270 _table = table; 271 _frame = frame; 272 initTable(); 273 } 274 275 // Default engines frame table column widths, starts with Number column and ends with Edit 276 private final int[] _enginesTableColumnWidths = 277 {60, 60, 60, 65, 50, 65, 65, 35, 75, 190, 190, 190, 140, 190, 65, 90, 50, 50, 50, 50, 100, 130, 50, 50, 50, 278 100, 65, 70}; 279 280 void initTable() { 281 // Use XTableColumnModel so we can control which columns are visible 282 XTableColumnModel tcm = new XTableColumnModel(); 283 _table.setColumnModel(tcm); 284 _table.createDefaultColumnsFromModel(); 285 286 // Install the button handlers 287 ButtonRenderer buttonRenderer = new ButtonRenderer(); 288 tcm.getColumn(SET_COLUMN).setCellRenderer(buttonRenderer); 289 TableCellEditor buttonEditor = new ButtonEditor(new javax.swing.JButton()); 290 tcm.getColumn(SET_COLUMN).setCellEditor(buttonEditor); 291 tcm.getColumn(EDIT_COLUMN).setCellRenderer(buttonRenderer); 292 tcm.getColumn(EDIT_COLUMN).setCellEditor(buttonEditor); 293 294 // set column preferred widths 295 // load defaults, xml file data not found 296 for (int i = 0; i < tcm.getColumnCount(); i++) { 297 tcm.getColumn(i).setPreferredWidth(_enginesTableColumnWidths[i]); 298 } 299 _frame.loadTableDetails(_table); 300 301 // turn off columns 302 tcm.setColumnVisible(tcm.getColumnByModelIndex(BUILT_COLUMN), false); 303 tcm.setColumnVisible(tcm.getColumnByModelIndex(OWNER_COLUMN), false); 304 tcm.setColumnVisible(tcm.getColumnByModelIndex(VALUE_COLUMN), false); 305 tcm.setColumnVisible(tcm.getColumnByModelIndex(RFID_COLUMN), false); 306 tcm.setColumnVisible(tcm.getColumnByModelIndex(RFID_WHEN_LAST_SEEN_COLUMN), false); 307 tcm.setColumnVisible(tcm.getColumnByModelIndex(RFID_WHERE_LAST_SEEN_COLUMN), false); 308 tcm.setColumnVisible(tcm.getColumnByModelIndex(PREVIOUS_LOCATION_COLUMN), false); 309 tcm.setColumnVisible(tcm.getColumnByModelIndex(LAST_COLUMN), false); 310 tcm.setColumnVisible(tcm.getColumnByModelIndex(LAST_TRAIN_COLUMN), false); 311 tcm.setColumnVisible(tcm.getColumnByModelIndex(DCC_ADDRESS_COLUMN), false); 312 tcm.setColumnVisible(tcm.getColumnByModelIndex(PICKUP_COLUMN), false); 313 tcm.setColumnVisible(tcm.getColumnByModelIndex(SETOUT_COLUMN), false); 314 tcm.setColumnVisible(tcm.getColumnByModelIndex(COMMENT_COLUMN), false); 315 316 // turn on default 317 tcm.setColumnVisible(tcm.getColumnByModelIndex(MOVES_COLUMN), true); 318 } 319 320 @Override 321 public int getRowCount() { 322 return engineList.size(); 323 } 324 325 @Override 326 public int getColumnCount() { 327 return HIGHEST_COLUMN; 328 } 329 330 @Override 331 public String getColumnName(int col) { 332 switch (col) { 333 case SELECT_COLUMN: 334 return Bundle.getMessage("ButtonSelect"); 335 case NUM_COLUMN: 336 return Bundle.getMessage("Number"); 337 case ROAD_COLUMN: 338 return Bundle.getMessage("Road"); 339 case MODEL_COLUMN: 340 return Bundle.getMessage("Model"); 341 case HP_COLUMN: 342 return Bundle.getMessage("HP"); 343 case TYPE_COLUMN: 344 return Bundle.getMessage("Type"); 345 case LENGTH_COLUMN: 346 return Bundle.getMessage("Len"); 347 case WEIGHT_COLUMN: 348 return Bundle.getMessage("Weight"); 349 case CONSIST_COLUMN: 350 return Bundle.getMessage("Consist"); 351 case LOCATION_COLUMN: 352 return Bundle.getMessage("Location"); 353 case RFID_WHERE_LAST_SEEN_COLUMN: 354 return Bundle.getMessage("WhereLastSeen"); 355 case RFID_WHEN_LAST_SEEN_COLUMN: 356 return Bundle.getMessage("WhenLastSeen"); 357 case DESTINATION_COLUMN: 358 return Bundle.getMessage("Destination"); 359 case PREVIOUS_LOCATION_COLUMN: 360 return Bundle.getMessage("LastLocation"); 361 case TRAIN_COLUMN: 362 return Bundle.getMessage("Train"); 363 case LAST_TRAIN_COLUMN: 364 return Bundle.getMessage("LastTrain"); 365 case MOVES_COLUMN: 366 return Bundle.getMessage("Moves"); 367 case BUILT_COLUMN: 368 return Bundle.getMessage("Built"); 369 case OWNER_COLUMN: 370 return Bundle.getMessage("Owner"); 371 case VALUE_COLUMN: 372 return Setup.getValueLabel(); 373 case RFID_COLUMN: 374 return Setup.getRfidLabel(); 375 case LAST_COLUMN: 376 return Bundle.getMessage("LastMoved"); 377 case DCC_ADDRESS_COLUMN: 378 return Bundle.getMessage("DccAddress"); 379 case PICKUP_COLUMN: 380 return Bundle.getMessage("Pickup"); 381 case SETOUT_COLUMN: 382 return Bundle.getMessage("SetOut"); 383 case COMMENT_COLUMN: 384 return Bundle.getMessage("Comment"); 385 case SET_COLUMN: 386 return Bundle.getMessage("Set"); 387 case EDIT_COLUMN: 388 return Bundle.getMessage("ButtonEdit"); // titles above all columns 389 default: 390 return "unknown"; // NOI18N 391 } 392 } 393 394 @Override 395 public Class<?> getColumnClass(int col) { 396 switch (col) { 397 case SELECT_COLUMN: 398 return Boolean.class; 399 case SET_COLUMN: 400 case EDIT_COLUMN: 401 return JButton.class; 402 case LENGTH_COLUMN: 403 case MOVES_COLUMN: 404 return Integer.class; 405 default: 406 return String.class; 407 } 408 } 409 410 @Override 411 public boolean isCellEditable(int row, int col) { 412 Engine engine = engineList.get(row); 413 if (engine.isClone()) { 414 return false; 415 } 416 switch (col) { 417 case SELECT_COLUMN: 418 case SET_COLUMN: 419 case EDIT_COLUMN: 420 case MOVES_COLUMN: 421 case VALUE_COLUMN: 422 case RFID_COLUMN: 423 return true; 424 default: 425 return false; 426 } 427 } 428 429 @Override 430 public Object getValueAt(int row, int col) { 431 if (row >= getRowCount()) { 432 return "ERROR row " + row; // NOI18N 433 } 434 Engine engine = engineList.get(row); 435 if (engine == null) { 436 return "ERROR engine unknown " + row; // NOI18N 437 } 438 switch (col) { 439 case SELECT_COLUMN: 440 return engine.isSelected(); 441 case NUM_COLUMN: 442 return engine.getNumber(); 443 case ROAD_COLUMN: 444 return engine.getRoadName(); 445 case LENGTH_COLUMN: 446 return engine.getLengthInteger(); 447 case MODEL_COLUMN: 448 return engine.getModel(); 449 case HP_COLUMN: 450 return engine.getHp(); 451 case TYPE_COLUMN: { 452 if (engine.isBunit()) { 453 return engine.getTypeName() + " " + Bundle.getMessage("(B)"); 454 } 455 return engine.getTypeName(); 456 } 457 case WEIGHT_COLUMN: 458 return engine.getWeightTons(); 459 case CONSIST_COLUMN: { 460 if (engine.isLead()) { 461 return engine.getConsistName() + "*"; 462 } 463 return engine.getConsistName(); 464 } 465 case LOCATION_COLUMN: { 466 String s = engine.getStatus(); 467 if (!engine.getLocationName().equals(Engine.NONE)) { 468 s = engine.getStatus() + engine.getLocationName() + " (" + engine.getTrackName() + ")"; 469 } 470 return s; 471 } 472 case RFID_WHERE_LAST_SEEN_COLUMN: { 473 return engine.getWhereLastSeenName() + 474 (engine.getTrackLastSeenName().equals(Engine.NONE) ? "" : " (" + engine.getTrackLastSeenName() + ")"); 475 } 476 case RFID_WHEN_LAST_SEEN_COLUMN: { 477 return engine.getWhenLastSeenDate(); 478 } 479 case DESTINATION_COLUMN: { 480 String s = ""; 481 if (!engine.getDestinationName().equals(Engine.NONE)) { 482 s = engine.getDestinationName() + " (" + engine.getDestinationTrackName() + ")"; 483 } 484 return s; 485 } 486 case PREVIOUS_LOCATION_COLUMN: { 487 String s = ""; 488 if (!engine.getLastLocationName().equals(Engine.NONE)) { 489 s = engine.getLastLocationName() + " (" + engine.getLastTrackName() + ")"; 490 } 491 return s; 492 } 493 case TRAIN_COLUMN: { 494 // if train was manually set by user add an asterisk 495 if (engine.getTrain() != null && engine.getRouteLocation() == null) { 496 return engine.getTrainName() + "*"; 497 } 498 return engine.getTrainName(); 499 } 500 case LAST_TRAIN_COLUMN: 501 return engine.getLastTrainName(); 502 case MOVES_COLUMN: 503 return engine.getMoves(); 504 case BUILT_COLUMN: 505 return engine.getBuilt(); 506 case OWNER_COLUMN: 507 return engine.getOwnerName(); 508 case VALUE_COLUMN: 509 return engine.getValue(); 510 case RFID_COLUMN: 511 return engine.getRfid(); 512 case LAST_COLUMN: 513 return engine.getSortDate(); 514 case DCC_ADDRESS_COLUMN: 515 return engine.getDccAddress(); 516 case PICKUP_COLUMN: 517 return engine.getPickupTime(); 518 case SETOUT_COLUMN: 519 return engine.getSetoutTime(); 520 case COMMENT_COLUMN: 521 return engine.getComment(); 522 case SET_COLUMN: 523 return Bundle.getMessage("Set"); 524 case EDIT_COLUMN: 525 return Bundle.getMessage("ButtonEdit"); 526 default: 527 return "unknown " + col; // NOI18N 528 } 529 } 530 531 EngineEditFrame engineEditFrame = null; 532 EngineSetFrame engineSetFrame = null; 533 534 @Override 535 public void setValueAt(Object value, int row, int col) { 536 Engine engine = engineList.get(row); 537 switch (col) { 538 case SELECT_COLUMN: 539 engine.setSelected(((Boolean) value).booleanValue()); 540 break; 541 case MOVES_COLUMN: 542 try { 543 engine.setMoves(Integer.parseInt(value.toString())); 544 } catch (NumberFormatException e) { 545 log.error("move count must be a number"); 546 } 547 break; 548 case BUILT_COLUMN: 549 engine.setBuilt(value.toString()); 550 break; 551 case OWNER_COLUMN: 552 engine.setOwnerName(value.toString()); 553 break; 554 case VALUE_COLUMN: 555 engine.setValue(value.toString()); 556 break; 557 case RFID_COLUMN: 558 engine.setRfid(value.toString()); 559 break; 560 case SET_COLUMN: 561 log.debug("Set engine location"); 562 if (engineSetFrame != null) { 563 engineSetFrame.dispose(); 564 } 565 // use invokeLater so new window appears on top 566 SwingUtilities.invokeLater(() -> { 567 engineSetFrame = new EngineSetFrame(); 568 engineSetFrame.initComponents(); 569 engineSetFrame.load(engine); 570 }); 571 break; 572 case EDIT_COLUMN: 573 log.debug("Edit engine"); 574 if (engineEditFrame != null) { 575 engineEditFrame.dispose(); 576 } 577 // use invokeLater so new window appears on top 578 SwingUtilities.invokeLater(() -> { 579 engineEditFrame = new EngineEditFrame(); 580 engineEditFrame.initComponents(); 581 engineEditFrame.load(engine); 582 }); 583 break; 584 default: 585 break; 586 } 587 } 588 589 public void dispose() { 590 log.debug("dispose EngineTableModel"); 591 engineManager.removePropertyChangeListener(this); 592 removePropertyChangeEngines(); 593 if (engineSetFrame != null) { 594 engineSetFrame.dispose(); 595 } 596 if (engineEditFrame != null) { 597 engineEditFrame.dispose(); 598 } 599 } 600 601 private void addPropertyChangeEngines() { 602 for (RollingStock rs : engineManager.getList()) { 603 rs.addPropertyChangeListener(this); 604 } 605 } 606 607 private void removePropertyChangeEngines() { 608 for (RollingStock rs : engineManager.getList()) { 609 rs.removePropertyChangeListener(this); 610 } 611 } 612 613 @Override 614 public void propertyChange(PropertyChangeEvent e) { 615 if (Control.SHOW_PROPERTY) { 616 log.debug("Property change: ({}) old: ({}) new: ({})", e.getPropertyName(), e.getOldValue(), e 617 .getNewValue()); 618 } 619 if (e.getPropertyName().equals(EngineManager.LISTLENGTH_CHANGED_PROPERTY) || 620 e.getPropertyName().equals(ConsistManager.LISTLENGTH_CHANGED_PROPERTY)) { 621 updateList(); 622 fireTableDataChanged(); 623 } 624 // Engine length, type, and HP are based on model, so multiple changes 625 else if (e.getPropertyName().equals(Engine.LENGTH_CHANGED_PROPERTY) || 626 e.getPropertyName().equals(Engine.TYPE_CHANGED_PROPERTY) || 627 e.getPropertyName().equals(Engine.HP_CHANGED_PROPERTY)) { 628 fireTableDataChanged(); 629 } 630 // must be a engine change 631 else if (e.getSource().getClass().equals(Engine.class)) { 632 Engine engine = (Engine) e.getSource(); 633 int row = engineList.indexOf(engine); 634 if (Control.SHOW_PROPERTY) { 635 log.debug("Update engine table row: {}", row); 636 } 637 if (row >= 0) { 638 fireTableRowsUpdated(row, row); 639 // next is needed when only showing engines at a location or track 640 } else if (e.getPropertyName().equals(Engine.TRACK_CHANGED_PROPERTY)) { 641 updateList(); 642 fireTableDataChanged(); 643 } 644 } 645 } 646 647 private final static Logger log = LoggerFactory.getLogger(EnginesTableModel.class); 648}