001package jmri.jmrix.ecos.swing.locodatabase; 002 003import java.awt.Component; 004import java.awt.event.ActionEvent; 005import java.awt.event.ActionListener; 006import java.util.Hashtable; 007import java.util.List; 008 009import javax.annotation.Nonnull; 010import javax.annotation.CheckForNull; 011import javax.swing.BorderFactory; 012import javax.swing.BoxLayout; 013import javax.swing.DefaultCellEditor; 014import javax.swing.JButton; 015import javax.swing.JCheckBox; 016import javax.swing.JComboBox; 017import javax.swing.JDialog; 018import javax.swing.JLabel; 019import javax.swing.JPanel; 020import javax.swing.JTable; 021import javax.swing.JTextField; 022import javax.swing.RowSorter; 023import javax.swing.table.TableCellEditor; 024import javax.swing.table.TableCellRenderer; 025import javax.swing.table.TableColumn; 026import javax.swing.table.TableModel; 027import javax.swing.table.TableRowSorter; 028 029import jmri.Manager; 030import jmri.NamedBean; 031import jmri.jmrit.beantable.AbstractTableAction; 032import jmri.jmrit.beantable.BeanTableDataModel; 033import jmri.jmrit.roster.Roster; 034import jmri.jmrit.roster.RosterEntry; 035import jmri.jmrit.roster.swing.GlobalRosterEntryComboBox; 036import jmri.jmrix.ecos.EcosLocoAddress; 037import jmri.jmrix.ecos.EcosLocoAddressManager; 038import jmri.jmrix.ecos.EcosMessage; 039import jmri.jmrix.ecos.EcosSystemConnectionMemo; 040import jmri.jmrix.ecos.utilities.EcosLocoToRoster; 041import jmri.jmrix.ecos.utilities.RemoveObjectFromEcos; 042import jmri.util.swing.JmriJOptionPane; 043import jmri.util.swing.JmriMouseEvent; 044import jmri.util.swing.XTableColumnModel; 045 046public class EcosLocoTableAction extends AbstractTableAction<NamedBean> { 047 048 /** 049 * Create an action with a specific title. 050 * <p> 051 * Note that the argument is the Action title, not the title of the 052 * resulting frame. Perhaps this should be changed? 053 * @param s Action title string. 054 */ 055 public EcosLocoTableAction(String s) { 056 super(s); 057 } 058 059 public EcosLocoTableAction() { 060 this(Bundle.getMessage("EcosLocoTableTitle")); 061 } 062 063 public EcosLocoTableAction(String s, EcosSystemConnectionMemo memo) { 064 this(s); 065 setAdapterMemo(memo); 066 includeAddButton = false; 067 } 068 069 @Override 070 public void actionPerformed(ActionEvent e) { 071 // create the JTable model, with changes for specific NamedBean 072 createModel(); 073 TableRowSorter<BeanTableDataModel<NamedBean>> sorter = new TableRowSorter<>(m); 074 JTable dataTable = m.makeJTable(getClassName(), m, sorter); 075 // create the frame 076 f = new jmri.jmrit.beantable.BeanTableFrame<NamedBean>(m, helpTarget(), dataTable) { 077 }; 078 setMenuBar(f); 079 setTitle(); 080 addToFrame(f); 081 f.pack(); 082 f.setVisible(true); 083 } 084 085 protected EcosSystemConnectionMemo adaptermemo; 086 protected EcosLocoAddressManager locoManager; 087 088 @Override 089 public void setManager(Manager<NamedBean> man) { 090 if (!(man instanceof EcosLocoAddressManager)) { 091 throw new IllegalArgumentException("Manager is not an EcosLocoAddressManager"); 092 } 093 locoManager = (EcosLocoAddressManager) man; 094 } 095 protected String rosterAttribute; 096 097 public void setAdapterMemo(EcosSystemConnectionMemo memo) { 098 adaptermemo = memo; 099 locoManager = adaptermemo.getLocoAddressManager(); 100 rosterAttribute = adaptermemo.getPreferenceManager().getRosterAttribute(); 101 } 102 103 protected EcosLocoAddress getByEcosObject(String object) { 104 return locoManager.getByEcosObject(object); 105 } 106 107 List<String> ecosObjectIdList = null; 108 JTable table; 109 110 static public final int PROTOCOL = 5; 111 static public final int ADDTOROSTERCOL = 6; 112 static public final int SPEEDDIR = 7; 113 static public final int STOP = 8; 114 115 @Override 116 protected void createModel() { 117 m = new BeanTableDataModel<NamedBean>() { // this is a hack to get this to compile, as EcosLocoAddress is itself not a NamedBean 118 119 //We have to set a manager first off, but this gets replaced. 120 @Override 121 protected EcosLocoAddressManager getManager() { 122 return locoManager; 123 } 124 125 protected String getRosterAttribute() { 126 return rosterAttribute; 127 } 128 129 @Override 130 public String getValue(String s) { 131 return Bundle.getMessage("ButtonSet"); 132 } 133 134 @Override 135 protected String getMasterClassName() { 136 return getClassName(); 137 } 138 139 @Override 140 public void clickOn(jmri.NamedBean t) { 141 } 142 143 @Override 144 protected synchronized void updateNameList() { 145 // first, remove listeners from the individual objects 146 if (ecosObjectIdList != null) { 147 for (int i = 0; i < ecosObjectIdList.size(); i++) { 148 // if object has been deleted, it's not here; ignore it 149 jmri.jmrix.ecos.EcosLocoAddress b = getByEcosObject(ecosObjectIdList.get(i)); 150 if (b != null) { 151 b.removePropertyChangeListener(this); 152 } 153 } 154 } 155 ecosObjectIdList = getManager().getEcosObjectList(); 156 // and add them back in 157 for (int i = 0; i < ecosObjectIdList.size(); i++) { 158 getByEcosObject(ecosObjectIdList.get(i)).addPropertyChangeListener(this); 159 } 160 } 161 162 @Override 163 public void propertyChange(java.beans.PropertyChangeEvent e) { 164 updateNameList(); 165 if (e.getPropertyName().equals("length")) { 166 // a new jmri.jmrix.ecos.EcosLocoAddressManager is available in the manager 167 updateNameList(); 168 fireTableDataChanged(); 169 } else if (matchPropertyName(e)) { 170 // a value changed. Find it, to avoid complete redraw 171 String object = ((jmri.jmrix.ecos.EcosLocoAddress) e.getSource()).getEcosObject(); 172 // since we can add columns, the entire row is marked as updated 173 int row = ecosObjectIdList.indexOf(object); 174 fireTableRowsUpdated(row, row); 175 } 176 } 177 178 @Override 179 public int getColumnCount() { 180 return STOP + 1; 181 } 182 183 @Override 184 public void setValueAt(Object value, int row, int col) { 185 if (col == COMMENTCOL) { 186 RosterEntry re; 187 String ecosObjectNo = ecosObjectIdList.get(row); 188 if (value == null) { 189 return; 190 } else if (value instanceof RosterEntry) { 191 re = (RosterEntry) value; 192 if ((re.getAttribute(getRosterAttribute()) != null && !re.getAttribute(getRosterAttribute()).equals(""))) { 193 JmriJOptionPane.showMessageDialog(f, 194 Bundle.getMessage("EcosEditAssignedDialog", ecosObjectNo)); 195 log.error("{} This roster entry already has an ECoS loco assigned to it", ecosObjectNo); 196 return; 197 } 198 String oldRoster = getByEcosObject(ecosObjectNo).getRosterId(); 199 RosterEntry oldre; 200 if (oldRoster != null) { 201 oldre = Roster.getDefault().getEntryForId(oldRoster); 202 if (oldre != null) { 203 oldre.deleteAttribute(getRosterAttribute()); 204 } 205 } 206 re.putAttribute(getRosterAttribute(), ecosObjectNo); 207 getByEcosObject(ecosObjectNo).setRosterId(re.getId()); 208 re.updateFile(); 209 } else if (value instanceof String) { 210 List<RosterEntry> r = Roster.getDefault().getEntriesWithAttributeKeyValue(getRosterAttribute(), ecosObjectNo); 211 if (r.isEmpty()) { 212 r.get(0).deleteAttribute(getRosterAttribute()); 213 getByEcosObject(ecosObjectNo).setRosterId(null); 214 r.get(0).updateFile(); 215 } 216 217 } 218 Roster.getDefault().writeRoster(); 219 } else if (col == ADDTOROSTERCOL) { 220 addToRoster(row, col); 221 } else if (col == STOP) { 222 stopLoco(row, col); 223 } else if (col == DELETECOL) { 224 // button fired, delete Bean 225 deleteLoco(row, col); 226 } else if (col == USERNAMECOL) { 227 jmri.jmrix.ecos.EcosLocoAddress b = getByEcosObject(ecosObjectIdList.get(row)); 228 EcosMessage m = new EcosMessage("request(" + b.getEcosObject() + ", control, force)"); 229 adaptermemo.getTrafficController().sendEcosMessage(m, null); 230 m = new EcosMessage("set(" + b.getEcosObject() + ", name[\"" + (String) value + "\"])"); 231 adaptermemo.getTrafficController().sendEcosMessage(m, null); 232 m = new EcosMessage("release(" + b.getEcosObject() + ", control)"); 233 adaptermemo.getTrafficController().sendEcosMessage(m, null); 234 } 235 } 236 237 @Override 238 public JTable makeJTable(@Nonnull String name, @Nonnull TableModel model, @CheckForNull RowSorter<? extends TableModel> sorter) { 239 return this.configureJTable(name, this.makeJTable(model), sorter); 240 } 241 242 private JTable makeJTable(@Nonnull TableModel model) { 243 JTable table = new JTable(model) { 244 245 @Override 246 public TableCellRenderer getCellRenderer(int row, int column) { 247 if (column == COMMENTCOL) { 248 return getRenderer(row); 249 } else { 250 return super.getCellRenderer(row, column); 251 } 252 } 253 254 @Override 255 public TableCellEditor getCellEditor(int row, int column) { 256 if (column == COMMENTCOL) { 257 return getEditor(row); 258 } else { 259 return super.getCellEditor(row, column); 260 } 261 } 262 263 TableCellRenderer getRenderer(int row) { 264 TableCellRenderer retval = rendererMap.get(ecosObjectIdList.get(row)); 265 if (retval == null) { 266 jmri.jmrix.ecos.EcosLocoAddress b = getByEcosObject(ecosObjectIdList.get(row)); 267 RosterEntry re = null; 268 if (b != null) { 269 re = Roster.getDefault().getEntryForId(b.getRosterId()); 270 } 271 retval = new RosterBoxRenderer(re); 272 rendererMap.put(ecosObjectIdList.get(row), retval); 273 } 274 return retval; 275 } 276 Hashtable<Object, TableCellRenderer> rendererMap = new Hashtable<>(); 277 278 TableCellEditor getEditor(int row) { 279 TableCellEditor retval = editorMap.get(ecosObjectIdList.get(row)); 280 if (retval == null) { 281 jmri.jmrix.ecos.EcosLocoAddress b = getByEcosObject(ecosObjectIdList.get(row)); 282 RosterEntry re = null; 283 if (b != null) { 284 re = Roster.getDefault().getEntryForId(b.getRosterId()); 285 } 286 GlobalRosterEntryComboBox cb = new GlobalRosterEntryComboBox(); 287 cb.setNonSelectedItem(" "); 288 if (re == null) { 289 cb.setSelectedIndex(0); 290 } else { 291 cb.setSelectedItem(re); 292 } 293 // create a new one with right aspects 294 retval = new RosterComboBoxEditor(cb); 295 editorMap.put(ecosObjectIdList.get(row), retval); 296 } 297 return retval; 298 } 299 Hashtable<Object, TableCellEditor> editorMap = new Hashtable<>(); 300 }; 301 table.getTableHeader().setReorderingAllowed(true); 302 table.setColumnModel(new XTableColumnModel()); 303 table.createDefaultColumnsFromModel(); 304 305 addMouseListenerToHeader(table); 306 return table; 307 } 308 309 /** 310 * Is this property event announcing a change this table should 311 * display? 312 * <p> 313 * Note that events will come both from the 314 * jmri.jmrix.ecos.EcosLocoAddressManagers and also from the manager 315 */ 316 @Override 317 protected boolean matchPropertyName(java.beans.PropertyChangeEvent e) { 318 if (!showLocoMonitor && (e.getPropertyName().equals("Speed") || e.getPropertyName().equals("Direction"))) { 319 return false; 320 } 321 return true; 322 } 323 324 @Override 325 public String getColumnName(int col) { 326 switch (col) { 327 case SYSNAMECOL: 328 return Bundle.getMessage("ObjectIdCol"); 329 case USERNAMECOL: 330 return Bundle.getMessage("DescriptionCol"); 331 case VALUECOL: 332 return Bundle.getMessage("AddressCol"); 333 case COMMENTCOL: 334 return Bundle.getMessage("JmriIdCol"); 335 case DELETECOL: 336 return ""; // no heading on Delete column 337 case PROTOCOL: 338 return Bundle.getMessage("ProtocolCol"); 339 case ADDTOROSTERCOL: 340 return ""; // no heading on Add to Roster column 341 case SPEEDDIR: 342 return Bundle.getMessage("SpeedCol") + " " + Bundle.getMessage("DirectionCol"); 343 case STOP: 344 return ""; // no heading on Stop column 345 default: 346 return "unknown"; // NOI18N 347 } 348 } 349 350 @Override 351 public Class<?> getColumnClass(int col) { 352 switch (col) { 353 case SYSNAMECOL: 354 case USERNAMECOL: 355 case PROTOCOL: 356 case SPEEDDIR: 357 return String.class; 358 case VALUECOL: 359 return Integer.class; 360 case ADDTOROSTERCOL: 361 case DELETECOL: 362 case STOP: 363 return JButton.class; 364 case COMMENTCOL: 365 return JComboBox.class; 366 default: 367 return null; 368 } 369 } 370 371 @Override 372 public boolean isCellEditable(int row, int col) { 373 switch (col) { 374 case COMMENTCOL: 375 return true; 376 case ADDTOROSTERCOL: 377 jmri.jmrix.ecos.EcosLocoAddress b = getByEcosObject(ecosObjectIdList.get(row)); 378 if (b.getRosterId() == null || b.getRosterId().equals("")) { 379 return true; 380 } else { 381 return false; 382 } 383 case USERNAMECOL: 384 case DELETECOL: 385 case STOP: 386 return true; 387 default: 388 return false; 389 } 390 } 391 392 @edu.umd.cs.findbugs.annotations.SuppressFBWarnings(value = "DB_DUPLICATE_SWITCH_CLAUSES", 393 justification="better to keep cases in column order rather than to combine") 394 @Override 395 public int getPreferredWidth(int col) { 396 switch (col) { 397 case SYSNAMECOL: 398 return new JTextField(5).getPreferredSize().width; 399 case COMMENTCOL: 400 return new JTextField(20).getPreferredSize().width; 401 case USERNAMECOL: 402 return new JTextField(20).getPreferredSize().width; 403 case ADDTOROSTERCOL: // not actually used due to the configureTable, setColumnToHoldButton, configureButton 404 return new JTextField(12).getPreferredSize().width; 405 case STOP: // not actually used due to the configureTable, setColumnToHoldButton, configureButton 406 return new JTextField(6).getPreferredSize().width; 407 case VALUECOL: 408 return new JTextField(5).getPreferredSize().width; 409 case SPEEDDIR: 410 return new JTextField(10).getPreferredSize().width; 411 case PROTOCOL: 412 return new JTextField(5).getPreferredSize().width; 413 default: 414 //log.warn("Unexpected column in getPreferredWidth: "+col); 415 return super.getPreferredWidth(col); 416 //return new JTextField(8).getPreferredSize().width; 417 } 418 } 419 420 @Override 421 public void configureTable(JTable tbl) { 422 table = tbl; 423 setColumnToHoldButton(table, ADDTOROSTERCOL, 424 new JButton(Bundle.getMessage("ButtonAddRoster"))); 425 setColumnToHoldButton(table, STOP, stopButton()); 426 super.configureTable(table); 427 XTableColumnModel columnModel = (XTableColumnModel) table.getColumnModel(); 428 TableColumn column = columnModel.getColumnByModelIndex(SPEEDDIR); 429 columnModel.setColumnVisible(column, false); 430 column = columnModel.getColumnByModelIndex(STOP); 431 columnModel.setColumnVisible(column, false); 432 } 433 434 @Override 435 public NamedBean getBySystemName(@Nonnull String name) { 436 return null; 437 } 438 439 @Override 440 public NamedBean getByUserName(@Nonnull String name) { 441 return null; 442 } 443 444 @Override 445 synchronized public void dispose() { 446 showLocoMonitor = false; 447 getManager().removePropertyChangeListener(this); 448 if (ecosObjectIdList != null) { 449 for (int i = 0; i < ecosObjectIdList.size(); i++) { 450 jmri.jmrix.ecos.EcosLocoAddress b = getByEcosObject(ecosObjectIdList.get(i)); 451 if (b != null) { 452 b.removePropertyChangeListener(this); 453 } 454 } 455 } 456 } 457 458 protected void deleteLoco(final int row, int col) { 459 if (row >= ecosObjectIdList.size()) { 460 log.debug("row is greater than list size"); 461 return; 462 } 463 jmri.jmrix.ecos.EcosLocoAddress b = getByEcosObject(ecosObjectIdList.get(row)); 464 final JDialog dialog = new JDialog(); 465 dialog.setTitle(Bundle.getMessage("RemoveLocoTitle")); 466 dialog.setLocation(300, 200); 467 dialog.setDefaultCloseOperation(javax.swing.JFrame.DISPOSE_ON_CLOSE); 468 JPanel container = new JPanel(); 469 container.setLayout(new BoxLayout(container, BoxLayout.Y_AXIS)); 470 container.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); 471 472 JLabel question = new JLabel(Bundle.getMessage("RemoveLocoXDialog", b.getEcosDescription())); 473 question.setAlignmentX(Component.CENTER_ALIGNMENT); 474 container.add(question); 475 JButton yesButton = new JButton(Bundle.getMessage("ButtonYes")); 476 JButton noButton = new JButton(Bundle.getMessage("ButtonNo")); 477 JPanel button = new JPanel(); 478 button.setAlignmentX(Component.CENTER_ALIGNMENT); 479 button.add(yesButton); 480 button.add(noButton); 481 container.add(button); 482 483 noButton.addActionListener(new ActionListener() { 484 @Override 485 public void actionPerformed(ActionEvent e) { 486 dialog.dispose(); 487 } 488 }); 489 490 yesButton.addActionListener(new ActionListener() { 491 @Override 492 public void actionPerformed(ActionEvent e) { 493 RemoveObjectFromEcos removeObjectFromEcos = new RemoveObjectFromEcos(); 494 removeObjectFromEcos.removeObjectFromEcos(ecosObjectIdList.get(row), adaptermemo.getTrafficController()); 495 dialog.dispose(); 496 } 497 }); 498 container.setAlignmentX(Component.CENTER_ALIGNMENT); 499 container.setAlignmentY(Component.CENTER_ALIGNMENT); 500 dialog.getContentPane().add(container); 501 dialog.pack(); 502 dialog.setModal(true); 503 dialog.setVisible(true); 504 } 505 506 @Override 507 public int getRowCount() { 508 return ecosObjectIdList.size(); 509 } 510 511 @Override 512 public Object getValueAt(int row, int col) { 513 if (row >= ecosObjectIdList.size()) { 514 log.debug("row is greater than list size"); 515 return null; 516 517 } 518 jmri.jmrix.ecos.EcosLocoAddress b; 519 switch (col) { 520 case SYSNAMECOL: 521 return ecosObjectIdList.get(row); 522 case USERNAMECOL: // return user name 523 // sometimes, the TableSorter invokes this on rows that no longer exist, so we check 524 b = getByEcosObject(ecosObjectIdList.get(row)); 525 return (b != null) ? b.getEcosDescription() : null; 526 case VALUECOL: // 527 b = getByEcosObject(ecosObjectIdList.get(row)); 528 return (b != null) ? b.getNumber() : null; 529 case COMMENTCOL: 530 b = getByEcosObject(ecosObjectIdList.get(row)); 531 RosterEntry re = null; 532 if (b != null) { 533 re = Roster.getDefault().getEntryForId(b.getRosterId()); 534 } 535 GlobalRosterEntryComboBox cb = (GlobalRosterEntryComboBox) table.getCellRenderer(row, col); 536 if (re == null) { 537 cb.setSelectedIndex(0); 538 } else { 539 cb.setSelectedItem(re); 540 } 541 return re; 542 case PROTOCOL: 543 b = getByEcosObject(ecosObjectIdList.get(row)); 544 return (b != null) ? b.getECOSProtocol() : null; 545 case ADDTOROSTERCOL: // 546 b = getByEcosObject(ecosObjectIdList.get(row)); 547 if (b.getRosterId() == null || b.getRosterId().equals("")) { 548 return Bundle.getMessage("ButtonAddRoster"); 549 } else { 550 return " "; 551 } 552 case STOP: 553 return Bundle.getMessage("ButtonStop"); 554 case SPEEDDIR: 555 b = getByEcosObject(ecosObjectIdList.get(row)); 556 return (b != null) ? (b.getDirectionAsString() + " : " + b.getSpeed()) : null; 557 case DELETECOL: // 558 return Bundle.getMessage("ButtonDelete"); 559 default: 560 //log.error("internal state inconsistent with table requst for "+row+" "+col); 561 return null; 562 } 563 } 564 565 @Override 566 protected String getBeanType() { 567 return Bundle.getMessage("EcosLocoTitle"); 568 } 569 570 @Override 571 protected void showPopup(JmriMouseEvent e) { 572 573 } 574 }; 575 } 576 577 boolean showLocoMonitor = false; 578 579 void showMonitorChanged() { 580 showLocoMonitor = showMonitorLoco.isSelected(); 581 XTableColumnModel columnModel = (XTableColumnModel) table.getColumnModel(); 582 TableColumn column = columnModel.getColumnByModelIndex(SPEEDDIR); 583 columnModel.setColumnVisible(column, showLocoMonitor); 584 column = columnModel.getColumnByModelIndex(STOP); 585 columnModel.setColumnVisible(column, showLocoMonitor); 586 } 587 588 JCheckBox showMonitorLoco = new JCheckBox("Monitor Loco Speed"); 589 590 /** 591 * Create a JButton to edit a turnout operation. 592 * 593 * @return the JButton 594 */ 595 protected JButton stopButton() { 596 JButton stopButton = new JButton("STOP"); 597 return (stopButton); 598 } 599 600 void stopLoco(int row, int col) { 601 602 String objectNumber = ecosObjectIdList.get(row); 603 EcosMessage msg; 604 //We will repeat this three times to make sure it gets through. 605 for (int x = 0; x < 3; x++) { 606 msg = new EcosMessage("request(" + objectNumber + ", control, force)"); 607 adaptermemo.getTrafficController().sendEcosMessage(msg, null); 608 msg = new EcosMessage("set(" + objectNumber + ", stop)"); 609 adaptermemo.getTrafficController().sendEcosMessage(msg, null); 610 msg = new EcosMessage("release(" + objectNumber + ", control)"); 611 adaptermemo.getTrafficController().sendEcosMessage(msg, null); 612 } 613 } 614 615 public void addToPanel(EcosLocoTableTabAction f) { 616 f.addToBottomBox(showMonitorLoco, adaptermemo.getUserName()); 617 showMonitorLoco.setToolTipText("Show extra columns for configuring turnout feedback?"); 618 showMonitorLoco.addActionListener(new ActionListener() { 619 @Override 620 public void actionPerformed(ActionEvent e) { 621 showMonitorChanged(); 622 } 623 }); 624 } 625 626 void addToRoster(int row, int col) { 627 if (getByEcosObject(ecosObjectIdList.get(row)).getRosterId() == null) { 628 EcosLocoToRoster addLoco = new EcosLocoToRoster(adaptermemo); 629 getByEcosObject(ecosObjectIdList.get(row)).allowAddToRoster(); 630 addLoco.addToQueue(getByEcosObject(ecosObjectIdList.get(row))); 631 addLoco.processQueue(); 632 m.fireTableRowsUpdated(row, row); 633 } 634 } 635 636 @Override 637 protected void setTitle() { 638 if (adaptermemo != null) { 639 f.setTitle(Bundle.getMessage("XLocoTableTitle", adaptermemo.getUserName())); 640 } 641 f.setTitle(Bundle.getMessage("EcosLocoTableTitle")); 642 } 643 644 @Override 645 protected String helpTarget() { 646 return "package.jmri.jmrix.ecos.swing.locodatabase.EcosLocoTable"; // very simple help page 647 } 648 649 static class RosterBoxRenderer extends GlobalRosterEntryComboBox implements TableCellRenderer { 650 651 public RosterBoxRenderer(RosterEntry re) { 652 super(); 653 setNonSelectedItem(" "); 654 if (re == null) { 655 setSelectedIndex(0); 656 } else { 657 setSelectedItem(re); 658 } 659 } 660 661 @Override 662 public Component getTableCellRendererComponent(JTable table, Object value, 663 boolean isSelected, boolean hasFocus, int row, int column) { 664 if (isSelected) { 665 setForeground(table.getSelectionForeground()); 666 super.setBackground(table.getSelectionBackground()); 667 } else { 668 setForeground(table.getForeground()); 669 setBackground(table.getBackground()); 670 } 671 if (value == null) { 672 setSelectedIndex(0); 673 } else { 674 setSelectedItem(value); 675 } 676 return this; 677 } 678 } 679 680 static class RosterComboBoxEditor extends DefaultCellEditor { 681 682 public RosterComboBoxEditor(GlobalRosterEntryComboBox cb) { 683 super(cb); 684 } 685 } 686 687 @Override 688 protected void addPressed(ActionEvent e) { 689 } 690 691 @Override 692 protected String getClassName() { 693 return EcosLocoTableAction.class.getName(); 694 } 695 696 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(EcosLocoTableAction.class); 697 698}