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