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