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