001package jmri.jmrix.can.cbus.swing.nodeconfig; 002 003import java.awt.BorderLayout; 004import java.awt.Component; 005import java.awt.Dimension; 006import java.text.DateFormat; 007import java.text.SimpleDateFormat; 008import javax.swing.*; 009import javax.swing.event.TableModelEvent; 010import javax.swing.table.TableCellRenderer; 011import javax.swing.table.TableRowSorter; 012import jmri.jmrix.can.CanSystemConnectionMemo; 013import jmri.jmrix.can.cbus.CbusConfigurationManager; 014import jmri.jmrix.can.cbus.node.CbusNodeTableDataModel; 015import jmri.jmrix.can.cbus.swing.CbusCommonSwing; 016import jmri.util.ThreadingUtil; 017import jmri.util.swing.XTableColumnModel; 018import jmri.util.table.*; 019 020// import org.slf4j.Logger; 021// import org.slf4j.LoggerFactory; 022 023/** 024 * Pane providing a CBUS node table. 025 * 026 * @author Steve Young (C) 2019 027 * @see CbusNodeTableDataModel 028 * 029 * @since 2.99.2 030 */ 031public class CbusNodeTablePane extends JPanel { 032 033 private CbusNodeTableDataModel nodeModel; 034 protected JTable nodeTable; 035 036 private TableRowSorter<CbusNodeTableDataModel> sorter; 037 038 private final DateFormat DATE_FORMAT = new SimpleDateFormat("HH:mm EEE d MMM"); 039 040 public void initComponents(CanSystemConnectionMemo memo) { 041 nodeModel = memo.get(CbusConfigurationManager.class) 042 .provide(CbusNodeTableDataModel.class); 043 044 init(); 045 046 } 047 048 public CbusNodeTablePane() { 049 super(); 050 } 051 052 public void init() { 053 054 nodeTable = new JTableWithColumnToolTips(nodeModel,CbusNodeTableDataModel.COLUMNTOOLTIPS){ 055 056 @Override 057 public Component prepareRenderer(TableCellRenderer renderer, int row, int column) { 058 int modelRow = convertRowIndexToModel(row); 059 int modelColumn = convertColumnIndexToModel(column); 060 Component comp = super.prepareRenderer(renderer, row, column); 061 if (!isRowSelected(modelRow) && 062 ( modelColumn == CbusNodeTableDataModel.NODE_IN_LEARN_MODE_COLUMN 063 || modelColumn == CbusNodeTableDataModel.NODE_EVENT_INDEX_VALID_COLUMN 064 )) { 065 comp.setBackground(( row % 2 == 0 ) ? this.getBackground() : jmri.jmrix.can.cbus.swing.CbusCommonSwing.WHITE_GREEN ); 066 } 067 return comp; 068 } 069 }; 070 071 // Use XTableColumnModel so we can control which columns are visible 072 XTableColumnModel tcm = new XTableColumnModel(); 073 nodeTable.setColumnModel(tcm); 074 075 sorter = new TableRowSorter<>(nodeModel); 076 nodeTable.setRowSorter(sorter); 077 078 // configure items for GUI 079 CbusCommonSwing.configureTable(nodeTable); 080 081 tcm.getColumn(CbusNodeTableDataModel.NODE_NUMBER_COLUMN).setCellRenderer(getRenderer()); 082 tcm.getColumn(CbusNodeTableDataModel.NODE_TYPE_NAME_COLUMN).setCellRenderer(getRenderer()); 083 tcm.getColumn(CbusNodeTableDataModel.NODE_USER_NAME_COLUMN).setCellRenderer(getRenderer()); 084 tcm.getColumn(CbusNodeTableDataModel.NODE_EVENTS_COLUMN).setCellRenderer(getRenderer()); 085 tcm.getColumn(CbusNodeTableDataModel.COMMAND_STAT_NUMBER_COLUMN).setCellRenderer(getRenderer()); 086 tcm.getColumn(CbusNodeTableDataModel.CANID_COLUMN).setCellRenderer(getRenderer()); 087 tcm.getColumn(CbusNodeTableDataModel.NODE_TOTAL_BYTES_COLUMN).setCellRenderer(getRenderer()); 088 tcm.getColumn(CbusNodeTableDataModel.BYTES_REMAINING_COLUMN).setCellRenderer(new ProgressCellRender(CbusCommonSwing.WHITE_GREEN)); 089 tcm.getColumn(CbusNodeTableDataModel.NUMBER_BACKUPS_COLUMN).setCellRenderer(getRenderer()); 090 tcm.getColumn(CbusNodeTableDataModel.SESSION_BACKUP_STATUS_COLUMN).setCellRenderer(getRenderer()); 091 tcm.getColumn(CbusNodeTableDataModel.LAST_BACKUP_COLUMN).setCellRenderer(getRenderer()); 092 093 tcm.getColumn(CbusNodeTableDataModel.NODE_RESYNC_BUTTON_COLUMN).setCellEditor(new ButtonEditor(new JButton())); 094 tcm.getColumn(CbusNodeTableDataModel.NODE_RESYNC_BUTTON_COLUMN).setCellRenderer(new ButtonRenderer()); 095 096 tcm.getColumn(CbusNodeTableDataModel.NODE_EDIT_BUTTON_COLUMN).setCellEditor(new ButtonEditor(new JButton())); 097 tcm.getColumn(CbusNodeTableDataModel.NODE_EDIT_BUTTON_COLUMN).setCellRenderer(new ButtonRenderer()); 098 099 ((JComponent) tcm.getColumn(CbusNodeTableDataModel.NODE_RESYNC_BUTTON_COLUMN).getCellRenderer()).setOpaque(false); 100 ((JComponent) tcm.getColumn(CbusNodeTableDataModel.NODE_EDIT_BUTTON_COLUMN).getCellRenderer()).setOpaque(false); 101 102 setLayout(new BorderLayout()); 103 JScrollPane eventScroll = new JScrollPane(nodeTable); 104 eventScroll.setVisible(true); 105 eventScroll.setPreferredSize(new Dimension(300, 40)); 106 add(eventScroll); 107 108 validate(); 109 repaint(); 110 111 nodeModel.addTableModelListener((TableModelEvent e) -> { 112 if (nodeModel.getRequestNodeRowToDisplay()>-1) { 113 setRowToNode(); 114 } 115 }); 116 nodeModel.fireTableDataChanged(); 117 } 118 119 private void setRowToNode(){ 120 ThreadingUtil.runOnGUIEventually(() -> { 121 int newRow = nodeModel.getRequestNodeRowToDisplay(); 122 if ( newRow>-1 ) { 123 nodeTable.setRowSelectionInterval(newRow, newRow); 124 nodeTable.scrollRectToVisible(nodeTable.getCellRect(newRow, 0, true)); 125 nodeModel.setRequestNodeDisplay(-1); 126 } 127 }); 128 } 129 130 /** 131 * Cell Renderer for string table columns 132 */ 133 private TableCellRenderer getRenderer() { 134 return new TableCellRenderer() { 135 JTextField f = new JTextField(); 136 137 @Override 138 public Component getTableCellRendererComponent( 139 JTable table, Object arg1, boolean isSelected, boolean hasFocus, 140 int row, int col) { 141 String string; 142 if(arg1 != null){ 143 string = arg1.toString(); 144 f.setText(string); 145 f.setHorizontalAlignment(JTextField.CENTER); 146 CbusCommonSwing.hideNumbersLessThan(0, string, f); 147 CbusCommonSwing.setCellFromDate(arg1,f,DATE_FORMAT); 148 CbusCommonSwing.setCellFromBackupEnum(arg1,f); 149 150 } else { 151 f.setText(""); 152 } 153 154 CbusCommonSwing.setCellBackground(isSelected, f, table,row); 155 CbusCommonSwing.setCellFocus(hasFocus, f, table); 156 157 return f; 158 } 159 }; 160 } 161 162 public void dispose() { 163 nodeTable = null; 164 } 165 166 // private final static Logger log = LoggerFactory.getLogger(CbusNodeTablePane.class); 167 168}