001package jmri.jmrit.logixng.actions.swing;
002
003import java.util.List;
004
005import javax.annotation.CheckForNull;
006import javax.annotation.Nonnull;
007import javax.swing.*;
008
009import jmri.*;
010import jmri.jmrit.logixng.*;
011import jmri.jmrit.logixng.actions.ActionCreateBeansFromTable;
012import jmri.jmrit.logixng.NamedBeanType;
013import jmri.util.swing.BeanSelectPanel;
014import jmri.util.swing.JComboBoxUtil;
015
016/**
017 * Configures an ActionCreateBeansFromTable object with a Swing JPanel.
018 *
019 * @author Daniel Bergqvist Copyright 2022
020 */
021public class ActionCreateBeansFromTableSwing extends AbstractDigitalActionSwing {
022
023    private BeanSelectPanel<NamedTable> _tableBeanPanel;
024    private JComboBox<TableRowOrColumn> _tableRowOrColumnComboBox;
025    private JComboBox<String> _rowOrColumnSystemNameComboBox;
026    private JComboBox<String> _rowOrColumnUserNameComboBox;
027    private JCheckBox _includeCellsWithoutHeaderCheckBox;
028    private JCheckBox _onlyCreatableTypesCheckBox;
029    private JComboBox<NamedBeanType> _namedBeanTypeComboBox;
030    private JCheckBox _moveUserNameCheckBox;
031    private JCheckBox _updateToUserNameCheckBox;
032    private JCheckBox _removeOldBeanCheckBox;
033
034    @Override
035    protected void createPanel(@CheckForNull Base object, @Nonnull JPanel buttonPanel) {
036        if ((object != null) && !(object instanceof ActionCreateBeansFromTable)) {
037            throw new IllegalArgumentException("object must be an ActionCreateBeansFromTable but is a: "+object.getClass().getName());
038        }
039
040        ActionCreateBeansFromTable action = (ActionCreateBeansFromTable)object;
041
042        panel = new JPanel();
043        panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
044
045        JPanel tableBeanPanelPanel = new JPanel();
046        tableBeanPanelPanel.add(new JLabel(Bundle.getMessage("ActionCreateBeansFromTableSwing_Table")));
047        _tableBeanPanel = new BeanSelectPanel<>(InstanceManager.getDefault(NamedTableManager.class), null);
048        tableBeanPanelPanel.add(_tableBeanPanel);
049        panel.add(tableBeanPanelPanel);
050
051        _rowOrColumnSystemNameComboBox = new JComboBox<>();
052        _rowOrColumnUserNameComboBox = new JComboBox<>();
053        _tableRowOrColumnComboBox = new JComboBox<>();
054        for (TableRowOrColumn item : TableRowOrColumn.values()) {
055            _tableRowOrColumnComboBox.addItem(item);
056        }
057        JComboBoxUtil.setupComboBoxMaxRows(_tableRowOrColumnComboBox);
058        _tableRowOrColumnComboBox.addActionListener((evt) -> {
059            comboListener(action);
060        });
061        _tableBeanPanel.getBeanCombo().addActionListener((evt) -> {
062            comboListener(action);
063        });
064
065        JPanel tableRowOrColumnPanel = new JPanel();
066        tableRowOrColumnPanel.add(new JLabel(Bundle.getMessage("ActionCreateBeansFromTableSwing_RowOrColumn")));
067        tableRowOrColumnPanel.add(_tableRowOrColumnComboBox);
068        panel.add(tableRowOrColumnPanel);
069
070        JPanel rowOrColumnSystemNamePanel = new JPanel();
071        rowOrColumnSystemNamePanel.add(new JLabel(Bundle.getMessage("ActionCreateBeansFromTableSwing_RowOrColumnSystemName")));
072        rowOrColumnSystemNamePanel.add(_rowOrColumnSystemNameComboBox);
073        panel.add(rowOrColumnSystemNamePanel);
074        JComboBoxUtil.setupComboBoxMaxRows(_rowOrColumnSystemNameComboBox);
075
076        JPanel rowOrColumnUserNamePanel = new JPanel();
077        rowOrColumnUserNamePanel.add(new JLabel(Bundle.getMessage("ActionCreateBeansFromTableSwing_RowOrColumnUserName")));
078        rowOrColumnUserNamePanel.add(_rowOrColumnUserNameComboBox);
079        panel.add(rowOrColumnUserNamePanel);
080        JComboBoxUtil.setupComboBoxMaxRows(_rowOrColumnUserNameComboBox);
081
082        JPanel includeCellsWithoutHeaderPanel = new JPanel();
083        includeCellsWithoutHeaderPanel.add(new JLabel(Bundle.getMessage("ActionCreateBeansFromTableSwing_IncludeCellsWithoutHeader")));
084        _includeCellsWithoutHeaderCheckBox = new JCheckBox();
085        includeCellsWithoutHeaderPanel.add(_includeCellsWithoutHeaderCheckBox);
086        panel.add(includeCellsWithoutHeaderPanel);
087
088        JPanel onlyCreatableTypesPanel = new JPanel();
089        onlyCreatableTypesPanel.add(new JLabel(Bundle.getMessage("ActionCreateBeansFromTableSwing_OnlyCreatableTypesCheckBox")));
090        _onlyCreatableTypesCheckBox = new JCheckBox();
091        _onlyCreatableTypesCheckBox.setSelected(true);
092        _onlyCreatableTypesCheckBox.addActionListener((evt)->{ updateNamedBeanTypeComboBox(); });
093        onlyCreatableTypesPanel.add(_onlyCreatableTypesCheckBox);
094        panel.add(onlyCreatableTypesPanel);
095
096        JPanel namedBeanTypePanel = new JPanel();
097        namedBeanTypePanel.add(new JLabel(Bundle.getMessage("ActionCreateBeansFromTableSwing_NamedBeanType")));
098        _namedBeanTypeComboBox = new JComboBox<>();
099        JComboBoxUtil.setupComboBoxMaxRows(_namedBeanTypeComboBox);
100        namedBeanTypePanel.add(_namedBeanTypeComboBox);
101        panel.add(namedBeanTypePanel);
102
103        JPanel moveUserNamePanel = new JPanel();
104        moveUserNamePanel.add(new JLabel(Bundle.getMessage("ActionCreateBeansFromTableSwing_MoveUserNameCheckBox")));
105        _moveUserNameCheckBox = new JCheckBox();
106        moveUserNamePanel.add(_moveUserNameCheckBox);
107        panel.add(moveUserNamePanel);
108
109        JPanel updateToUserNamePanel = new JPanel();
110        updateToUserNamePanel.add(new JLabel(Bundle.getMessage("ActionCreateBeansFromTableSwing_UpdateToUserName")));
111        _updateToUserNameCheckBox = new JCheckBox();
112        updateToUserNamePanel.add(_updateToUserNameCheckBox);
113        panel.add(updateToUserNamePanel);
114
115        JPanel removeOldBeanPanel = new JPanel();
116        removeOldBeanPanel.add(new JLabel(Bundle.getMessage("ActionCreateBeansFromTableSwing_RemoveOldBeanCheckBox")));
117        _removeOldBeanCheckBox = new JCheckBox();
118        removeOldBeanPanel.add(_removeOldBeanCheckBox);
119        panel.add(removeOldBeanPanel);
120
121        panel.add(new JLabel(Bundle.getMessage("ActionCreateBeansFromTableSwing_Message1")));
122        panel.add(new JLabel(Bundle.getMessage("ActionCreateBeansFromTableSwing_Message2")));
123
124        if (action != null) {
125            if (action.getSelectNamedBean().getNamedBean() != null) {
126                _tableBeanPanel.setDefaultNamedBean(action.getSelectNamedBean().getNamedBean().getBean());
127            }
128            _tableRowOrColumnComboBox.setSelectedItem(action.getTableRowOrColumn());
129            _includeCellsWithoutHeaderCheckBox.setSelected(action.isIncludeCellsWithoutHeader());
130            _moveUserNameCheckBox.setSelected(action.isMoveUserName());
131            _updateToUserNameCheckBox.setSelected(action.isUpdateToUserName());
132            _removeOldBeanCheckBox.setSelected(action.isRemoveOldBean());
133
134            // All types must be in the list when the type is selected.
135            _onlyCreatableTypesCheckBox.setSelected(false);
136            updateNamedBeanTypeComboBox();
137            _namedBeanTypeComboBox.setSelectedItem(action.getNamedBeanType());
138            _onlyCreatableTypesCheckBox.setSelected(action.isOnlyCreatableTypes());
139        }
140    }
141
142    private void updateNamedBeanTypeComboBox() {
143        NamedBeanType lastSelectedItem =
144                _namedBeanTypeComboBox.getSelectedIndex() != -1
145                ? _namedBeanTypeComboBox.getItemAt(
146                        _namedBeanTypeComboBox.getSelectedIndex())
147                : null;
148
149        _namedBeanTypeComboBox.removeAllItems();
150        for (NamedBeanType item : NamedBeanType.values()) {
151            if (!_onlyCreatableTypesCheckBox.isSelected()
152                    || item.getCreateBean() != null) {
153                _namedBeanTypeComboBox.addItem(item);
154            }
155        }
156
157        if (lastSelectedItem != null) {
158            _namedBeanTypeComboBox.setSelectedItem(lastSelectedItem);
159        }
160    }
161
162    private void comboListener( ActionCreateBeansFromTable action ) {
163
164        _rowOrColumnSystemNameComboBox.removeAllItems();
165        _rowOrColumnUserNameComboBox.removeAllItems();
166        _rowOrColumnUserNameComboBox.addItem("");
167
168        NamedTable table = _tableBeanPanel.getNamedBean();
169        if (table != null) {
170            if (_tableRowOrColumnComboBox.getItemAt(_tableRowOrColumnComboBox.getSelectedIndex()) == TableRowOrColumn.Column) {
171                for (int column=0; column <= table.numColumns(); column++) {
172                    // If the header is null or empty, treat the row as a comment
173                    Object header = table.getCell(0, column);
174                    if ((header != null) && (!header.toString().isEmpty())) {
175                        _rowOrColumnSystemNameComboBox.addItem(header.toString());
176                        _rowOrColumnUserNameComboBox.addItem(header.toString());
177                    }
178                }
179            } else {
180                for (int row=0; row <= table.numRows(); row++) {
181                    // If the header is null or empty, treat the row as a comment
182                    Object header = table.getCell(row, 0);
183                    if ((header != null) && (!header.toString().isEmpty())) {
184                        _rowOrColumnSystemNameComboBox.addItem(header.toString());
185                        _rowOrColumnUserNameComboBox.addItem(header.toString());
186                    }
187                }
188            }
189            if (action != null) {
190                _rowOrColumnSystemNameComboBox.setSelectedItem(action.getRowOrColumnSystemName());
191                _rowOrColumnUserNameComboBox.setSelectedItem(action.getRowOrColumnUserName());
192            }
193        }
194    }
195
196    /** {@inheritDoc} */
197    @Override
198    public boolean validate(@Nonnull List<String> errorMessages) {
199        if (_tableBeanPanel.getNamedBean() != null) {
200            String rowColSystemName = null;
201            String rowColUserName = null;
202            if (_rowOrColumnSystemNameComboBox.getSelectedIndex() != -1) {
203                rowColSystemName = _rowOrColumnSystemNameComboBox.getItemAt(_rowOrColumnSystemNameComboBox.getSelectedIndex());
204            }
205            if (_rowOrColumnUserNameComboBox.getSelectedIndex() != -1) {
206                rowColUserName = _rowOrColumnUserNameComboBox.getItemAt(_rowOrColumnUserNameComboBox.getSelectedIndex());
207            }
208            if (rowColSystemName == null) {
209                errorMessages.add("\"Row or column system name\" must be selected");
210            } else if (rowColSystemName.equals(rowColUserName)) {
211                errorMessages.add("\"Row or column system name\" must not be the same as \"Row or column user name\"");
212            }
213        }
214        return errorMessages.isEmpty();
215    }
216
217    /** {@inheritDoc} */
218    @Override
219    public MaleSocket createNewObject(@Nonnull String systemName, @CheckForNull String userName) {
220        ActionCreateBeansFromTable action = new ActionCreateBeansFromTable(systemName, userName);
221        updateObject(action);
222        return InstanceManager.getDefault(DigitalActionManager.class).registerAction(action);
223    }
224
225    /** {@inheritDoc} */
226    @Override
227    public void updateObject(@Nonnull Base object) {
228        if (!(object instanceof ActionCreateBeansFromTable)) {
229            throw new IllegalArgumentException("object must be an ActionCreateBeansFromTable but is a: "+object.getClass().getName());
230        }
231        if ( _tableBeanPanel == null ){
232            throw new UnsupportedOperationException("No Bean Panel Present ");
233        }
234
235        ActionCreateBeansFromTable action = (ActionCreateBeansFromTable)object;
236        NamedTable table = _tableBeanPanel.getNamedBean();
237        if (table != null) {
238            NamedBeanHandle<NamedTable> handle
239                    = InstanceManager.getDefault(NamedBeanHandleManager.class)
240                            .getNamedBeanHandle(table.getDisplayName(), table);
241            action.getSelectNamedBean().setNamedBean(handle);
242        } else {
243            action.getSelectNamedBean().removeNamedBean();
244        }
245        action.setTableRowOrColumn(_tableRowOrColumnComboBox.getItemAt(_tableRowOrColumnComboBox.getSelectedIndex()));
246        if (_rowOrColumnSystemNameComboBox.getSelectedIndex() != -1) {
247            action.setRowOrColumnSystemName(_rowOrColumnSystemNameComboBox.getItemAt(_rowOrColumnSystemNameComboBox.getSelectedIndex()));
248        } else {
249            action.setRowOrColumnSystemName("");
250        }
251        if (_rowOrColumnUserNameComboBox.getSelectedIndex() != -1) {
252            action.setRowOrColumnUserName(_rowOrColumnUserNameComboBox.getItemAt(_rowOrColumnUserNameComboBox.getSelectedIndex()));
253        } else {
254            action.setRowOrColumnUserName("");
255        }
256        action.setOnlyCreatableTypes(_onlyCreatableTypesCheckBox.isSelected());
257        if (_namedBeanTypeComboBox.getSelectedIndex() != -1) {
258            action.setNamedBeanType(_namedBeanTypeComboBox.getItemAt(_namedBeanTypeComboBox.getSelectedIndex()));
259        }
260        action.setIncludeCellsWithoutHeader(_includeCellsWithoutHeaderCheckBox.isSelected());
261        action.setMoveUserName(_moveUserNameCheckBox.isSelected());
262        action.setUpdateToUserName(_updateToUserNameCheckBox.isSelected());
263        action.setRemoveOldBean(_removeOldBeanCheckBox.isSelected());
264    }
265
266    /** {@inheritDoc} */
267    @Override
268    public String toString() {
269        return Bundle.getMessage("ActionCreateBeansFromTable_Short");
270    }
271
272    @Override
273    public void dispose() {
274    }
275
276
277//    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ActionCreateBeansFromTableSwing.class);
278
279}