001package jmri.jmrix.cmri.serial.cmrinetmanager;
002
003import java.awt.*;
004import java.awt.event.ActionEvent;
005import java.util.ArrayList;
006import javax.swing.*;
007import javax.swing.border.Border;
008import javax.swing.border.TitledBorder;
009import javax.swing.table.*;
010import jmri.jmrix.cmri.CMRISystemConnectionMemo;
011import jmri.jmrix.cmri.serial.SerialNode;
012import jmri.jmrix.cmri.serial.SerialTrafficController;
013import jmri.jmrix.cmri.serial.serialmon.*;
014
015/**
016 * Frame for a table view to manage a CMRInet network.
017 * @author  Chuck Catania   Copyright (C) 2014, 2015, 2016, 2017
018 */
019public class CMRInetManagerFrame extends jmri.util.JmriJFrame {
020
021    ArrayList<SerialNode> cmriNode = new  ArrayList<SerialNode>();  //c2
022
023    // poll list node information
024    protected boolean inputSelected = false;  // true if displaying input assignments, false for output
025    protected SerialNode selNode = null;
026    protected String selNodeID = "x"; // text address of selected Node
027    public int selNodeNum = 0;  // Address (ua) of selected Node
028
029    protected int selectedNodeAddr = -1;  //c2
030
031    // node table pane items
032    protected JPanel pollListPanel = null;
033    protected Border pollListBorder = BorderFactory.createEtchedBorder();
034
035    protected JTable nodeTable = null;
036    protected TableModel nodeTableModel = null;
037
038    protected JPanel CMRInetParams = new JPanel();
039
040    // button pane items
041    JButton monitorButton = new JButton(Bundle.getMessage("MonitorButtonText") );
042    JButton doneButton = new JButton(Bundle.getMessage("DoneButtonText") );
043    JButton haltPollButton = new JButton(Bundle.getMessage("HaltPollButtonText") );
044    JButton netStatsButton = new JButton(Bundle.getMessage("NetStatsButtonText") );
045
046    private CMRISystemConnectionMemo _memo = null;
047
048    public CMRInetManagerFrame(CMRISystemConnectionMemo memo) {
049        super();
050        _memo = memo;
051    }
052
053    protected javax.swing.JTextField pollIntervalField = new javax.swing.JTextField();
054
055    /**
056     * {@inheritDoc}
057     */
058    @Override
059    public void initComponents() {
060        initializeNodes();
061
062        // set the frame's initial state
063        setTitle(Bundle.getMessage("WindowTitle") + " - Connection " + _memo.getUserName());
064        setSize(1200, 300);
065
066        Container contentPane = getContentPane();
067        contentPane.setLayout(new FlowLayout());
068
069        // Set up the poll list panel
070        pollListPanel = new JPanel();
071        pollListPanel.setLayout(new BoxLayout(pollListPanel, BoxLayout.Y_AXIS));
072
073        nodeTableModel = new NodeTableModel();
074        nodeTable = new JTable(nodeTableModel);
075
076        nodeTable.setShowGrid(true);
077        nodeTable.setGridColor(Color.black);
078        nodeTable.setRowSelectionAllowed(false);
079        nodeTable.setFont(new Font("Lucida Grande", Font.PLAIN, 13));
080        nodeTable.setPreferredScrollableViewportSize(new java.awt.Dimension(300, 350));
081        nodeTable.setRowHeight(30);
082        nodeTable.getTableHeader().setReorderingAllowed(false);
083        TableColumnModel pollListColumnModel = nodeTable.getColumnModel();
084
085        DefaultTableCellRenderer dtcen = new DefaultTableCellRenderer();
086        dtcen.setHorizontalAlignment(SwingConstants.CENTER);
087        DefaultTableCellRenderer dtlft = new DefaultTableCellRenderer();
088        dtlft.setHorizontalAlignment(SwingConstants.LEFT);
089
090        TableCellRenderer rendererFromHeader = nodeTable.getTableHeader().getDefaultRenderer();
091        JLabel headerLabel = (JLabel) rendererFromHeader;
092        headerLabel.setHorizontalAlignment(JLabel.CENTER);
093
094        TableColumn pollseqColumn = pollListColumnModel.getColumn(NodeTableModel.POLLSEQ_COLUMN);
095        pollseqColumn.setMinWidth(40);
096        pollseqColumn.setMaxWidth(80);
097        pollseqColumn.setCellRenderer(dtcen);
098        pollseqColumn.setResizable(false);
099
100        TableColumn enabledColumn = pollListColumnModel.getColumn(NodeTableModel.ENABLED_COLUMN);
101        enabledColumn.setMinWidth(40);
102        enabledColumn.setMaxWidth(80);
103        enabledColumn.setResizable(false);
104
105        TableColumn nodenumColumn = pollListColumnModel.getColumn(NodeTableModel.NODENUM_COLUMN);
106        nodenumColumn.setMinWidth(40);
107        nodenumColumn.setMaxWidth(70);
108        nodenumColumn.setCellRenderer(dtcen);
109        nodenumColumn.setResizable(false);
110
111        TableColumn nodetypeColumn = pollListColumnModel.getColumn(NodeTableModel.NODETYPE_COLUMN);
112        nodetypeColumn.setMinWidth(40);
113        nodetypeColumn.setMaxWidth(80);
114        nodetypeColumn.setCellRenderer(dtcen);
115        nodetypeColumn.setResizable(false);
116
117        TableColumn statusColumn = pollListColumnModel.getColumn(NodeTableModel.STATUS_COLUMN);
118        statusColumn.setMinWidth(10);
119        statusColumn.setMaxWidth(80);
120        statusColumn.setCellRenderer(dtcen);
121        statusColumn.setResizable(false);
122
123        TableColumn nodedescColumn = pollListColumnModel.getColumn(NodeTableModel.NODEDESC_COLUMN);
124        nodedescColumn.setMinWidth(10);
125        nodedescColumn.setMaxWidth(350);
126        nodedescColumn.setCellRenderer(dtlft);
127        nodedescColumn.setResizable(false);
128
129        JScrollPane nodeTableScrollPane = new JScrollPane(nodeTable);
130
131        Border pollListBorderTitled = BorderFactory.createTitledBorder(pollListBorder, " ",
132                TitledBorder.LEFT, TitledBorder.ABOVE_TOP);
133        pollListPanel.add(nodeTableScrollPane, BorderLayout.EAST);
134        pollListPanel.setBorder(pollListBorderTitled);
135        // Set the scroll window size
136        setPreferredSize(new Dimension(750, 500));
137
138        nodeTable.setAutoCreateRowSorter(true);
139        nodeTable.getRowSorter().toggleSortOrder(NodeTableModel.POLLSEQ_COLUMN);
140
141        // Poll list drag and drop handler
142        nodeTable.setDragEnabled(true);
143
144        contentPane.add(pollListPanel);
145
146        CMRInetParams.add(haltPollButton);
147        contentPane.add(CMRInetParams);
148
149        Container contentPane13 = getContentPane();
150        contentPane.setLayout(new BoxLayout(contentPane13, BoxLayout.Y_AXIS));
151
152        // --------------------
153        // Setup window buttons
154        // --------------------
155        JPanel panel3 = new JPanel();
156        panel3.setLayout(new BoxLayout(panel3, BoxLayout.LINE_AXIS));
157        panel3.setPreferredSize(new Dimension(600, 45));
158
159        // --------------------------
160        // Set up Halt Polling button
161        // --------------------------
162        haltPollButton.setVisible(true);
163        haltPollButton.setToolTipText(Bundle.getMessage("HaltPollButtonTip"));
164        haltPollButton.addActionListener(new java.awt.event.ActionListener() {
165            @Override
166            public void actionPerformed(java.awt.event.ActionEvent e) {
167                haltpollButtonActionPerformed(e);
168            }
169        });
170        SerialTrafficController stc = _memo.getTrafficController();
171        if (stc.getPollNetwork()) {
172            haltPollButton.setText(Bundle.getMessage("HaltPollButtonText"));
173        } else {
174            haltPollButton.setText(Bundle.getMessage("ResumePollButtonText"));
175        }
176        panel3.add(haltPollButton);
177
178        // --------------------------
179        // Set up Open monitor button
180        // --------------------------
181        monitorButton.setVisible(true);
182        monitorButton.setToolTipText(Bundle.getMessage("MonitorButtonTip"));
183        monitorButton.addActionListener(new java.awt.event.ActionListener() {
184            @Override
185            public void actionPerformed(java.awt.event.ActionEvent e) {
186                monitorButtonActionPerformed(e);
187            }
188        });
189        panel3.add(monitorButton);
190
191        // -----------------------------
192        // Set up Network Metrics button
193        // -----------------------------
194        netStatsButton.setVisible(false);
195        netStatsButton.setToolTipText(Bundle.getMessage("NetStatsButtonTip"));
196        netStatsButton.addActionListener(new java.awt.event.ActionListener() {
197            @Override
198            public void actionPerformed(java.awt.event.ActionEvent e) {
199                netStatsButtonActionPerformed(e);
200            }
201        });
202        panel3.add(netStatsButton);
203        panel3.add(Box.createRigidArea(new Dimension(30, 0)));
204
205        // ------------------
206        // Set up Done button
207        // ------------------
208        doneButton.setVisible(true);
209        doneButton.setToolTipText(Bundle.getMessage("DoneButtonTip"));
210        doneButton.addActionListener(new java.awt.event.ActionListener() {
211            @Override
212            public void actionPerformed(java.awt.event.ActionEvent e) {
213                doneButtonActionPerformed();
214            }
215        });
216        panel3.add(doneButton);
217        contentPane13.add(panel3);
218
219        addHelpMenu("package.jmri.jmrix.cmri.serial.cmrinetmanager.CMRInetManagerFrame", true);
220
221        // pack for display
222        pack();
223
224    }
225    
226    /**
227     * Method to initialize configured nodes and set up the node select combo box
228     */
229    public void initializeNodes() {
230        // get all configured nodes
231        SerialNode node = (SerialNode) _memo.getTrafficController().getNode(0);
232        int index = 1;
233        while (node != null) {
234            cmriNode.add(node);
235            // set the polling sequence to the ordinal value in the list
236            if (cmriNode.get(index - 1).getPollListPosition() == 0) {
237                cmriNode.get(index - 1).setPollListPosition(index);
238            }
239            node = (SerialNode) _memo.getTrafficController().getNode(index);
240
241            index++;
242
243        }
244    }
245    
246    // --------------------------------------------
247    // Extract the node address from the node table
248    // --------------------------------------------
249    public int getSelectedNodeAddr() {
250        return (Integer)nodeTable.getValueAt(nodeTable.getSelectedRow(),1);
251    }
252    
253    // ----------------------------
254    // Node browser button handlers
255    // ----------------------------
256    public void doneButtonActionPerformed() {
257        setVisible(false);
258        dispose();
259    }
260    
261    // ------------------------------
262    // CMRInet Monitor button handler
263    // ------------------------------
264    public void monitorButtonActionPerformed(ActionEvent e) {
265        SerialMonAction f = new SerialMonAction(_memo);
266        try {
267            f.actionPerformed(e);
268        }
269        catch (Exception ex)
270            {
271                log.info("Exception-C2: {}", ex.toString());
272            }
273    }
274    
275    // ---------------------------------
276    // CMRInet Statistics button handler
277    // ---------------------------------
278    public void netStatsButtonActionPerformed(ActionEvent e) {
279        //        CMRInetMetricsAction f = new CMRInetMetricsAction(_memo);  **********
280        try {
281            //                f.actionPerformed(e);
282            netStatsButton.setEnabled(false);
283        }
284        catch (Exception ex)
285            {
286                log.info("Exception-C2: {}", ex.toString());
287            }
288    }
289    
290    // ------------------------
291    // Halt Poll button handler
292    // ------------------------
293    public void haltpollButtonActionPerformed(ActionEvent e) {
294        SerialTrafficController stc = _memo.getTrafficController();
295        stc.setPollNetwork(!stc.getPollNetwork());
296        if (stc.getPollNetwork())
297            haltPollButton.setText(Bundle.getMessage("HaltPollButtonText"));
298        else
299            haltPollButton.setText(Bundle.getMessage("ResumePollButtonText"));
300    }
301    
302    /**
303     * Set up table for displaying bit assignments
304     */
305    public class NodeTableModel extends AbstractTableModel {
306
307        @Override
308        public String getColumnName(int c) {
309            return pollListColumnsNames[c];
310        }
311
312        @Override
313        public Class<?> getColumnClass(int c) {
314            switch (c) {
315                case ENABLED_COLUMN:
316                    return Boolean.class;
317                case POLLSEQ_COLUMN:
318                    return Integer.class;
319                case NODENUM_COLUMN:
320                    return Integer.class;
321                default:
322                    return String.class;
323            }
324        }
325
326        @Override
327        public boolean isCellEditable(int r, int c) {
328            switch (c) {
329                case ENABLED_COLUMN:
330                    return (true);
331                default:
332            }
333
334            return (false);
335
336        }
337
338        @Override
339        public int getColumnCount() {
340            return NUM_COLUMNS;
341        }
342
343        @Override
344        public int getRowCount() {
345            return cmriNode.size();
346        }
347
348        @Override
349        public Object getValueAt(int r, int c) {
350            switch (c) {
351                case POLLSEQ_COLUMN:
352                    return cmriNode.get(r).getPollListPosition();
353
354                case ENABLED_COLUMN:
355                    if (cmriNode.get(r).getPollingEnabled()) {
356                        return true;
357                    } else {
358                        return false;
359                    }
360
361                case NODENUM_COLUMN:
362                    return cmriNode.get(r).getNodeAddress();
363
364                case NODETYPE_COLUMN:
365                    return "  " + nodeTypes[cmriNode.get(r).getNodeType()];
366
367                case STATUS_COLUMN:
368                    fireTableDataChanged();
369                    return pollStatus[cmriNode.get(r).getPollStatus()];
370
371                case NODEDESC_COLUMN:
372                    return " " + cmriNode.get(r).getcmriNodeDesc();
373
374                default:
375            }
376            return "";
377        }
378
379        @Override
380        public void setValueAt(Object value, int r, int c) {
381            switch (c) {
382                case POLLSEQ_COLUMN:
383                    cmriNode.get(r).setPollListPosition((Integer) value);
384                    fireTableDataChanged();
385
386                    break;
387                case ENABLED_COLUMN:
388                    cmriNode.get(r).setPollingEnabled(!cmriNode.get(r).getPollingEnabled());
389                    break;
390                case STATUS_COLUMN:
391                    cmriNode.get(r).setPollStatus(cmriNode.get(r).getPollStatus());
392                    break;
393                default:
394            }
395        }
396
397        public static final int POLLSEQ_COLUMN = 0;
398        public static final int ENABLED_COLUMN = 1;
399        public static final int NODENUM_COLUMN = 2;
400        public static final int NODETYPE_COLUMN = 3;
401        public static final int STATUS_COLUMN = 4;
402        public static final int NODEDESC_COLUMN = 5;
403        public static final int NUM_COLUMNS = NODEDESC_COLUMN + 1;
404
405    }
406    
407    private String[] pollListColumnsNames = {"Poll Seq", "Enabled", "Node", "Type", "Status", "Description"};
408    private String[] nodeTypes = {"--", "SMINI", "SUSIC", "CPNODE", "PiNODE"};
409    private String[] pollStatus = {"ERROR", "IDLE", "POLLING", "TIMEOUT", "INIT"};
410    
411    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(CMRInetManagerFrame.class);
412    
413}