001package jmri.jmrit.operations.routes.gui; 002 003import java.awt.BorderLayout; 004import java.awt.FlowLayout; 005import java.awt.event.ActionEvent; 006import java.awt.event.ActionListener; 007import java.beans.PropertyChangeEvent; 008import java.beans.PropertyChangeListener; 009import java.util.ArrayList; 010import java.util.List; 011 012import javax.swing.*; 013import javax.swing.colorchooser.AbstractColorChooserPanel; 014import javax.swing.table.DefaultTableCellRenderer; 015import javax.swing.table.TableCellEditor; 016 017import jmri.jmrit.operations.routes.Route; 018import jmri.jmrit.operations.routes.RouteLocation; 019import jmri.jmrit.operations.setup.Control; 020import jmri.jmrit.operations.setup.Setup; 021import jmri.jmrit.symbolicprog.ValueEditor; 022import jmri.jmrit.symbolicprog.ValueRenderer; 023import jmri.util.swing.*; 024import jmri.util.table.ButtonEditor; 025import jmri.util.table.ButtonRenderer; 026 027/** 028 * Table Model for edit of route locations used by operations 029 * 030 * @author Daniel Boudreau Copyright (C) 2008, 2013, 2025 031 */ 032public class RouteEditTableModel extends javax.swing.table.AbstractTableModel implements PropertyChangeListener { 033 034 // Defines the columns 035 private static final int ID_COLUMN = 0; 036 private static final int NAME_COLUMN = ID_COLUMN + 1; 037 private static final int TRAIN_DIRECTION_COLUMN = NAME_COLUMN + 1; 038 private static final int MAXMOVES_COLUMN = TRAIN_DIRECTION_COLUMN + 1; 039 private static final int RANDOM_CONTROL_COLUMN = MAXMOVES_COLUMN + 1; 040 private static final int PICKUP_COLUMN = RANDOM_CONTROL_COLUMN + 1; 041 private static final int DROP_COLUMN = PICKUP_COLUMN + 1; 042 private static final int LOCAL_COLUMN = DROP_COLUMN + 1; 043 private static final int DEPARTURE_DAY_COLUMN = LOCAL_COLUMN + 1; 044 private static final int DEPARTURE_TIME_COLUMN = DEPARTURE_DAY_COLUMN + 1; 045 private static final int TRAVEL_COLUMN = DEPARTURE_TIME_COLUMN + 1; 046 private static final int MAXLENGTH_COLUMN = TRAVEL_COLUMN + 1; 047 private static final int GRADE_COLUMN = MAXLENGTH_COLUMN + 1; 048 private static final int TRAINICONX_COLUMN = GRADE_COLUMN + 1; 049 private static final int TRAINICONY_COLUMN = TRAINICONX_COLUMN + 1; 050 private static final int COMMENT_COLUMN = TRAINICONY_COLUMN + 1; 051 private static final int UP_COLUMN = COMMENT_COLUMN + 1; 052 private static final int DOWN_COLUMN = UP_COLUMN + 1; 053 private static final int DELETE_COLUMN = DOWN_COLUMN + 1; 054 055 private static final int HIGHEST_COLUMN = DELETE_COLUMN + 1; 056 057 private JTable _table; 058 private Route _route; 059 private RouteEditFrame _frame; 060 List<RouteLocation> _routeList = new ArrayList<>(); 061 062 public RouteEditTableModel() { 063 super(); 064 } 065 066 private void updateList() { 067 if (_route == null) { 068 return; 069 } 070 // first, remove listeners from the individual objects 071 removePropertyChangeRouteLocations(); 072 _routeList = _route.getLocationsBySequenceList(); 073 // and add them back in 074 for (RouteLocation rl : _routeList) { 075 rl.addPropertyChangeListener(this); 076 } 077 } 078 079 protected void initTable(RouteEditFrame frame, JTable table, Route route) { 080 _frame = frame; 081 _table = table; 082 _route = route; 083 if (_route != null) { 084 _route.addPropertyChangeListener(this); 085 } 086 Setup.getDefault().addPropertyChangeListener(this); 087 initTable(table); 088 } 089 090 private void initTable(JTable table) { 091 // Use XTableColumnModel so we can control which columns are visible 092 XTableColumnModel tcm = new XTableColumnModel(); 093 _table.setColumnModel(tcm); 094 _table.createDefaultColumnsFromModel(); 095 // Install the button handlers 096 ButtonRenderer buttonRenderer = new ButtonRenderer(); 097 TableCellEditor buttonEditor = new ButtonEditor(new JButton()); 098 tcm.getColumn(COMMENT_COLUMN).setCellRenderer(buttonRenderer); 099 tcm.getColumn(COMMENT_COLUMN).setCellEditor(buttonEditor); 100 tcm.getColumn(UP_COLUMN).setCellRenderer(buttonRenderer); 101 tcm.getColumn(UP_COLUMN).setCellEditor(buttonEditor); 102 tcm.getColumn(DOWN_COLUMN).setCellRenderer(buttonRenderer); 103 tcm.getColumn(DOWN_COLUMN).setCellEditor(buttonEditor); 104 tcm.getColumn(DELETE_COLUMN).setCellRenderer(buttonRenderer); 105 tcm.getColumn(DELETE_COLUMN).setCellEditor(buttonEditor); 106 107 // for tool tips 108 DefaultTableCellRenderer defaultRenderer = new DefaultTableCellRenderer(); 109 tcm.getColumn(NAME_COLUMN).setCellRenderer(defaultRenderer); 110 tcm.getColumn(MAXMOVES_COLUMN).setCellRenderer(defaultRenderer); 111 tcm.getColumn(TRAVEL_COLUMN).setCellRenderer(defaultRenderer); 112 tcm.getColumn(MAXLENGTH_COLUMN).setCellRenderer(defaultRenderer); 113 tcm.getColumn(GRADE_COLUMN).setCellRenderer(defaultRenderer); 114 115 table.setDefaultRenderer(JComboBox.class, new ValueRenderer()); 116 table.setDefaultEditor(JComboBox.class, new ValueEditor()); 117 118 // set column preferred widths 119 table.getColumnModel().getColumn(ID_COLUMN).setPreferredWidth(40); 120 table.getColumnModel().getColumn(NAME_COLUMN).setPreferredWidth(150); 121 table.getColumnModel().getColumn(TRAIN_DIRECTION_COLUMN).setPreferredWidth(95); 122 table.getColumnModel().getColumn(MAXMOVES_COLUMN).setPreferredWidth(50); 123 table.getColumnModel().getColumn(RANDOM_CONTROL_COLUMN).setPreferredWidth(65); 124 table.getColumnModel().getColumn(PICKUP_COLUMN).setPreferredWidth(65); 125 table.getColumnModel().getColumn(DROP_COLUMN).setPreferredWidth(65); 126 table.getColumnModel().getColumn(LOCAL_COLUMN).setPreferredWidth(75); 127 table.getColumnModel().getColumn(TRAVEL_COLUMN).setPreferredWidth(65); 128 table.getColumnModel().getColumn(DEPARTURE_DAY_COLUMN).setPreferredWidth(65); 129 table.getColumnModel().getColumn(DEPARTURE_TIME_COLUMN).setPreferredWidth(65); 130 table.getColumnModel().getColumn(MAXLENGTH_COLUMN).setPreferredWidth(75); 131 table.getColumnModel().getColumn(GRADE_COLUMN).setPreferredWidth(50); 132 table.getColumnModel().getColumn(TRAINICONX_COLUMN).setPreferredWidth(35); 133 table.getColumnModel().getColumn(TRAINICONY_COLUMN).setPreferredWidth(35); 134 table.getColumnModel().getColumn(COMMENT_COLUMN).setPreferredWidth(70); 135 table.getColumnModel().getColumn(UP_COLUMN).setPreferredWidth(60); 136 table.getColumnModel().getColumn(DOWN_COLUMN).setPreferredWidth(70); 137 table.getColumnModel().getColumn(DELETE_COLUMN).setPreferredWidth(80); 138 139 _frame.loadTableDetails(table); 140 // does not use a table sorter 141 table.setRowSorter(null); 142 143 // turn on column that on earlier versions was off 144 tcm.setColumnVisible(tcm.getColumnByModelIndex(DEPARTURE_TIME_COLUMN), true); 145 146 updateList(); 147 } 148 149 @Override 150 public int getRowCount() { 151 return _routeList.size(); 152 } 153 154 @Override 155 public int getColumnCount() { 156 return HIGHEST_COLUMN; 157 } 158 159 @Override 160 public String getColumnName(int col) { 161 switch (col) { 162 case ID_COLUMN: 163 return Bundle.getMessage("Id"); 164 case NAME_COLUMN: 165 return Bundle.getMessage("Location"); 166 case TRAIN_DIRECTION_COLUMN: 167 return Bundle.getMessage("TrainDirection"); 168 case MAXMOVES_COLUMN: 169 return Bundle.getMessage("MaxMoves"); 170 case RANDOM_CONTROL_COLUMN: 171 return Bundle.getMessage("Random"); 172 case PICKUP_COLUMN: 173 return Bundle.getMessage("Pickups"); 174 case DROP_COLUMN: 175 return Bundle.getMessage("Drops"); 176 case LOCAL_COLUMN: 177 return Bundle.getMessage("LocalMoves"); 178 case TRAVEL_COLUMN: 179 return Bundle.getMessage("Travel"); 180 case DEPARTURE_DAY_COLUMN: 181 return Bundle.getMessage("Day"); 182 case DEPARTURE_TIME_COLUMN: 183 return Bundle.getMessage("Time"); 184 case MAXLENGTH_COLUMN: 185 return Bundle.getMessage("MaxLength"); 186 case GRADE_COLUMN: 187 return Bundle.getMessage("Grade"); 188 case TRAINICONX_COLUMN: 189 return Bundle.getMessage("X"); 190 case TRAINICONY_COLUMN: 191 return Bundle.getMessage("Y"); 192 case COMMENT_COLUMN: 193 return Bundle.getMessage("Comment"); 194 case UP_COLUMN: 195 return Bundle.getMessage("Up"); 196 case DOWN_COLUMN: 197 return Bundle.getMessage("Down"); 198 case DELETE_COLUMN: 199 return Bundle.getMessage("ButtonDelete"); // titles above all columns 200 default: 201 return "unknown"; // NOI18N 202 } 203 } 204 205 @Override 206 public Class<?> getColumnClass(int col) { 207 switch (col) { 208 case ID_COLUMN: 209 case NAME_COLUMN: 210 return String.class; 211 case TRAVEL_COLUMN: 212 case MAXLENGTH_COLUMN: 213 case MAXMOVES_COLUMN: 214 case TRAINICONX_COLUMN: 215 case TRAINICONY_COLUMN: 216 return Integer.class; 217 case GRADE_COLUMN: 218 return Double.class; 219 case TRAIN_DIRECTION_COLUMN: 220 case RANDOM_CONTROL_COLUMN: 221 case PICKUP_COLUMN: 222 case DROP_COLUMN: 223 case LOCAL_COLUMN: 224 case DEPARTURE_DAY_COLUMN: 225 case DEPARTURE_TIME_COLUMN: 226 return JComboBox.class; 227 case COMMENT_COLUMN: 228 case UP_COLUMN: 229 case DOWN_COLUMN: 230 case DELETE_COLUMN: 231 return JButton.class; 232 default: 233 return null; 234 } 235 } 236 237 @Override 238 public boolean isCellEditable(int row, int col) { 239 switch (col) { 240 case DELETE_COLUMN: 241 case TRAIN_DIRECTION_COLUMN: 242 case MAXMOVES_COLUMN: 243 case RANDOM_CONTROL_COLUMN: 244 case PICKUP_COLUMN: 245 case DROP_COLUMN: 246 case LOCAL_COLUMN: 247 case TRAVEL_COLUMN: 248 case DEPARTURE_DAY_COLUMN: 249 case DEPARTURE_TIME_COLUMN: 250 case MAXLENGTH_COLUMN: 251 case GRADE_COLUMN: 252 case TRAINICONX_COLUMN: 253 case TRAINICONY_COLUMN: 254 case COMMENT_COLUMN: 255 case UP_COLUMN: 256 case DOWN_COLUMN: 257 return true; 258 default: 259 return false; 260 } 261 } 262 263 @Override 264 public Object getValueAt(int row, int col) { 265 if (row >= getRowCount()) { 266 return "ERROR unknown " + row; // NOI18N 267 } 268 RouteLocation rl = _routeList.get(row); 269 if (rl == null) { 270 return "ERROR unknown route location " + row; // NOI18N 271 } 272 switch (col) { 273 case ID_COLUMN: 274 return rl.getId(); 275 case NAME_COLUMN: 276 setLocationToolTip(rl); 277 return rl.getName(); 278 case TRAIN_DIRECTION_COLUMN: { 279 JComboBox<String> cb = Setup.getTrainDirectionComboBox(); 280 cb.setSelectedItem(rl.getTrainDirectionString()); 281 return cb; 282 } 283 case MAXMOVES_COLUMN: 284 setToolTip(Bundle.getMessage("TipColMaxMoves", rl.getName()), col); 285 return rl.getMaxCarMoves(); 286 case RANDOM_CONTROL_COLUMN: { 287 JComboBox<String> cb = getRandomControlComboBox(); 288 cb.setToolTipText(Bundle.getMessage("TipRandomReduce", rl.getRandomControl())); 289 cb.setSelectedItem(rl.getRandomControl()); 290 return cb; 291 } 292 case PICKUP_COLUMN: { 293 JComboBox<String> cb = getYesNoComboBox(); 294 cb.setSelectedItem(rl.isPickUpAllowed() ? Bundle.getMessage("yes") : Bundle.getMessage("no")); 295 return cb; 296 } 297 case DROP_COLUMN: { 298 JComboBox<String> cb = getYesNoComboBox(); 299 cb.setSelectedItem(rl.isDropAllowed() ? Bundle.getMessage("yes") : Bundle.getMessage("no")); 300 return cb; 301 } 302 case LOCAL_COLUMN: { 303 JComboBox<String> cb = getYesNoComboBox(); 304 cb.setSelectedItem(rl.isLocalMovesAllowed() ? Bundle.getMessage("yes") : Bundle.getMessage("no")); 305 return cb; 306 } 307 case TRAVEL_COLUMN: { 308 setToolTip(Bundle.getMessage("TipColTravelTime"), col); 309 return rl.getWait() + Setup.getTravelTime(); 310 } 311 case DEPARTURE_DAY_COLUMN: { 312 JComboBox<String> cb = getDayComboBox(); 313 cb.setToolTipText(Bundle.getMessage("TipDepartureDay", rl.getName())); 314 cb.setSelectedItem(rl.getDepartureTimeDay()); 315 return cb; 316 } 317 case DEPARTURE_TIME_COLUMN: { 318 JComboBox<String> cb = getTimeComboBox(); 319 cb.setToolTipText(Bundle.getMessage("TipDepartureTime", rl.getName())); 320 cb.setSelectedItem(rl.getDepartureTimeHourMinutes()); 321 return cb; 322 } 323 case MAXLENGTH_COLUMN: 324 setToolTip(Bundle.getMessage("TipColMaxLength", rl.getName(), Setup.getLengthUnit().toLowerCase()), col); 325 return rl.getMaxTrainLength(); 326 case GRADE_COLUMN: 327 setToolTip(Bundle.getMessage("TipColGrade", rl.getName()), col); 328 return rl.getGrade(); 329 case TRAINICONX_COLUMN: 330 return rl.getTrainIconX(); 331 case TRAINICONY_COLUMN: 332 return rl.getTrainIconY(); 333 case COMMENT_COLUMN: { 334 if (rl.getComment().equals(RouteLocation.NONE)) { 335 return Bundle.getMessage("Add"); 336 } else { 337 return Bundle.getMessage("ButtonEdit"); 338 } 339 } 340 case UP_COLUMN: 341 return Bundle.getMessage("Up"); 342 case DOWN_COLUMN: 343 return Bundle.getMessage("Down"); 344 case DELETE_COLUMN: 345 return Bundle.getMessage("ButtonDelete"); 346 default: 347 return "unknown " + col; // NOI18N 348 } 349 } 350 351 @Override 352 public void setValueAt(Object value, int row, int col) { 353 if (value == null) { 354 log.debug("Warning route table row {} still in edit", row); 355 return; 356 } 357 RouteLocation rl = _routeList.get(row); 358 if (rl == null) { 359 log.error("ERROR unknown route location for row: {}", row); // NOI18N 360 } 361 switch (col) { 362 case COMMENT_COLUMN: 363 setComment(rl); 364 break; 365 case UP_COLUMN: 366 moveUpRouteLocation(rl); 367 break; 368 case DOWN_COLUMN: 369 moveDownRouteLocation(rl); 370 break; 371 case DELETE_COLUMN: 372 deleteRouteLocation(rl); 373 break; 374 case TRAIN_DIRECTION_COLUMN: 375 setTrainDirection(value, rl); 376 break; 377 case MAXMOVES_COLUMN: 378 setMaxTrainMoves(value, rl); 379 break; 380 case RANDOM_CONTROL_COLUMN: 381 setRandomControlValue(value, rl); 382 break; 383 case PICKUP_COLUMN: 384 setPickup(value, rl); 385 break; 386 case DROP_COLUMN: 387 setDrop(value, rl); 388 break; 389 case LOCAL_COLUMN: 390 setLocal(value, rl); 391 break; 392 case TRAVEL_COLUMN: 393 setTravel(value, rl); 394 break; 395 case DEPARTURE_DAY_COLUMN: 396 setDepartureDay(value, rl); 397 break; 398 case DEPARTURE_TIME_COLUMN: 399 setDepartureTime(value, rl); 400 break; 401 case MAXLENGTH_COLUMN: 402 setMaxTrainLength(value, rl); 403 break; 404 case GRADE_COLUMN: 405 setGrade(value, rl); 406 break; 407 case TRAINICONX_COLUMN: 408 setTrainIconX(value, rl); 409 break; 410 case TRAINICONY_COLUMN: 411 setTrainIconY(value, rl); 412 break; 413 default: 414 break; 415 } 416 } 417 418 private void moveUpRouteLocation(RouteLocation rl) { 419 log.debug("move location up"); 420 _route.moveLocationUp(rl); 421 } 422 423 private void moveDownRouteLocation(RouteLocation rl) { 424 log.debug("move location down"); 425 _route.moveLocationDown(rl); 426 } 427 428 private void deleteRouteLocation(RouteLocation rl) { 429 log.debug("Delete location"); 430 _route.deleteLocation(rl); 431 } 432 433 private int _trainDirection = Setup.getDirectionInt(Setup.getTrainDirectionList().get(0)); 434 435 public int getLastTrainDirection() { 436 return _trainDirection; 437 } 438 439 private void setTrainDirection(Object value, RouteLocation rl) { 440 _trainDirection = Setup.getDirectionInt((String) ((JComboBox<?>) value).getSelectedItem()); 441 rl.setTrainDirection(_trainDirection); 442 // update train icon 443 rl.setTrainIconCoordinates(); 444 } 445 446 private int _maxTrainMoves = Setup.getCarMoves(); 447 448 public int getLastMaxTrainMoves() { 449 return _maxTrainMoves; 450 } 451 452 private void setMaxTrainMoves(Object value, RouteLocation rl) { 453 int moves = (int) value; 454 if (moves <= 500) { 455 rl.setMaxCarMoves(moves); 456 _maxTrainMoves = moves; 457 } else { 458 JmriJOptionPane.showMessageDialog(null, Bundle.getMessage("MaximumLocationMoves"), Bundle 459 .getMessage("CanNotChangeMoves"), JmriJOptionPane.ERROR_MESSAGE); 460 } 461 } 462 463 private void setRandomControlValue(Object value, RouteLocation rl) { 464 rl.setRandomControl((String) ((JComboBox<?>) value).getSelectedItem()); 465 } 466 467 private void setDrop(Object value, RouteLocation rl) { 468 rl.setDropAllowed( 469 ((String) ((JComboBox<?>) value).getSelectedItem()).equals(Bundle.getMessage("yes"))); 470 } 471 472 private void setPickup(Object value, RouteLocation rl) { 473 rl.setPickUpAllowed( 474 ((String) ((JComboBox<?>) value).getSelectedItem()).equals(Bundle.getMessage("yes"))); 475 } 476 477 private void setLocal(Object value, RouteLocation rl) { 478 rl.setLocalMovesAllowed( 479 ((String) ((JComboBox<?>) value).getSelectedItem()).equals(Bundle.getMessage("yes"))); 480 } 481 482 private int _maxTrainLength = Setup.getMaxTrainLength(); 483 484 public int getLastMaxTrainLength() { 485 return _maxTrainLength; 486 } 487 488 private void setTravel(Object value, RouteLocation rl) { 489 int wait = (int) value; 490 rl.setWait(wait - Setup.getTravelTime()); 491 } 492 493 private void setDepartureTime(Object value, RouteLocation rl) { 494 rl.setDepartureTimeHourMinutes((String) ((JComboBox<?>) value).getSelectedItem()); 495 } 496 497 private void setDepartureDay(Object value, RouteLocation rl) { 498 rl.setDepartureTimeDay((String) ((JComboBox<?>) value).getSelectedItem()); 499 } 500 501 private void setMaxTrainLength(Object value, RouteLocation rl) { 502 int length = (int) value; 503 if (length < 0) { 504 log.error("Maximum departure length must be a postive number"); 505 return; 506 } 507 if (length > Setup.getMaxTrainLength()) { 508 log.error("Maximum departure length can not exceed maximum train length"); 509 JmriJOptionPane.showMessageDialog(null, Bundle.getMessage("DepartureLengthNotExceed", 510 length, Setup.getMaxTrainLength()), Bundle.getMessage("CanNotChangeMaxLength"), 511 JmriJOptionPane.ERROR_MESSAGE); 512 return; 513 } 514 if (rl != _route.getTerminatesRouteLocation() && 515 (length < 500 && Setup.getLengthUnit().equals(Setup.FEET) || 516 length < 160 && Setup.getLengthUnit().equals(Setup.METER))) { 517 // warn that train length might be too short 518 if (JmriJOptionPane.showConfirmDialog(null, Bundle.getMessage("LimitTrainLength", 519 length, Setup.getLengthUnit().toLowerCase(), rl.getName()), 520 Bundle.getMessage("WarningTooShort"), 521 JmriJOptionPane.OK_CANCEL_OPTION) != JmriJOptionPane.OK_OPTION) { 522 return; 523 } 524 } 525 rl.setMaxTrainLength(length); 526 _maxTrainLength = length; 527 } 528 529 private void setGrade(Object value, RouteLocation rl) { 530 double grade = (Double) value; 531 if (grade <= 6 && grade >= -6) { 532 rl.setGrade(grade); 533 } else { 534 log.error("Maximum grade is 6 percent"); 535 JmriJOptionPane.showMessageDialog(null, Bundle.getMessage("MaxGrade"), 536 Bundle.getMessage("CanNotChangeGrade"), 537 JmriJOptionPane.ERROR_MESSAGE); 538 } 539 } 540 541 private void setTrainIconX(Object value, RouteLocation rl) { 542 int x = (int) value; 543 rl.setTrainIconX(x); 544 } 545 546 private void setTrainIconY(Object value, RouteLocation rl) { 547 int y = (int) value; 548 rl.setTrainIconY(y); 549 } 550 551 private void setComment(RouteLocation rl) { 552 // Create comment panel 553 final JDialog dialog = new JDialog(); 554 dialog.setLayout(new BorderLayout()); 555 dialog.setTitle(Bundle.getMessage("Comment") + " " + rl.getName()); 556 final JTextArea commentTextArea = new JTextArea(5, 100); 557 JScrollPane commentScroller = new JScrollPane(commentTextArea); 558 dialog.add(commentScroller, BorderLayout.CENTER); 559 commentTextArea.setText(rl.getComment()); 560 561 JPanel buttonPane = new JPanel(); 562 buttonPane.setLayout(new FlowLayout(FlowLayout.CENTER)); 563 dialog.add(buttonPane, BorderLayout.SOUTH); 564 565 // text color chooser 566 JPanel pTextColor = new JPanel(); 567 pTextColor.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("TextColor"))); 568 JColorChooser commentColorChooser = new JColorChooser(rl.getCommentColor()); 569 AbstractColorChooserPanel commentColorPanels[] = {new SplitButtonColorChooserPanel()}; 570 commentColorChooser.setChooserPanels(commentColorPanels); 571 commentColorChooser.setPreviewPanel(new JPanel()); 572 pTextColor.add(commentColorChooser); 573 buttonPane.add(pTextColor); 574 575 JButton okayButton = new JButton(Bundle.getMessage("ButtonOK")); 576 okayButton.addActionListener(new ActionListener() { 577 @Override 578 public void actionPerformed(ActionEvent arg0) { 579 rl.setComment(commentTextArea.getText()); 580 rl.setCommentColor(commentColorChooser.getColor()); 581 dialog.dispose(); 582 return; 583 } 584 }); 585 buttonPane.add(okayButton); 586 587 JButton cancelButton = new JButton(Bundle.getMessage("ButtonCancel")); 588 cancelButton.addActionListener(new ActionListener() { 589 @Override 590 public void actionPerformed(ActionEvent arg0) { 591 dialog.dispose(); 592 return; 593 } 594 }); 595 buttonPane.add(cancelButton); 596 597 dialog.setModal(true); 598 dialog.pack(); 599 dialog.setVisible(true); 600 } 601 602 private JComboBox<String> getYesNoComboBox() { 603 JComboBox<String> cb = new JComboBox<>(); 604 cb.addItem(Bundle.getMessage("yes")); 605 cb.addItem(Bundle.getMessage("no")); 606 return cb; 607 } 608 609 private JComboBox<String> getRandomControlComboBox() { 610 JComboBox<String> cb = new JComboBox<>(); 611 cb.addItem(RouteLocation.DISABLED); 612 // 10 to 100 by 10 613 for (int i = 10; i < 101; i = i + 10) { 614 cb.addItem(Integer.toString(i)); 615 } 616 return cb; 617 } 618 619 protected JComboBox<String> getTimeComboBox() { 620 JComboBox<String> timeBox = new JComboBox<>(); 621 timeBox.addItem(""); 622 for (int i = 0; i < 24; i++) { 623 String hour = String.format("%02d", i); 624 for (int j = 0; j < 60; j++) { 625 String minute = String.format("%02d", j); 626 timeBox.addItem(hour + ":" + minute); 627 } 628 } 629 return timeBox; 630 } 631 632 protected JComboBox<String> getDayComboBox() { 633 JComboBox<String> dayBox = new JComboBox<>(); 634 for (int i = 0; i < 32; i++) { 635 dayBox.addItem(Integer.toString(i)); 636 } 637 return dayBox; 638 } 639 640 private void setLocationToolTip(RouteLocation rl) { 641 String text = Bundle.getMessage("TipTrainDirection", rl.getName(), rl.getTrainDirectionString()); 642 if (rl == _route.getTerminatesRouteLocation()) { 643 text = Bundle.getMessage("TipTrainTerminates", rl.getName()); 644 } 645 setToolTip(text, NAME_COLUMN); 646 } 647 648 private void setToolTip(String text, int col) { 649 XTableColumnModel tcm = (XTableColumnModel) _table.getColumnModel(); 650 JComponent jC = (JComponent) tcm.getColumnByModelIndex(col).getCellRenderer(); 651 if (jC != null) { 652 jC.setToolTipText(text); 653 } 654 } 655 656 // this table listens for changes to a route and it's locations 657 @Override 658 public void propertyChange(PropertyChangeEvent e) { 659 if (Control.SHOW_PROPERTY) { 660 log.debug("Property change: ({}) old: ({}) new: ({})", e.getPropertyName(), e.getOldValue(), e 661 .getNewValue()); 662 } 663 if (e.getPropertyName().equals(Route.LISTCHANGE_CHANGED_PROPERTY)) { 664 updateList(); 665 fireTableDataChanged(); 666 } 667 if (e.getPropertyName().equals(Setup.TRAIN_DIRECTION_PROPERTY_CHANGE) || 668 e.getPropertyName().equals(Setup.TRAVEL_TIME_PROPERTY_CHANGE)) { 669 fireTableDataChanged(); 670 } 671 if (e.getSource().getClass().equals(RouteLocation.class)) { 672 RouteLocation rl = (RouteLocation) e.getSource(); 673 int row = _routeList.indexOf(rl); 674 if (Control.SHOW_PROPERTY) { 675 log.debug("Update route table row: {} id: {}", row, rl.getId()); 676 } 677 if (row >= 0) { 678 fireTableRowsUpdated(row, row); 679 } 680 } 681 } 682 683 private void removePropertyChangeRouteLocations() { 684 for (RouteLocation rl : _routeList) { 685 rl.removePropertyChangeListener(this); 686 } 687 } 688 689 public void dispose() { 690 removePropertyChangeRouteLocations(); 691 if (_route != null) { 692 _route.removePropertyChangeListener(this); 693 } 694 Setup.getDefault().removePropertyChangeListener(this); 695 _routeList.clear(); 696 fireTableDataChanged(); 697 } 698 699 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(RouteEditTableModel.class); 700}