001package jmri.jmrit.operations.locations; 002 003import java.beans.PropertyChangeEvent; 004import java.beans.PropertyChangeListener; 005import java.util.*; 006 007import javax.swing.*; 008import javax.swing.event.*; 009import javax.swing.table.TableColumn; 010 011import org.slf4j.Logger; 012import org.slf4j.LoggerFactory; 013 014import jmri.InstanceManager; 015import jmri.jmrit.operations.OperationsPanel; 016import jmri.jmrit.operations.OperationsTableModel; 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 tracks used by operations 025 * 026 * @author Daniel Boudreau Copyright (C) 2008, 2011, 2012 027 */ 028public abstract class TrackTableModel extends OperationsTableModel implements PropertyChangeListener, TableColumnModelListener { 029 030 protected Location _location; 031 protected List<Track> _tracksList = new ArrayList<>(); 032 protected String _trackType; 033 protected JTable _table; 034 protected boolean _dirty = false; 035 036 // Defines the columns 037 protected static final int ID_COLUMN = 0; 038 protected static final int NAME_COLUMN = 1; 039 protected static final int LENGTH_COLUMN = 2; 040 protected static final int USED_LENGTH_COLUMN = 3; 041 protected static final int RESERVED_COLUMN = 4; 042 protected static final int MOVES_COLUMN = 5; 043 protected static final int CARS_COLUMN = 6; 044 protected static final int LOCOS_COLUMN = 7; 045 protected static final int PICKUPS_COLUMN = 8; 046 protected static final int SETOUT_COLUMN = 9; 047 protected static final int SCHEDULE_COLUMN = 10; 048 protected static final int ROAD_COLUMN = 11; 049 protected static final int LOAD_COLUMN = 12; 050 protected static final int DEFAULT_LOAD_COLUMN = 13; 051 protected static final int CUSTOM_LOAD_COLUMN = 14; 052 protected static final int DISABLE_LOAD_CHANGE_COLUMN = 15; 053 protected static final int SHIP_COLUMN = 16; 054 protected static final int RESTRICTION_COLUMN = 17; 055 protected static final int DESTINATION_COLUMN = 18; 056 protected static final int ROUTED_COLUMN = 19; 057 protected static final int HOLD_COLUMN = 20; 058 protected static final int POOL_COLUMN = 21; 059 protected static final int PLANPICKUP_COLUMN = 22; 060 protected static final int ALT_TRACK_COLUMN = 23; 061 protected static final int ORDER_COLUMN = 24; 062 protected static final int TRAIN_DIRECTION_COLUMN = 25; 063 protected static final int REPORTER_COLUMN = 26; 064 protected static final int EDIT_COLUMN = 27; 065 066 protected static final int HIGHESTCOLUMN = EDIT_COLUMN + 1; 067 068 public TrackTableModel() { 069 super(); 070 } 071 072 protected void initTable(JTable table, Location location, String trackType) { 073 _table = table; 074 _location = location; 075 _trackType = trackType; 076 if (_location != null) { 077 _location.addPropertyChangeListener(this); 078 } 079 Setup.getDefault().addPropertyChangeListener(this); 080 updateList(); 081 initTable(); 082 } 083 084 private void updateList() { 085 if (_location == null) { 086 return; 087 } 088 // first, remove listeners from the individual objects 089 removePropertyChangeTracks(); 090 091 _tracksList = _location.getTracksByNameList(_trackType); 092 // and add them back in 093 for (Track track : _tracksList) { 094 track.addPropertyChangeListener(this); 095 } 096 } 097 098 private void initTable() { 099 // Use XTableColumnModel so we can control which columns are visible 100 XTableColumnModel tcm = new XTableColumnModel(); 101 _table.setColumnModel(tcm); 102 _table.createDefaultColumnsFromModel(); 103 104 // set column preferred widths 105 tcm.getColumn(ID_COLUMN).setPreferredWidth(40); 106 tcm.getColumn(NAME_COLUMN).setPreferredWidth(200); 107 tcm.getColumn(LENGTH_COLUMN).setPreferredWidth( 108 Math.max(50, new JLabel(getColumnName(LENGTH_COLUMN)).getPreferredSize().width + 10)); 109 tcm.getColumn(USED_LENGTH_COLUMN).setPreferredWidth(50); 110 tcm.getColumn(RESERVED_COLUMN).setPreferredWidth( 111 Math.max(65, new JLabel(getColumnName(RESERVED_COLUMN)).getPreferredSize().width + 10)); 112 tcm.getColumn(MOVES_COLUMN).setPreferredWidth(60); 113 tcm.getColumn(LOCOS_COLUMN).setPreferredWidth(60); 114 tcm.getColumn(CARS_COLUMN).setPreferredWidth(60); 115 tcm.getColumn(PICKUPS_COLUMN).setPreferredWidth( 116 Math.max(60, new JLabel(getColumnName(PICKUPS_COLUMN)).getPreferredSize().width + 10)); 117 tcm.getColumn(SETOUT_COLUMN).setPreferredWidth( 118 Math.max(60, new JLabel(getColumnName(SETOUT_COLUMN)).getPreferredSize().width + 10)); 119 tcm.getColumn(SCHEDULE_COLUMN).setPreferredWidth( 120 Math.max(90, new JLabel(getColumnName(SCHEDULE_COLUMN)).getPreferredSize().width + 10)); 121 tcm.getColumn(RESTRICTION_COLUMN).setPreferredWidth(90); 122 tcm.getColumn(LOAD_COLUMN).setPreferredWidth(50); 123 tcm.getColumn(DEFAULT_LOAD_COLUMN).setPreferredWidth(60); 124 tcm.getColumn(CUSTOM_LOAD_COLUMN).setPreferredWidth(90); 125 tcm.getColumn(DISABLE_LOAD_CHANGE_COLUMN).setPreferredWidth(50); 126 tcm.getColumn(SHIP_COLUMN).setPreferredWidth(50); 127 tcm.getColumn(ROAD_COLUMN).setPreferredWidth(50); 128 tcm.getColumn(DESTINATION_COLUMN).setPreferredWidth(50); 129 tcm.getColumn(ROUTED_COLUMN).setPreferredWidth(50); 130 tcm.getColumn(HOLD_COLUMN).setPreferredWidth(50); 131 tcm.getColumn(POOL_COLUMN).setPreferredWidth(70); 132 tcm.getColumn(PLANPICKUP_COLUMN).setPreferredWidth(70); 133 tcm.getColumn(ALT_TRACK_COLUMN).setPreferredWidth(120); 134 tcm.getColumn(ORDER_COLUMN) 135 .setPreferredWidth(Math.max(50, new JLabel(getColumnName(ORDER_COLUMN)).getPreferredSize().width + 10)); 136 tcm.getColumn(TRAIN_DIRECTION_COLUMN).setPreferredWidth(30); 137 tcm.getColumn(REPORTER_COLUMN).setPreferredWidth(70); 138 tcm.getColumn(EDIT_COLUMN).setPreferredWidth(80); 139 140 tcm.getColumn(EDIT_COLUMN).setCellRenderer(new ButtonRenderer()); 141 tcm.getColumn(EDIT_COLUMN).setCellEditor(new ButtonEditor(new JButton())); 142 143 OperationsPanel.loadTableDetails(_table, "Location"); 144 setColumnsVisible(); 145 addTableColumnListeners(); 146 } 147 148 // only show columns if they are needed 149 private void setColumnsVisible() { 150 XTableColumnModel tcm = (XTableColumnModel) _table.getColumnModel(); 151 tcm.setColumnVisible(tcm.getColumnByModelIndex(ID_COLUMN), 152 InstanceManager.getDefault(LocationManager.class).isShowIdEnabled()); 153 tcm.setColumnVisible(tcm.getColumnByModelIndex(SCHEDULE_COLUMN), 154 _location.hasSchedules() && _trackType.equals(Track.SPUR)); 155 tcm.setColumnVisible(tcm.getColumnByModelIndex(RESTRICTION_COLUMN), 156 _location.hasServiceRestrictions() && !_trackType.equals(Track.YARD)); 157 tcm.setColumnVisible(tcm.getColumnByModelIndex(LOAD_COLUMN), _location.hasLoadRestrictions()); 158 tcm.setColumnVisible(tcm.getColumnByModelIndex(DEFAULT_LOAD_COLUMN), _trackType.equals(Track.STAGING)); 159 tcm.setColumnVisible(tcm.getColumnByModelIndex(CUSTOM_LOAD_COLUMN), _trackType.equals(Track.STAGING)); 160 tcm.setColumnVisible(tcm.getColumnByModelIndex(DISABLE_LOAD_CHANGE_COLUMN), 161 _location.hasDisableLoadChange() && _trackType.equals(Track.SPUR)); 162 tcm.setColumnVisible(tcm.getColumnByModelIndex(SHIP_COLUMN), _location.hasShipLoadRestrictions()); 163 tcm.setColumnVisible(tcm.getColumnByModelIndex(ROAD_COLUMN), _location.hasRoadRestrictions()); 164 tcm.setColumnVisible(tcm.getColumnByModelIndex(DESTINATION_COLUMN), _location.hasDestinationRestrictions() && 165 (_trackType.equals(Track.INTERCHANGE) || _trackType.equals(Track.STAGING))); 166 tcm.setColumnVisible(tcm.getColumnByModelIndex(ROUTED_COLUMN), _trackType.equals(Track.INTERCHANGE) || 167 _trackType.equals(Track.STAGING)); 168 tcm.setColumnVisible(tcm.getColumnByModelIndex(HOLD_COLUMN), 169 _location.hasSchedules() && _trackType.equals(Track.SPUR)); 170 tcm.setColumnVisible(tcm.getColumnByModelIndex(PLANPICKUP_COLUMN), _location.hasPlannedPickups()); 171 tcm.setColumnVisible(tcm.getColumnByModelIndex(POOL_COLUMN), _location.hasPools()); 172 tcm.setColumnVisible(tcm.getColumnByModelIndex(ALT_TRACK_COLUMN), _location.hasAlternateTracks()); 173 tcm.setColumnVisible(tcm.getColumnByModelIndex(ORDER_COLUMN), 174 _location.hasOrderRestrictions() && !_trackType.equals(Track.SPUR)); 175 tcm.setColumnVisible(tcm.getColumnByModelIndex(TRAIN_DIRECTION_COLUMN), 176 _location.hasTracksWithRestrictedTrainDirections()); 177 tcm.setColumnVisible(tcm.getColumnByModelIndex(REPORTER_COLUMN), 178 Setup.isRfidEnabled() && _location.hasReporters()); 179 tcm.setColumnVisible(tcm.getColumnByModelIndex(MOVES_COLUMN), Setup.isShowTrackMovesEnabled()); 180 } 181 182 /* 183 * Persisting using JmriJTablePersistenceManager doesn't quite work since 184 * the same table name is used for each track type; spur, yard, interchange, 185 * and staging. Plus multiple edit locations can be open at the same time, 186 * again using the same table name. The goal is to have a single change 187 * affect every table for all edit locations. Therefore any changes to 188 * column width or position is saved when the edit location window is 189 * closed. 190 */ 191 private void addTableColumnListeners() { 192 Enumeration<TableColumn> e = _table.getColumnModel().getColumns(); 193 while (e.hasMoreElements()) { 194 TableColumn column = e.nextElement(); 195 column.addPropertyChangeListener(this); 196 } 197 _table.getColumnModel().addColumnModelListener(this); 198 } 199 200 /** 201 * Table is dirty when a column is moved or width is changed. 202 * 203 * @param dirty set true if dirty 204 */ 205 private void setDirty(boolean dirty) { 206 _dirty = dirty; 207 } 208 209 private boolean isDirty() { 210 return _dirty; 211 } 212 213 @Override 214 public int getRowCount() { 215 return _tracksList.size(); 216 } 217 218 @Override 219 public int getColumnCount() { 220 return HIGHESTCOLUMN; 221 } 222 223 @Override 224 public String getColumnName(int col) { 225 switch (col) { 226 case ID_COLUMN: 227 return Bundle.getMessage("Id"); 228 case NAME_COLUMN: 229 return Bundle.getMessage("TrackName"); 230 case LENGTH_COLUMN: 231 return Bundle.getMessage("Length"); 232 case USED_LENGTH_COLUMN: 233 return Bundle.getMessage("Used"); 234 case RESERVED_COLUMN: 235 return Bundle.getMessage("Reserved"); 236 case MOVES_COLUMN: 237 return Bundle.getMessage("Moves"); 238 case LOCOS_COLUMN: 239 return Bundle.getMessage("Engines"); 240 case CARS_COLUMN: 241 return Bundle.getMessage("Cars"); 242 case PICKUPS_COLUMN: 243 return Bundle.getMessage("Pickups"); 244 case SETOUT_COLUMN: 245 return Bundle.getMessage("Drop"); 246 case SCHEDULE_COLUMN: 247 return Bundle.getMessage("Schedule"); 248 case RESTRICTION_COLUMN: 249 return Bundle.getMessage("Restrictions"); 250 case LOAD_COLUMN: 251 return Bundle.getMessage("Load"); 252 case DEFAULT_LOAD_COLUMN: 253 return Bundle.getMessage("LoadDefaultAbv"); 254 case CUSTOM_LOAD_COLUMN: 255 return Bundle.getMessage("LoadCustomAbv"); 256 case DISABLE_LOAD_CHANGE_COLUMN: 257 return Bundle.getMessage("DisableLoadChange"); 258 case SHIP_COLUMN: 259 return Bundle.getMessage("Ship"); 260 case ROAD_COLUMN: 261 return Bundle.getMessage("Road"); 262 case DESTINATION_COLUMN: 263 return Bundle.getMessage("Dest"); 264 case ROUTED_COLUMN: 265 return Bundle.getMessage("Routed"); 266 case HOLD_COLUMN: 267 return Bundle.getMessage("Hold"); 268 case POOL_COLUMN: 269 return Bundle.getMessage("Pool"); 270 case PLANPICKUP_COLUMN: 271 return Bundle.getMessage("PlanPickUp"); 272 case ALT_TRACK_COLUMN: 273 return Bundle.getMessage("AlternateTrack"); 274 case ORDER_COLUMN: 275 return Bundle.getMessage("ServiceOrder"); 276 case TRAIN_DIRECTION_COLUMN: 277 return Bundle.getMessage("AbbrevationDirection"); 278 case REPORTER_COLUMN: 279 return Bundle.getMessage("Reporters"); 280 case EDIT_COLUMN: 281 return Bundle.getMessage("ButtonEdit"); // titles above all 282 // columns 283 default: 284 return "unknown"; // NOI18N 285 } 286 } 287 288 @Override 289 public Class<?> getColumnClass(int col) { 290 switch (col) { 291 case ID_COLUMN: 292 case NAME_COLUMN: 293 case SCHEDULE_COLUMN: 294 case RESTRICTION_COLUMN: 295 case LOAD_COLUMN: 296 case DEFAULT_LOAD_COLUMN: 297 case CUSTOM_LOAD_COLUMN: 298 case SHIP_COLUMN: 299 case ROAD_COLUMN: 300 case DESTINATION_COLUMN: 301 case POOL_COLUMN: 302 case PLANPICKUP_COLUMN: 303 case ALT_TRACK_COLUMN: 304 case ORDER_COLUMN: 305 case TRAIN_DIRECTION_COLUMN: 306 case REPORTER_COLUMN: 307 return String.class; 308 case LENGTH_COLUMN: 309 case USED_LENGTH_COLUMN: 310 case RESERVED_COLUMN: 311 case MOVES_COLUMN: 312 case LOCOS_COLUMN: 313 case CARS_COLUMN: 314 case PICKUPS_COLUMN: 315 case SETOUT_COLUMN: 316 return Integer.class; 317 case EDIT_COLUMN: 318 return JButton.class; 319 case DISABLE_LOAD_CHANGE_COLUMN: 320 case ROUTED_COLUMN: 321 case HOLD_COLUMN: 322 return Boolean.class; 323 default: 324 return null; 325 } 326 } 327 328 @Override 329 public boolean isCellEditable(int row, int col) { 330 switch (col) { 331 case ROUTED_COLUMN: 332 case DISABLE_LOAD_CHANGE_COLUMN: 333 case HOLD_COLUMN: 334 case EDIT_COLUMN: 335 case MOVES_COLUMN: 336 return true; 337 default: 338 return false; 339 } 340 } 341 342 @Override 343 public Object getValueAt(int row, int col) { 344 if (row >= getRowCount()) { 345 return "ERROR row " + row; // NOI18N 346 } 347 Track track = _tracksList.get(row); 348 if (track == null) { 349 return "ERROR track unknown " + row; // NOI18N 350 } 351 switch (col) { 352 case ID_COLUMN: 353 return track.getId(); 354 case NAME_COLUMN: 355 return track.getName(); 356 case LENGTH_COLUMN: 357 return track.getLength(); 358 case USED_LENGTH_COLUMN: 359 return track.getUsedLength(); 360 case RESERVED_COLUMN: 361 return track.getReserved(); 362 case MOVES_COLUMN: 363 return track.getMoves(); 364 case LOCOS_COLUMN: 365 return track.getNumberEngines(); 366 case CARS_COLUMN: 367 return track.getNumberCars(); 368 case PICKUPS_COLUMN: 369 return track.getPickupRS(); 370 case SETOUT_COLUMN: 371 return track.getDropRS(); 372 case SCHEDULE_COLUMN: 373 return track.getScheduleName(); 374 case RESTRICTION_COLUMN: 375 return getRestrictions(track); 376 case LOAD_COLUMN: 377 return getModifiedString(track.getLoadNames().length, track.getLoadOption().equals(Track.ALL_LOADS), 378 track.getLoadOption().equals(Track.INCLUDE_LOADS)); 379 case DEFAULT_LOAD_COLUMN: 380 return getDefaultLoadString(track); 381 case CUSTOM_LOAD_COLUMN: 382 return getCustomLoadString(track); 383 case DISABLE_LOAD_CHANGE_COLUMN: 384 return track.isDisableLoadChangeEnabled(); 385 case SHIP_COLUMN: 386 return getModifiedString(track.getShipLoadNames().length, 387 track.getShipLoadOption().equals(Track.ALL_LOADS), 388 track.getShipLoadOption().equals(Track.INCLUDE_LOADS)); 389 case ROAD_COLUMN: 390 return getModifiedString(track.getRoadNames().length, track.getRoadOption().equals(Track.ALL_ROADS), 391 track.getRoadOption().equals(Track.INCLUDE_ROADS)); 392 case DESTINATION_COLUMN: { 393 return getDestinationString(track); 394 } 395 case ROUTED_COLUMN: 396 return track.isOnlyCarsWithFinalDestinationEnabled(); 397 case HOLD_COLUMN: 398 return track.isHoldCarsWithCustomLoadsEnabled(); 399 case POOL_COLUMN: 400 return track.getPoolName(); 401 case PLANPICKUP_COLUMN: 402 if (track.getIgnoreUsedLengthPercentage() > Track.IGNORE_0) { 403 return track.getIgnoreUsedLengthPercentage() + "%"; 404 } 405 return ""; 406 case ALT_TRACK_COLUMN: 407 if (track.getAlternateTrack() != null) { 408 return track.getAlternateTrack().getName(); 409 } 410 if (track.isAlternate()) { 411 return Bundle.getMessage("ButtonYes"); 412 } 413 return ""; 414 case ORDER_COLUMN: 415 return track.getServiceOrder(); 416 case TRAIN_DIRECTION_COLUMN: 417 int trainDirections = track.getLocation().getTrainDirections() & Setup.getTrainDirection(); 418 if (trainDirections != (track.getTrainDirections() & trainDirections)) { 419 return "X"; 420 } 421 return ""; 422 case REPORTER_COLUMN: 423 return track.getReporterName(); 424 case EDIT_COLUMN: 425 return Bundle.getMessage("ButtonEdit"); 426 default: 427 return "unknown " + col; // NOI18N 428 } 429 } 430 431 private String getRestrictions(Track track) { 432 StringBuffer restrictions = new StringBuffer(); 433 if (!track.getDropOption().equals(Track.ANY)) { 434 String suffix = " "; 435 if (track.getDropOption().equals(Track.EXCLUDE_ROUTES) || 436 track.getDropOption().equals(Track.EXCLUDE_TRAINS)) { 437 suffix = "x"; 438 } 439 restrictions.append(Bundle.getMessage("AbbreviationSetOut") + suffix + track.getDropIds().length); 440 } 441 if (!track.getPickupOption().equals(Track.ANY)) { 442 String suffix = " "; 443 if (track.getPickupOption().equals(Track.EXCLUDE_ROUTES) || 444 track.getPickupOption().equals(Track.EXCLUDE_TRAINS)) { 445 suffix = "x"; 446 } 447 restrictions.append(" " + Bundle.getMessage("AbbreviationPickUp") + suffix + track.getPickupIds().length); 448 } 449 return restrictions.toString(); 450 } 451 452 private String getModifiedString(int number, boolean all, boolean accept) { 453 if (all) { 454 return ""; 455 } 456 if (accept) { 457 return "A " + Integer.toString(number); // NOI18N 458 } 459 return "E " + Integer.toString(number); // NOI18N 460 } 461 462 private String getDefaultLoadString(Track track) { 463 String defaultLoad = ""; 464 if (track.isLoadSwapEnabled()) { 465 defaultLoad = Bundle.getMessage("ABV_SwapDefaultLoads"); 466 } 467 if (track.isLoadEmptyEnabled()) { 468 defaultLoad = Bundle.getMessage("ABV_EmptyDefaultLoads"); 469 } 470 return defaultLoad; 471 } 472 473 private String getCustomLoadString(Track track) { 474 StringBuffer customLoad = new StringBuffer(); 475 if (track.isRemoveCustomLoadsEnabled()) { 476 customLoad.append(Bundle.getMessage("ABV_EmptyCustomLoads") + " "); 477 } 478 if (track.isAddCustomLoadsEnabled()) { 479 customLoad.append(Bundle.getMessage("ABV_GenerateCustomLoad") + " "); 480 } 481 if (track.isAddCustomLoadsAnySpurEnabled()) { 482 customLoad.append(Bundle.getMessage("ABV_GenerateCustomLoadAnySpur") + " "); 483 } 484 if (track.isAddCustomLoadsAnyStagingTrackEnabled()) { 485 customLoad.append(Bundle.getMessage("ABV_GereateCustomLoadStaging")); 486 } 487 if (track.isBlockCarsEnabled()) { 488 customLoad.append(Bundle.getMessage("ABV_CarBlocking")); 489 } 490 return customLoad.toString(); 491 } 492 493 private String getDestinationString(Track track) { 494 int size = track.getDestinationListSize(); 495 if (track.getDestinationOption().equals(Track.EXCLUDE_DESTINATIONS)) { 496 size = InstanceManager.getDefault(LocationManager.class).getNumberOfLocations() - size; 497 } else if (size == 1 && track.getDestinationOption().equals(Track.INCLUDE_DESTINATIONS)) { 498 // if there's only one destination return the destination name 499 Location loc = 500 InstanceManager.getDefault(LocationManager.class).getLocationById(track.getDestinationIds()[0]); 501 if (loc != null) { 502 return loc.getName(); 503 } 504 } 505 return getModifiedString(size, track.getDestinationOption().equals(Track.ALL_DESTINATIONS), 506 track.getDestinationOption().equals(Track.INCLUDE_DESTINATIONS)); 507 } 508 509 @Override 510 public void setValueAt(Object value, int row, int col) { 511 switch (col) { 512 case DISABLE_LOAD_CHANGE_COLUMN: 513 setDisableLoadChange(row, value); 514 break; 515 case ROUTED_COLUMN: 516 setRouted(row, value); 517 break; 518 case HOLD_COLUMN: 519 setHold(row, value); 520 break; 521 case EDIT_COLUMN: 522 editTrack(row); 523 break; 524 case MOVES_COLUMN: 525 setMoves(row, value); 526 break; 527 default: 528 break; 529 } 530 } 531 532 TrackEditFrame tef = null; 533 534 abstract protected void editTrack(int row); 535 536 private void setDisableLoadChange(int row, Object value) { 537 Track track = _tracksList.get(row); 538 track.setDisableLoadChangeEnabled(((Boolean) value).booleanValue()); 539 } 540 541 private void setRouted(int row, Object value) { 542 Track track = _tracksList.get(row); 543 track.setOnlyCarsWithFinalDestinationEnabled(((Boolean) value).booleanValue()); 544 } 545 546 private void setHold(int row, Object value) { 547 Track track = _tracksList.get(row); 548 track.setHoldCarsWithCustomLoadsEnabled(((Boolean) value).booleanValue()); 549 } 550 551 private void setMoves(int row, Object value) { 552 Track track = _tracksList.get(row); 553 track.setMoves((int) value); 554 } 555 556 private void removePropertyChangeTracks() { 557 for (Track track : _tracksList) { 558 track.removePropertyChangeListener(this); 559 } 560 } 561 562 public void dispose() { 563 if (_table != null) { 564 _table.getRowSorter().setSortKeys(null); 565 if (isDirty()) { 566 OperationsPanel.cacheState(_table); 567 OperationsPanel.saveTableState(); 568 setDirty(false); 569 } 570 } 571 removePropertyChangeTracks(); 572 if (_location != null) { 573 _location.removePropertyChangeListener(this); 574 } 575 if (tef != null) { 576 tef.dispose(); 577 } 578 Setup.getDefault().removePropertyChangeListener(this); 579 _tracksList.clear(); 580 fireTableDataChanged(); 581 } 582 583 // this table listens for changes to a location and it's tracks 584 @Override 585 public void propertyChange(PropertyChangeEvent e) { 586 if (Control.SHOW_PROPERTY) { 587 log.debug("Property change: ({}) old: ({}) new: ({})", e.getPropertyName(), e.getOldValue(), 588 e.getNewValue()); 589 } 590 if (e.getPropertyName().equals(Location.TRACK_LISTLENGTH_CHANGED_PROPERTY) || 591 e.getPropertyName().equals(Location.TRAIN_DIRECTION_CHANGED_PROPERTY)) { 592 updateList(); 593 fireTableDataChanged(); 594 } 595 if (e.getPropertyName().equals(Setup.SHOW_TRACK_MOVES_PROPERTY_CHANGE) || 596 e.getPropertyName().equals(Location.TRAIN_DIRECTION_CHANGED_PROPERTY) || 597 e.getPropertyName().equals(Setup.ROUTING_STAGING_PROPERTY_CHANGE)) { 598 setColumnsVisible(); 599 } 600 if (e.getSource().getClass().equals(Track.class) && 601 (e.getPropertyName().equals(Track.DROP_CHANGED_PROPERTY) || 602 e.getPropertyName().equals(Track.PICKUP_CHANGED_PROPERTY) || 603 e.getPropertyName().equals(Track.SCHEDULE_ID_CHANGED_PROPERTY) || 604 e.getPropertyName().equals(Track.LOADS_CHANGED_PROPERTY) || 605 e.getPropertyName().equals(Track.ROADS_CHANGED_PROPERTY) || 606 e.getPropertyName().equals(Track.DESTINATION_OPTIONS_CHANGED_PROPERTY) || 607 e.getPropertyName().equals(Track.POOL_CHANGED_PROPERTY) || 608 e.getPropertyName().equals(Track.PLANNED_PICKUPS_CHANGED_PROPERTY) || 609 e.getPropertyName().equals(Track.ALTERNATE_TRACK_CHANGED_PROPERTY) || 610 e.getPropertyName().equals(Track.SERVICE_ORDER_CHANGED_PROPERTY) || 611 e.getPropertyName().equals(Track.LOAD_OPTIONS_CHANGED_PROPERTY) || 612 e.getPropertyName().equals(Track.TRAIN_DIRECTION_CHANGED_PROPERTY) || 613 e.getPropertyName().equals(Track.TRACK_REPORTER_CHANGED_PROPERTY))) { 614 setColumnsVisible(); 615 } 616 if (e.getSource() instanceof TableColumn && e.getPropertyName().equals("preferredWidth")) { 617 log.debug("Column width change"); 618 setDirty(true); 619 } 620 } 621 622 @Override 623 public void columnAdded(TableColumnModelEvent e) { 624 // do nothing 625 } 626 627 @Override 628 public void columnRemoved(TableColumnModelEvent e) { 629 // do nothing 630 } 631 632 @Override 633 public void columnMoved(TableColumnModelEvent e) { 634 if (e.getFromIndex() != e.getToIndex()) { 635 log.debug("Table Column Moved"); 636 setDirty(true); 637 } 638 } 639 640 @Override 641 public void columnMarginChanged(ChangeEvent e) { 642 // do nothing 643 } 644 645 @Override 646 public void columnSelectionChanged(ListSelectionEvent e) { 647 // do nothing 648 } 649 650 private final static Logger log = LoggerFactory.getLogger(TrackTableModel.class); 651}