001package jmri.jmrix.can.cbus.swing.cbusslotmonitor;
002
003import java.awt.BorderLayout;
004import java.awt.Dimension;
005import java.awt.event.ActionEvent;
006import java.util.ArrayList;
007import java.util.Arrays;
008import java.util.List;
009import javax.swing.*;
010import javax.swing.table.TableColumn;
011import javax.swing.table.TableRowSorter;
012import jmri.InstanceManager;
013import jmri.jmrit.catalog.NamedIcon;
014import jmri.jmrit.throttle.LargePowerManagerButton;
015import jmri.jmrix.can.CanSystemConnectionMemo;
016import jmri.jmrix.can.cbus.swing.CbusCommonSwing;
017import jmri.swing.JmriJTablePersistenceManager;
018import jmri.util.swing.StayOpenCheckBoxItem;
019import jmri.util.swing.XTableColumnModel;
020import jmri.util.table.ButtonEditor;
021import jmri.util.table.ButtonRenderer;
022import jmri.util.table.JTableWithColumnToolTips;
023
024// import org.slf4j.Logger;
025// import org.slf4j.LoggerFactory;
026
027/**
028 * Pane for monitoring and configuring a MERG CBUS Command Station.
029 *
030 * @author Steve Young Copyright (C) 2018
031 * @since 4.13.4
032 */
033public class CbusSlotMonitorPane extends jmri.jmrix.can.swing.CanPanel {
034
035    private JScrollPane scrolltablefeedback;
036    private JSplitPane split;
037    private final double _splitratio = 0.95;
038    private JScrollPane slotScroll;
039    
040    protected CbusSlotMonitorDataModel slotModel;
041    private JTable _slotTable;
042    private final XTableColumnModel tcm = new XTableColumnModel();
043    private final JMenu colMenu = new JMenu((Bundle.getMessage("SessCol")));
044    
045    // private JMenu cancmdMenu = new JMenu("CANCMD Setup");
046    
047    public CbusSlotMonitorPane() {
048        super();
049    }
050    
051    @Override
052    public void initComponents(CanSystemConnectionMemo memo) {
053        super.initComponents(memo);
054        slotModel = new CbusSlotMonitorDataModel(memo);
055        _slotTable = new JTableWithColumnToolTips(slotModel,CbusSlotMonitorDataModel.CBUSSLOTMONTOOLTIPS);
056        init();
057    }
058
059    public void init() {
060        
061        // Use XTableColumnModel so we can control which columns are visible
062        _slotTable.setColumnModel(tcm);
063        
064        setupColumnsMenuLinks();
065        
066        final TableRowSorter<CbusSlotMonitorDataModel> sorter = new TableRowSorter<>(slotModel);
067        _slotTable.setRowSorter(sorter);
068        
069        TableColumn estopColumn = tcm.getColumnByModelIndex(CbusSlotMonitorDataModel.ESTOP_COLUMN);                
070        estopColumn.setMinWidth(60);
071        estopColumn.setCellRenderer( new ButtonRenderer() );
072        estopColumn.setCellEditor( new ButtonEditor( new JButton() ) );    
073
074        slotScroll = new JScrollPane(_slotTable);
075        slotScroll.setPreferredSize(new Dimension(400, 200));
076        
077        this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
078
079        scrolltablefeedback = new JScrollPane (slotModel.tablefeedback());
080        scrolltablefeedback.setMinimumSize(new Dimension(150, 20));
081        
082        JPanel toppanelcontainer = new JPanel();
083        toppanelcontainer.setLayout(new BoxLayout(toppanelcontainer, BoxLayout.X_AXIS));
084        toppanelcontainer.add(getStopButton());
085        toppanelcontainer.add(new LargePowerManagerButton(true));
086        
087        split = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
088            slotScroll, scrolltablefeedback);
089        split.setResizeWeight(_splitratio);
090        split.setContinuousLayout(true);
091
092        JPanel p1 = new JPanel();
093        p1.setLayout(new BorderLayout());
094        
095        p1.add(toppanelcontainer, BorderLayout.PAGE_START);
096        p1.add(split, BorderLayout.CENTER);        
097        add(p1);
098        
099        p1.setMinimumSize(new Dimension(450, 200));
100        p1.setVisible(true);
101    }
102    
103    private JButton getStopButton(){
104        JButton estopButton = new JButton("Stop All");
105        estopButton.setIcon(new NamedIcon("resources/icons/throttles/estop.png", "resources/icons/throttles/estop.png"));
106        estopButton.setToolTipText(Bundle.getMessage("ThrottleToolBarStopAllToolTip"));
107        estopButton.addActionListener((ActionEvent e) -> {
108            slotModel.sendcbusestop();
109        });
110        return estopButton;
111    }
112    
113    private void setupColumnsMenuLinks() {
114        
115        // configure items for GUI
116        CbusCommonSwing.configureTable(_slotTable);
117        
118        StayOpenCheckBoxItem[] cbArray = new StayOpenCheckBoxItem[slotModel.getColumnCount()];
119        
120        // initialise and set default column visibiity
121        for (int i = 0; i < slotModel.getColumnCount(); i++) {
122            StayOpenCheckBoxItem cbi = new StayOpenCheckBoxItem(slotModel.getColumnName(i));
123            cbArray[i] = cbi;
124            TableColumn column  = tcm.getColumnByModelIndex(i);
125            cbi.addActionListener((ActionEvent e) -> {
126                tcm.setColumnVisible(column, cbi.isSelected());
127            });
128            final int ii = i;
129            tcm.setColumnVisible(tcm.getColumnByModelIndex(i),
130                Arrays.stream(CbusSlotMonitorDataModel.CBUSSLOTMONINITIALCOLS).anyMatch(j -> j == ii)
131                );
132            
133        }
134        
135        InstanceManager.getOptionalDefault(JmriJTablePersistenceManager.class).ifPresent((tpm) -> {
136            tpm.persist(_slotTable, true);
137        });
138        
139        
140        for (int i = 0; i < slotModel.getColumnCount(); i++) {
141            cbArray[i].setSelected(tcm.isColumnVisible(tcm.getColumnByModelIndex(i)));
142            colMenu.add(cbArray[i]); // count columns
143        }
144        
145    }
146    
147    /**
148     * {@inheritDoc}
149     */
150    @Override
151    public String getTitle() {
152        return prependConnToString(Bundle.getMessage("MenuItemCbusSlotMonitor"));
153    }
154
155    /**
156     * Creates a Menu List.
157     * {@inheritDoc}
158     */
159    @Override
160    public List<JMenu> getMenus() {
161        List<JMenu> menuList = new ArrayList<>();
162        menuList.add(colMenu);
163        return menuList;
164    }
165
166    /**
167     * {@inheritDoc}
168     */
169    @Override
170    public String getHelpTarget() {
171        return "package.jmri.jmrix.can.cbus.swing.cbusslotmonitor.CbusSlotMonitorPane";
172    }    
173    
174    /**
175     * {@inheritDoc}
176     */
177    @Override
178    public void dispose() {
179        InstanceManager.getOptionalDefault(JmriJTablePersistenceManager.class).ifPresent((tpm) -> {
180            tpm.stopPersisting(_slotTable);
181        });
182        _slotTable = null;
183        slotModel.dispose();
184        super.dispose();
185    }
186
187    /**
188     * Nested class to create one of these using old-style defaults
189     */
190    static public class Default extends jmri.jmrix.can.swing.CanNamedPaneAction {
191
192        public Default() {
193            super(Bundle.getMessage("MenuItemCbusSlotMonitor"),
194                    new jmri.util.swing.sdi.JmriJFrameInterface(),
195                    CbusSlotMonitorPane.class.getName(),
196                    jmri.InstanceManager.getDefault(CanSystemConnectionMemo.class));
197        }
198    }
199
200    // private static final Logger log = LoggerFactory.getLogger(CbusSlotMonitorPane.class);
201
202}