001package jmri.jmrix.can.cbus.swing.nodeconfig;
002
003import java.awt.BorderLayout;
004import java.awt.Component;
005import javax.swing.*;
006import javax.swing.table.TableCellRenderer;
007import javax.swing.table.TableColumn;
008import javax.swing.table.TableColumnModel;
009import javax.swing.table.TableRowSorter;
010import jmri.jmrix.can.cbus.node.CbusNode;
011import jmri.jmrix.can.cbus.node.CbusNodeEventTableDataModel;
012import jmri.jmrix.can.cbus.swing.CbusTableRowEventDnDHandler;
013import jmri.jmrix.can.cbus.swing.CbusCommonSwing;
014import jmri.util.table.ButtonEditor;
015import jmri.util.table.ButtonRenderer;
016
017/**
018 * Pane providing a CBUS Node Event table for a single node.
019 *
020 * @author Steve Young (C) 2019
021 * @see CbusNodeEventTableDataModel
022 *
023 * @since 4.15.5
024 */
025public class CbusNodeEventTablePane extends jmri.jmrix.can.swing.CanPanel {
026
027    private final CbusNodeEventTableDataModel nodeEventModel;
028    private JScrollPane eventVarScroll;
029    private JPanel pane1;
030    private JTable nodeEventTable;
031    private TableRowSorter<CbusNodeEventTableDataModel> sorter;
032    private CbusTableRowEventDnDHandler eventDragHandler;
033    
034    /**
035     * Create a new CBUS Node Event Table Pane
036     * @param model the Table Model to use
037     */
038    public CbusNodeEventTablePane( CbusNodeEventTableDataModel model ) {
039        super();
040        nodeEventModel = model;
041        nodeEventTable = new JTable(nodeEventModel);
042    }
043    
044    /**
045     * Set the Node
046     * @param node the CBUS Node Events to display
047     */
048    public void setNode( CbusNode node) {
049        
050        if (node == null && pane1!=null){ 
051            pane1.setVisible(false);
052            return;
053        }
054        nodeEventModel.setNode(node);
055        nodeEventTable = new JTable(nodeEventModel);
056        init();
057    }
058
059    public void init() {
060        
061        if (pane1 != null ){ 
062            pane1.setVisible(false);
063        }
064        
065        pane1 = null;
066        
067        if ( nodeEventTable == null ){
068            return;
069        }
070        
071        TableColumnModel tcm = nodeEventTable.getColumnModel();
072        
073        sorter = null;
074        
075        if (nodeEventModel.getRowCount() > 0 ) {
076            nodeEventTable.setAutoCreateRowSorter(true);
077            sorter = new TableRowSorter<>(nodeEventModel);
078            nodeEventTable.setRowSorter(sorter);
079        }
080        
081        // configure items for GUI
082        CbusCommonSwing.configureTable(nodeEventTable);
083        
084        setColumnRenderers(tcm);
085        
086        pane1 = new JPanel();
087        
088        setLayout(new BorderLayout() );
089        pane1.setLayout(new BorderLayout());
090        
091        // scroller for main table
092        eventVarScroll = new JScrollPane(nodeEventTable);
093
094        pane1.add(eventVarScroll);
095        
096        add(pane1);
097        pane1.setVisible(true);
098        
099        nodeEventTable.setDragEnabled(true);
100        nodeEventTable.setDropMode(DropMode.ON);
101        eventDragHandler = new CbusTableRowEventDnDHandler(this.memo, nodeEventTable);
102        nodeEventTable.setTransferHandler(eventDragHandler);
103        
104    }
105    
106    private void setColumnRenderers(TableColumnModel tcm){
107    
108        for (int i = 0; i < CbusNodeEventTableDataModel.MAX_COLUMN; i++) {
109            if ( CbusNodeEventTableDataModel.NODE_EDIT_BUTTON_COLUMN == i){
110                tcm.getColumn(i).setCellEditor(new ButtonEditor(new JButton()));
111                tcm.getColumn(i).setCellRenderer(new ButtonRenderer());
112            } else {
113                tcm.getColumn(i).setCellRenderer(getRenderer());
114            }
115        }
116
117        if ( hideEditButton ) {
118            TableColumn delBColumn = tcm.getColumn(CbusNodeEventTableDataModel.NODE_EDIT_BUTTON_COLUMN);
119            delBColumn.setMinWidth(0);
120            delBColumn.setMaxWidth(0);
121            delBColumn.setWidth(0);
122            
123            // if not editable, index column also invalid
124            delBColumn = tcm.getColumn(CbusNodeEventTableDataModel.EV_INDEX_COLUMN);
125            delBColumn.setMinWidth(0);
126            delBColumn.setMaxWidth(0);
127            delBColumn.setWidth(0);
128        }
129    
130    }
131    
132    private boolean hideEditButton = false;
133    
134    protected void setHideEditButton(){
135        hideEditButton = true;
136    }
137    
138    /**
139     * Cell Renderer for string table columns, highlights any text in filter input
140     */    
141    private TableCellRenderer getRenderer() {
142        return new TableCellRenderer() {
143            
144            JTextField f = new JTextField();
145            
146            /** {@inheritDoc} */
147            @Override
148            public Component getTableCellRendererComponent(
149                JTable table, Object arg1, boolean isSelected, boolean hasFocus, 
150                int row, int col) {
151                
152                f.setHorizontalAlignment(JTextField.CENTER);
153                f.setBorder( table.getBorder() );
154                
155                String string;
156                if(arg1 != null){
157                    string = arg1.toString();
158                    f.setText(string);
159                    CbusCommonSwing.hideNumbersLessThan(0, string, f);
160                    
161                } else {
162                    f.setText("");
163                }
164                
165                CbusCommonSwing.setCellBackground(isSelected, f, table,row);
166                CbusCommonSwing.setCellFocus(hasFocus, f, table);
167                
168                return f;
169            }
170        };
171    }
172
173    /**
174     * Only used for testing.
175     * {@inheritDoc}
176     */
177    @Override
178    public String getTitle() {
179        return prependConnToString(Bundle.getMessage("MenuItemEventTable"));
180    }
181    
182    /**
183     * {@inheritDoc}
184     */
185    @Override
186    public void dispose() {
187        eventDragHandler.dispose();
188        eventVarScroll = null;
189    }
190
191 //   private final static Logger log = LoggerFactory.getLogger(CbusNodeEventTablePane.class);
192
193}