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