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