001package jmri.jmrit.logixng.actions.swing; 002 003import java.awt.Component; 004import java.awt.event.ActionEvent; 005import java.awt.event.ActionListener; 006import java.util.*; 007 008import javax.swing.*; 009import javax.swing.table.AbstractTableModel; 010import javax.swing.table.DefaultTableCellRenderer; 011import javax.swing.table.TableCellEditor; 012 013import jmri.jmrit.logixng.SymbolTable.InitialValueType; 014import jmri.jmrit.logixng.actions.WebRequest; 015import jmri.util.swing.JComboBoxUtil; 016 017/** 018 * Table model for WebRequest 019 * 020 * @author Daniel Bergqvist Copyright 2021 021 */ 022public class WebRequestTableModel extends AbstractTableModel { 023 024 // COLUMN_DUMMY is "hidden" but used when the panel is closed to 025 // ensure that the last edited cell is saved. 026 public static final int COLUMN_NAME = 0; 027 public static final int COLUMN_TYPE = 1; 028 public static final int COLUMN_DATA = 2; 029 public static final int COLUMN_DELETE = 3; 030 public static final int COLUMN_DUMMY = 4; 031 032 private final List<WebRequest.Parameter> _parameterList = new ArrayList<>(); 033 034 035 public WebRequestTableModel(Collection<WebRequest.Parameter> namedBeanReference) { 036 if (namedBeanReference != null) _parameterList.addAll(namedBeanReference); 037 } 038 039 /** {@inheritDoc} */ 040 @Override 041 public int getRowCount() { 042 return _parameterList.size(); 043 } 044 045 /** {@inheritDoc} */ 046 @Override 047 public int getColumnCount() { 048 return COLUMN_DUMMY+1; 049 } 050 051 /** {@inheritDoc} */ 052 @Override 053 public String getColumnName(int col) { 054 switch (col) { 055 case COLUMN_NAME: 056 return Bundle.getMessage("WebRequest_ColumnName"); 057 case COLUMN_TYPE: 058 return Bundle.getMessage("WebRequest_ColumnType"); 059 case COLUMN_DATA: 060 return Bundle.getMessage("WebRequest_ColumnData"); 061 case COLUMN_DELETE: 062 return ""; // no label 063 case COLUMN_DUMMY: 064 return ""; // no label 065 default: 066 throw new IllegalArgumentException("Invalid column"); 067 } 068 } 069 070 /** {@inheritDoc} */ 071 @Override 072 public Class<?> getColumnClass(int col) { 073 switch (col) { 074 case COLUMN_NAME: 075 return String.class; 076 case COLUMN_TYPE: 077 return InitialValueType.class; 078 case COLUMN_DATA: 079 return String.class; 080 case COLUMN_DELETE: 081 return JButton.class; 082 case COLUMN_DUMMY: 083 return String.class; 084 default: 085 throw new IllegalArgumentException("Invalid column"); 086 } 087 } 088 089 /** {@inheritDoc} */ 090 @Override 091 public boolean isCellEditable(int row, int col) { 092 return true; 093 } 094 095 /** {@inheritDoc} */ 096 @Override 097 public void setValueAt(Object value, int rowIndex, int columnIndex) { 098 WebRequest.Parameter ref = _parameterList.get(rowIndex); 099 100 switch (columnIndex) { 101 case COLUMN_NAME: 102 ref.setName((String) value); 103 break; 104 case COLUMN_TYPE: 105 if (value != null) { 106 InitialValueType oldType = ref.getType(); 107 ref.setType((InitialValueType) value); 108 if (oldType != ref.getType()) ref.setData(""); 109 } else { 110 // This happens if the combo box is open when the user clicks on another cell. 111 log.debug("Cannot set data type to null"); 112 } 113 break; 114 case COLUMN_DATA: 115 ref.setData((String) value); 116 break; 117 case COLUMN_DELETE: 118 delete(rowIndex); 119 break; 120 case COLUMN_DUMMY: 121 break; 122 default: 123 throw new IllegalArgumentException("Invalid column"); 124 } 125 } 126 127 /** {@inheritDoc} */ 128 @Override 129 public Object getValueAt(int rowIndex, int columnIndex) { 130 if (rowIndex >= _parameterList.size()) throw new IllegalArgumentException("Invalid row"); 131 132 switch (columnIndex) { 133 case COLUMN_NAME: 134 return _parameterList.get(rowIndex).getName(); 135 case COLUMN_TYPE: 136 return _parameterList.get(rowIndex).getType(); 137 case COLUMN_DATA: 138 return _parameterList.get(rowIndex).getData(); 139 case COLUMN_DELETE: 140 return Bundle.getMessage("ButtonDelete"); // NOI18N 141 case COLUMN_DUMMY: 142 return ""; 143 default: 144 throw new IllegalArgumentException("Invalid column"); 145 } 146 } 147 148 public void setColumnsForComboBoxes(JTable table) { 149 JComboBox<InitialValueType> beanTypeComboBox = new JComboBox<>(); 150 table.setRowHeight(beanTypeComboBox.getPreferredSize().height); 151 table.getColumnModel().getColumn(COLUMN_TYPE) 152 .setPreferredWidth((beanTypeComboBox.getPreferredSize().width) + 4); 153 } 154 155 public void add() { 156 int row = _parameterList.size(); 157 _parameterList.add(new WebRequest.Parameter("", InitialValueType.LocalVariable, "")); 158 fireTableRowsInserted(row, row); 159 } 160 161 private void delete(int row) { 162 _parameterList.remove(row); 163 fireTableRowsDeleted(row, row); 164 } 165 166 public List<WebRequest.Parameter> getDataList() { 167 return _parameterList; 168 } 169 170 171 public static class CellRenderer extends DefaultTableCellRenderer { 172 173 @Override 174 public Component getTableCellRendererComponent(JTable table, Object value, 175 boolean isSelected, boolean hasFocus, int row, int column) { 176 177 if (column == COLUMN_TYPE) { 178 if (value == null) value = InitialValueType.LocalVariable; 179 180 if (! (value instanceof InitialValueType)) { 181 throw new IllegalArgumentException("value is not an InitialValueType: " + value.getClass().getName()); 182 } 183 setText(((InitialValueType) value).toString()); 184 } else { 185 throw new RuntimeException("Unknown column: "+Integer.toString(column)); 186 } 187 return this; 188 } 189 } 190 191 192 public static class DataTypeCellEditor extends AbstractCellEditor 193 implements TableCellEditor, ActionListener { 194 195 private InitialValueType _beanType; 196 197 @Override 198 public Object getCellEditorValue() { 199 return this._beanType; 200 } 201 202 @Override 203 public Component getTableCellEditorComponent(JTable table, Object value, 204 boolean isSelected, int row, int column) { 205 206 if (value == null) value = InitialValueType.LocalVariable; 207 208 if (! (value instanceof InitialValueType)) { 209 throw new IllegalArgumentException("value is not an InitialValueType: " + value.getClass().getName()); 210 } 211 212 JComboBox<InitialValueType> returnValueTypeComboBox = new JComboBox<>(); 213 214 for (InitialValueType type : InitialValueType.values()) { 215 returnValueTypeComboBox.addItem(type); 216 } 217 JComboBoxUtil.setupComboBoxMaxRows(returnValueTypeComboBox); 218 219 returnValueTypeComboBox.setSelectedItem(value); 220 returnValueTypeComboBox.addActionListener(this); 221 222 return returnValueTypeComboBox; 223 } 224 225 @Override 226 @SuppressWarnings("unchecked") // Not possible to check that event.getSource() is instanceof JComboBox<InitialValueType> 227 public void actionPerformed(ActionEvent event) { 228 if (! (event.getSource() instanceof JComboBox)) { 229 throw new IllegalArgumentException("value is not an JComboBox: " + event.getSource().getClass().getName()); 230 } 231 JComboBox<InitialValueType> returnValueTypeComboBox = 232 (JComboBox<InitialValueType>) event.getSource(); 233 _beanType = returnValueTypeComboBox.getItemAt(returnValueTypeComboBox.getSelectedIndex()); 234 235 } 236 237 } 238 239 240 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(WebRequestTableModel.class); 241 242}