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