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) && Setup.isCarRoutingViaStagingEnabled())); 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 Track track = _tracksList.get(row); 333 return !track.isModifyLoadsEnabled(); 334 case DISABLE_LOAD_CHANGE_COLUMN: 335 case HOLD_COLUMN: 336 case EDIT_COLUMN: 337 case MOVES_COLUMN: 338 return true; 339 default: 340 return false; 341 } 342 } 343 344 @Override 345 public Object getValueAt(int row, int col) { 346 if (row >= getRowCount()) { 347 return "ERROR row " + row; // NOI18N 348 } 349 Track track = _tracksList.get(row); 350 if (track == null) { 351 return "ERROR track unknown " + row; // NOI18N 352 } 353 switch (col) { 354 case ID_COLUMN: 355 return track.getId(); 356 case NAME_COLUMN: 357 return track.getName(); 358 case LENGTH_COLUMN: 359 return track.getLength(); 360 case USED_LENGTH_COLUMN: 361 return track.getUsedLength(); 362 case RESERVED_COLUMN: 363 return track.getReserved(); 364 case MOVES_COLUMN: 365 return track.getMoves(); 366 case LOCOS_COLUMN: 367 return track.getNumberEngines(); 368 case CARS_COLUMN: 369 return track.getNumberCars(); 370 case PICKUPS_COLUMN: 371 return track.getPickupRS(); 372 case SETOUT_COLUMN: 373 return track.getDropRS(); 374 case SCHEDULE_COLUMN: 375 return track.getScheduleName(); 376 case RESTRICTION_COLUMN: 377 return getRestrictions(track); 378 case LOAD_COLUMN: 379 return getModifiedString(track.getLoadNames().length, track.getLoadOption().equals(Track.ALL_LOADS), 380 track.getLoadOption().equals(Track.INCLUDE_LOADS)); 381 case DEFAULT_LOAD_COLUMN: 382 return getDefaultLoadString(track); 383 case CUSTOM_LOAD_COLUMN: 384 return getCustomLoadString(track); 385 case DISABLE_LOAD_CHANGE_COLUMN: 386 return track.isDisableLoadChangeEnabled(); 387 case SHIP_COLUMN: 388 return getModifiedString(track.getShipLoadNames().length, 389 track.getShipLoadOption().equals(Track.ALL_LOADS), 390 track.getShipLoadOption().equals(Track.INCLUDE_LOADS)); 391 case ROAD_COLUMN: 392 return getModifiedString(track.getRoadNames().length, track.getRoadOption().equals(Track.ALL_ROADS), 393 track.getRoadOption().equals(Track.INCLUDE_ROADS)); 394 case DESTINATION_COLUMN: { 395 return getDestinationString(track); 396 } 397 case ROUTED_COLUMN: 398 return track.isOnlyCarsWithFinalDestinationEnabled(); 399 case HOLD_COLUMN: 400 return track.isHoldCarsWithCustomLoadsEnabled(); 401 case POOL_COLUMN: 402 return track.getPoolName(); 403 case PLANPICKUP_COLUMN: 404 if (track.getIgnoreUsedLengthPercentage() > Track.IGNORE_0) { 405 return track.getIgnoreUsedLengthPercentage() + "%"; 406 } 407 return ""; 408 case ALT_TRACK_COLUMN: 409 if (track.getAlternateTrack() != null) { 410 return track.getAlternateTrack().getName(); 411 } 412 if (track.isAlternate()) { 413 return Bundle.getMessage("ButtonYes"); 414 } 415 return ""; 416 case ORDER_COLUMN: 417 return track.getServiceOrder(); 418 case TRAIN_DIRECTION_COLUMN: 419 int trainDirections = track.getLocation().getTrainDirections() & Setup.getTrainDirection(); 420 if (trainDirections != (track.getTrainDirections() & trainDirections)) { 421 return "X"; 422 } 423 return ""; 424 case REPORTER_COLUMN: 425 return track.getReporterName(); 426 case EDIT_COLUMN: 427 return Bundle.getMessage("ButtonEdit"); 428 default: 429 return "unknown " + col; // NOI18N 430 } 431 } 432 433 private String getRestrictions(Track track) { 434 StringBuffer restrictions = new StringBuffer(); 435 if (!track.getDropOption().equals(Track.ANY)) { 436 String suffix = " "; 437 if (track.getDropOption().equals(Track.EXCLUDE_ROUTES) || 438 track.getDropOption().equals(Track.EXCLUDE_TRAINS)) { 439 suffix = "x"; 440 } 441 restrictions.append(Bundle.getMessage("AbbreviationSetOut") + suffix + track.getDropIds().length); 442 } 443 if (!track.getPickupOption().equals(Track.ANY)) { 444 String suffix = " "; 445 if (track.getPickupOption().equals(Track.EXCLUDE_ROUTES) || 446 track.getPickupOption().equals(Track.EXCLUDE_TRAINS)) { 447 suffix = "x"; 448 } 449 restrictions.append(" " + Bundle.getMessage("AbbreviationPickUp") + suffix + track.getPickupIds().length); 450 } 451 return restrictions.toString(); 452 } 453 454 private String getModifiedString(int number, boolean all, boolean accept) { 455 if (all) { 456 return ""; 457 } 458 if (accept) { 459 return "A " + Integer.toString(number); // NOI18N 460 } 461 return "E " + Integer.toString(number); // NOI18N 462 } 463 464 private String getDefaultLoadString(Track track) { 465 String defaultLoad = ""; 466 if (track.isLoadSwapEnabled()) { 467 defaultLoad = Bundle.getMessage("ABV_SwapDefaultLoads"); 468 } 469 if (track.isLoadEmptyEnabled()) { 470 defaultLoad = Bundle.getMessage("ABV_EmptyDefaultLoads"); 471 } 472 return defaultLoad; 473 } 474 475 private String getCustomLoadString(Track track) { 476 StringBuffer customLoad = new StringBuffer(); 477 if (track.isRemoveCustomLoadsEnabled()) { 478 customLoad.append(Bundle.getMessage("ABV_EmptyCustomLoads") + " "); 479 } 480 if (track.isAddCustomLoadsEnabled()) { 481 customLoad.append(Bundle.getMessage("ABV_GenerateCustomLoad") + " "); 482 } 483 if (track.isAddCustomLoadsAnySpurEnabled()) { 484 customLoad.append(Bundle.getMessage("ABV_GenerateCustomLoadAnySpur") + " "); 485 } 486 if (track.isAddCustomLoadsAnyStagingTrackEnabled()) { 487 customLoad.append(Bundle.getMessage("ABV_GereateCustomLoadStaging")); 488 } 489 if (track.isBlockCarsEnabled()) { 490 customLoad.append(Bundle.getMessage("ABV_CarBlocking")); 491 } 492 return customLoad.toString(); 493 } 494 495 private String getDestinationString(Track track) { 496 int size = track.getDestinationListSize(); 497 if (track.getDestinationOption().equals(Track.EXCLUDE_DESTINATIONS)) { 498 size = InstanceManager.getDefault(LocationManager.class).getNumberOfLocations() - size; 499 } else if (size == 1 && track.getDestinationOption().equals(Track.INCLUDE_DESTINATIONS)) { 500 // if there's only one destination return the destination name 501 Location loc = 502 InstanceManager.getDefault(LocationManager.class).getLocationById(track.getDestinationIds()[0]); 503 if (loc != null) { 504 return loc.getName(); 505 } 506 } 507 return getModifiedString(size, track.getDestinationOption().equals(Track.ALL_DESTINATIONS), 508 track.getDestinationOption().equals(Track.INCLUDE_DESTINATIONS)); 509 } 510 511 @Override 512 public void setValueAt(Object value, int row, int col) { 513 switch (col) { 514 case DISABLE_LOAD_CHANGE_COLUMN: 515 setDisableLoadChange(row, value); 516 break; 517 case ROUTED_COLUMN: 518 setRouted(row, value); 519 break; 520 case HOLD_COLUMN: 521 setHold(row, value); 522 break; 523 case EDIT_COLUMN: 524 editTrack(row); 525 break; 526 case MOVES_COLUMN: 527 setMoves(row, value); 528 break; 529 default: 530 break; 531 } 532 } 533 534 TrackEditFrame tef = null; 535 536 abstract protected void editTrack(int row); 537 538 private void setDisableLoadChange(int row, Object value) { 539 Track track = _tracksList.get(row); 540 track.setDisableLoadChangeEnabled(((Boolean) value).booleanValue()); 541 } 542 543 private void setRouted(int row, Object value) { 544 Track track = _tracksList.get(row); 545 track.setOnlyCarsWithFinalDestinationEnabled(((Boolean) value).booleanValue()); 546 } 547 548 private void setHold(int row, Object value) { 549 Track track = _tracksList.get(row); 550 track.setHoldCarsWithCustomLoadsEnabled(((Boolean) value).booleanValue()); 551 } 552 553 private void setMoves(int row, Object value) { 554 Track track = _tracksList.get(row); 555 track.setMoves((int) value); 556 } 557 558 private void removePropertyChangeTracks() { 559 for (Track track : _tracksList) { 560 track.removePropertyChangeListener(this); 561 } 562 } 563 564 public void dispose() { 565 if (_table != null) { 566 _table.getRowSorter().setSortKeys(null); 567 if (isDirty()) { 568 OperationsPanel.cacheState(_table); 569 OperationsPanel.saveTableState(); 570 setDirty(false); 571 } 572 } 573 removePropertyChangeTracks(); 574 if (_location != null) { 575 _location.removePropertyChangeListener(this); 576 } 577 if (tef != null) { 578 tef.dispose(); 579 } 580 Setup.getDefault().removePropertyChangeListener(this); 581 _tracksList.clear(); 582 fireTableDataChanged(); 583 } 584 585 // this table listens for changes to a location and it's tracks 586 @Override 587 public void propertyChange(PropertyChangeEvent e) { 588 if (Control.SHOW_PROPERTY) { 589 log.debug("Property change: ({}) old: ({}) new: ({})", e.getPropertyName(), e.getOldValue(), 590 e.getNewValue()); 591 } 592 if (e.getPropertyName().equals(Location.TRACK_LISTLENGTH_CHANGED_PROPERTY) || 593 e.getPropertyName().equals(Location.TRAIN_DIRECTION_CHANGED_PROPERTY)) { 594 updateList(); 595 fireTableDataChanged(); 596 } 597 if (e.getPropertyName().equals(Setup.SHOW_TRACK_MOVES_PROPERTY_CHANGE) || 598 e.getPropertyName().equals(Location.TRAIN_DIRECTION_CHANGED_PROPERTY) || 599 e.getPropertyName().equals(Setup.ROUTING_STAGING_PROPERTY_CHANGE)) { 600 setColumnsVisible(); 601 } 602 if (e.getSource().getClass().equals(Track.class) && 603 (e.getPropertyName().equals(Track.DROP_CHANGED_PROPERTY) || 604 e.getPropertyName().equals(Track.PICKUP_CHANGED_PROPERTY) || 605 e.getPropertyName().equals(Track.SCHEDULE_ID_CHANGED_PROPERTY) || 606 e.getPropertyName().equals(Track.LOADS_CHANGED_PROPERTY) || 607 e.getPropertyName().equals(Track.ROADS_CHANGED_PROPERTY) || 608 e.getPropertyName().equals(Track.DESTINATION_OPTIONS_CHANGED_PROPERTY) || 609 e.getPropertyName().equals(Track.POOL_CHANGED_PROPERTY) || 610 e.getPropertyName().equals(Track.PLANNED_PICKUPS_CHANGED_PROPERTY) || 611 e.getPropertyName().equals(Track.ALTERNATE_TRACK_CHANGED_PROPERTY) || 612 e.getPropertyName().equals(Track.SERVICE_ORDER_CHANGED_PROPERTY) || 613 e.getPropertyName().equals(Track.LOAD_OPTIONS_CHANGED_PROPERTY) || 614 e.getPropertyName().equals(Track.TRAIN_DIRECTION_CHANGED_PROPERTY) || 615 e.getPropertyName().equals(Track.TRACK_REPORTER_CHANGED_PROPERTY))) { 616 setColumnsVisible(); 617 } 618 if (e.getSource() instanceof TableColumn && e.getPropertyName().equals("preferredWidth")) { 619 log.debug("Column width change"); 620 setDirty(true); 621 } 622 } 623 624 @Override 625 public void columnAdded(TableColumnModelEvent e) { 626 // do nothing 627 } 628 629 @Override 630 public void columnRemoved(TableColumnModelEvent e) { 631 // do nothing 632 } 633 634 @Override 635 public void columnMoved(TableColumnModelEvent e) { 636 if (e.getFromIndex() != e.getToIndex()) { 637 log.debug("Table Column Moved"); 638 setDirty(true); 639 } 640 } 641 642 @Override 643 public void columnMarginChanged(ChangeEvent e) { 644 // do nothing 645 } 646 647 @Override 648 public void columnSelectionChanged(ListSelectionEvent e) { 649 // do nothing 650 } 651 652 private final static Logger log = LoggerFactory.getLogger(TrackTableModel.class); 653}