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.ActionTable;
012import jmri.jmrit.logixng.actions.ActionTable.ConstantType;
013import jmri.jmrit.logixng.actions.ActionTable.VariableOperation;
014import jmri.jmrit.logixng.swing.SwingConfiguratorInterface;
015import jmri.jmrit.logixng.util.parser.ParserException;
016import jmri.jmrit.logixng.util.swing.LogixNG_SelectTableSwing;
017import jmri.util.swing.BeanSelectPanel;
018import jmri.util.swing.JComboBoxUtil;
019
020/**
021 * Configures an ActionTable object with a Swing JPanel.
022 *
023 * @author Daniel Bergqvist Copyright 2021
024 */
025public class ActionTableSwing extends AbstractDigitalActionSwing {
026
027    private LogixNG_SelectTableSwing selectTableToSetSwing;
028
029    private JTabbedPane _tabbedPaneVariableOperation;
030    private BeanSelectPanel<Memory> _copyMemoryBeanPanel;
031    private JCheckBox _listenOnMemory;
032    private BeanSelectPanel<Block> _copyBlockBeanPanel;
033    private JCheckBox _listenOnBlock;
034    private BeanSelectPanel<Reporter> _copyReporterBeanPanel;
035    private JCheckBox _listenOnReporter;
036    private JPanel _setToNull;
037    private JPanel _setToConstant;
038    private JPanel _copyMemory;
039    private JPanel _copyBlock;
040    private JPanel _copyReporter;
041    private JPanel _copyVariable;
042    private JPanel _copyReference;
043    private JPanel _calculateFormula;
044    private JPanel _copyTableCell;
045    private JComboBox<ConstantType> _setToConstantTypeComboBox;
046    private JTextField _setToConstantTextField;
047    private JTextField _copyLocalVariableTextField;
048    private JTextField _copyReferenceTextField;
049    private JTextField _calculateFormulaTextField;
050    private LogixNG_SelectTableSwing selectTableSwing;
051
052
053    @Override
054    protected void createPanel(@CheckForNull Base object, @Nonnull JPanel buttonPanel) {
055        ActionTable action = (ActionTable)object;
056
057        selectTableToSetSwing = new LogixNG_SelectTableSwing(getJDialog(), this);
058        JPanel selectTableToSetPanel;
059
060        selectTableToSetSwing.addChangeListener((e) -> { getJDialog().pack(); });
061
062        selectTableSwing = new LogixNG_SelectTableSwing(getJDialog(), this);
063
064        panel = new JPanel();
065
066        _tabbedPaneVariableOperation = new JTabbedPane();
067
068        _setToNull = new JPanel();
069        _setToConstant = new JPanel();
070        _setToConstant.setLayout(new BoxLayout(_setToConstant, BoxLayout.Y_AXIS));
071        _copyMemory = new JPanel();
072        _copyBlock = new JPanel();
073        _copyReporter = new JPanel();
074        if (action != null) {
075            selectTableToSetPanel = selectTableToSetSwing.createPanel(action.getSelectTableToSet());
076            _copyTableCell = selectTableSwing.createPanel(action.getSelectTable());
077        } else {
078            selectTableToSetPanel = selectTableToSetSwing.createPanel(null);
079            _copyTableCell = selectTableSwing.createPanel(null);
080        }
081        _copyVariable = new JPanel();
082        _copyReference = new JPanel();
083        _calculateFormula = new JPanel();
084
085
086        _tabbedPaneVariableOperation.addTab(VariableOperation.SetToNull.toString(), _setToNull);
087        _tabbedPaneVariableOperation.addTab(VariableOperation.SetToString.toString(), _setToConstant);
088        _tabbedPaneVariableOperation.addTab(VariableOperation.CopyMemoryToVariable.toString(), _copyMemory);
089        _tabbedPaneVariableOperation.addTab(VariableOperation.CopyBlockToVariable.toString(), _copyBlock);
090        _tabbedPaneVariableOperation.addTab(VariableOperation.CopyReporterToVariable.toString(), _copyReporter);
091        _tabbedPaneVariableOperation.addTab(VariableOperation.CopyVariableToVariable.toString(), _copyVariable);
092        _tabbedPaneVariableOperation.addTab(VariableOperation.CopyReferenceToVariable.toString(), _copyReference);
093        _tabbedPaneVariableOperation.addTab(VariableOperation.CopyTableCellToVariable.toString(), _copyTableCell);
094        _tabbedPaneVariableOperation.addTab(VariableOperation.CalculateFormula.toString(), _calculateFormula);
095
096        _setToNull.add(new JLabel("Null"));     // No I18N
097
098        JPanel _setToConstantTypeInnerPanel = new JPanel();
099        _setToConstantTypeComboBox = new JComboBox<>();
100        for (ConstantType value : ConstantType.values()) {
101            _setToConstantTypeComboBox.addItem(value);
102        }
103        JComboBoxUtil.setupComboBoxMaxRows(_setToConstantTypeComboBox);
104        _setToConstantTypeInnerPanel.add(new JLabel(Bundle.getMessage("ActionTable_ConstantType")));
105        _setToConstantTypeInnerPanel.add(_setToConstantTypeComboBox);
106        _setToConstant.add(_setToConstantTypeInnerPanel);
107
108        JPanel _setToConstantTextFieldInnerPanel = new JPanel();
109        _setToConstantTextField = new JTextField(30);
110        _setToConstantTextFieldInnerPanel.add(_setToConstantTextField);
111        _setToConstant.add(_setToConstantTextFieldInnerPanel);
112
113        _copyMemoryBeanPanel = new BeanSelectPanel<>(InstanceManager.getDefault(MemoryManager.class), null);
114        _listenOnMemory = new JCheckBox(Bundle.getMessage("ActionTable_ListenOnMemory"));
115        _copyMemory.add(_copyMemoryBeanPanel);
116        _copyMemory.add(_listenOnMemory);
117
118        _copyBlockBeanPanel = new BeanSelectPanel<>(InstanceManager.getDefault(BlockManager.class), null);
119        _listenOnBlock = new JCheckBox(Bundle.getMessage("ActionTable_ListenOnBlock"));
120        _copyBlock.add(_copyBlockBeanPanel);
121        _copyBlock.add(_listenOnBlock);
122
123        _copyReporterBeanPanel = new BeanSelectPanel<>(InstanceManager.getDefault(ReporterManager.class), null);
124        _listenOnReporter = new JCheckBox(Bundle.getMessage("ActionTable_ListenOnReporter"));
125        _copyReporter.add(_copyReporterBeanPanel);
126        _copyReporter.add(_listenOnReporter);
127
128        _copyLocalVariableTextField = new JTextField(30);
129        _copyVariable.add(_copyLocalVariableTextField);
130
131        _copyReferenceTextField = new JTextField(30);
132        _copyReference.add(_copyReferenceTextField);
133
134        _calculateFormulaTextField = new JTextField(30);
135        _calculateFormula.add(_calculateFormulaTextField);
136
137
138        if (action != null) {
139            if (action.getSelectMemoryNamedBean().getNamedBean() != null) {
140                _copyMemoryBeanPanel.setDefaultNamedBean(action.getSelectMemoryNamedBean().getNamedBean().getBean());
141            }
142            if (action.getSelectBlockNamedBean().getNamedBean() != null) {
143                _copyBlockBeanPanel.setDefaultNamedBean(action.getSelectBlockNamedBean().getNamedBean().getBean());
144            }
145            if (action.getSelectReporterNamedBean().getNamedBean() != null) {
146                _copyReporterBeanPanel.setDefaultNamedBean(action.getSelectReporterNamedBean().getNamedBean().getBean());
147            }
148            switch (action.getVariableOperation()) {
149                case SetToNull: _tabbedPaneVariableOperation.setSelectedComponent(_setToNull); break;
150                case SetToString: _tabbedPaneVariableOperation.setSelectedComponent(_setToConstant); break;
151                case CopyMemoryToVariable: _tabbedPaneVariableOperation.setSelectedComponent(_copyMemory); break;
152                case CopyTableCellToVariable: _tabbedPaneVariableOperation.setSelectedComponent(_copyTableCell); break;
153                case CopyBlockToVariable: _tabbedPaneVariableOperation.setSelectedComponent(_copyBlock); break;
154                case CopyReporterToVariable: _tabbedPaneVariableOperation.setSelectedComponent(_copyReporter); break;
155                case CopyVariableToVariable: _tabbedPaneVariableOperation.setSelectedComponent(_copyVariable); break;
156                case CopyReferenceToVariable: _tabbedPaneVariableOperation.setSelectedComponent(_copyReference); break;
157                case CalculateFormula: _tabbedPaneVariableOperation.setSelectedComponent(_calculateFormula); break;
158                default: throw new IllegalArgumentException("invalid _addressing state: " + action.getVariableOperation().name());
159            }
160            _setToConstantTypeComboBox.setSelectedItem(action.getConstantType());
161            _setToConstantTextField.setText(action.getConstantValue());
162            _copyLocalVariableTextField.setText(action.getOtherLocalVariable());
163            _copyReferenceTextField.setText(action.getReference());
164            _calculateFormulaTextField.setText(action.getFormula());
165
166            _listenOnMemory.setSelected(action.getListenToMemory());
167            _listenOnBlock.setSelected(action.getListenToBlock());
168            _listenOnReporter.setSelected(action.getListenToReporter());
169        }
170
171        JComponent[] components = new JComponent[]{
172            selectTableToSetPanel,
173            _tabbedPaneVariableOperation
174        };
175
176        List<JComponent> componentList = SwingConfiguratorInterface.parseMessage(
177                Bundle.getMessage("ActionTable_Components"), components);
178
179        for (JComponent c : componentList) panel.add(c);
180    }
181
182    /** {@inheritDoc} */
183    @Override
184    public boolean validate(@Nonnull List<String> errorMessages) {
185        ActionTable action = new ActionTable("IQDA1", null);
186
187        selectTableToSetSwing.validate(action.getSelectTableToSet(), errorMessages);
188
189        try {
190            action.setVariableOperation(VariableOperation.CalculateFormula);
191            action.setFormula(_calculateFormulaTextField.getText());
192        } catch (ParserException e) {
193            errorMessages.add(e.getMessage());
194        }
195
196        // If using the Memory tab, validate the memory variable selection.
197        if (_tabbedPaneVariableOperation.getSelectedComponent() == _copyMemory) {
198            if (_copyMemoryBeanPanel.getNamedBean() == null) {
199                errorMessages.add(Bundle.getMessage("ActionTable_CopyErrorMemory"));
200            }
201        }
202
203         // If using the Block tab, validate the block variable selection.
204        if (_tabbedPaneVariableOperation.getSelectedComponent() == _copyBlock) {
205            if (_copyBlockBeanPanel.getNamedBean() == null) {
206                errorMessages.add(Bundle.getMessage("ActionTable_CopyErrorBlock"));
207            }
208        }
209
210         // If using the Reporter tab, validate the reporter variable selection.
211        if (_tabbedPaneVariableOperation.getSelectedComponent() == _copyReporter) {
212            if (_copyReporterBeanPanel.getNamedBean() == null) {
213                errorMessages.add(Bundle.getMessage("ActionTable_CopyErrorReporter"));
214            }
215        }
216
217        selectTableSwing.validate(action.getSelectTable(), errorMessages);
218
219        return errorMessages.isEmpty();
220    }
221
222    /** {@inheritDoc} */
223    @Override
224    public MaleSocket createNewObject(@Nonnull String systemName, @CheckForNull String userName) {
225        ActionTable action = new ActionTable(systemName, userName);
226        updateObject(action);
227        return InstanceManager.getDefault(DigitalActionManager.class).registerAction(action);
228    }
229
230    /** {@inheritDoc} */
231    @Override
232    public void updateObject(@Nonnull Base object) {
233        if (! (object instanceof ActionTable)) {
234            throw new IllegalArgumentException("object must be an ActionTable but is a: "+object.getClass().getName());
235        }
236        ActionTable action = (ActionTable)object;
237
238        selectTableToSetSwing.updateObject(action.getSelectTableToSet());
239
240
241        if (!_copyMemoryBeanPanel.isEmpty()
242                && (_tabbedPaneVariableOperation.getSelectedComponent() == _copyMemory)) {
243            Memory memory = _copyMemoryBeanPanel.getNamedBean();
244            if (memory != null) {
245                NamedBeanHandle<Memory> handle
246                        = InstanceManager.getDefault(NamedBeanHandleManager.class)
247                                .getNamedBeanHandle(memory.getDisplayName(), memory);
248                action.getSelectMemoryNamedBean().setNamedBean(handle);
249            }
250        }
251
252        if (!_copyBlockBeanPanel.isEmpty()
253                && (_tabbedPaneVariableOperation.getSelectedComponent() == _copyBlock)) {
254            Block block = _copyBlockBeanPanel.getNamedBean();
255            if (block != null) {
256                NamedBeanHandle<Block> handle
257                        = InstanceManager.getDefault(NamedBeanHandleManager.class)
258                                .getNamedBeanHandle(block.getDisplayName(), block);
259                action.getSelectBlockNamedBean().setNamedBean(handle);
260            }
261        }
262
263        if (!_copyReporterBeanPanel.isEmpty()
264                && (_tabbedPaneVariableOperation.getSelectedComponent() == _copyReporter)) {
265            Reporter reporter = _copyReporterBeanPanel.getNamedBean();
266            if (reporter != null) {
267                NamedBeanHandle<Reporter> handle
268                        = InstanceManager.getDefault(NamedBeanHandleManager.class)
269                                .getNamedBeanHandle(reporter.getDisplayName(), reporter);
270                action.getSelectReporterNamedBean().setNamedBean(handle);
271            }
272        }
273
274        try {
275            if (_tabbedPaneVariableOperation.getSelectedComponent() == _setToNull) {
276                action.setVariableOperation(VariableOperation.SetToNull);
277            } else if (_tabbedPaneVariableOperation.getSelectedComponent() == _setToConstant) {
278                action.setVariableOperation(VariableOperation.SetToString);
279                action.setConstantType(_setToConstantTypeComboBox.getItemAt(
280                        _setToConstantTypeComboBox.getSelectedIndex()));
281                action.setConstantValue(_setToConstantTextField.getText());
282            } else if (_tabbedPaneVariableOperation.getSelectedComponent() == _copyMemory) {
283                action.setVariableOperation(VariableOperation.CopyMemoryToVariable);
284            } else if (_tabbedPaneVariableOperation.getSelectedComponent() == _copyBlock) {
285                action.setVariableOperation(VariableOperation.CopyBlockToVariable);
286            } else if (_tabbedPaneVariableOperation.getSelectedComponent() == _copyReporter) {
287                action.setVariableOperation(VariableOperation.CopyReporterToVariable);
288            } else if (_tabbedPaneVariableOperation.getSelectedComponent() == _copyTableCell) {
289                action.setVariableOperation(VariableOperation.CopyTableCellToVariable);
290            } else if (_tabbedPaneVariableOperation.getSelectedComponent() == _copyVariable) {
291                action.setVariableOperation(VariableOperation.CopyVariableToVariable);
292                action.setOtherLocalVariable(_copyLocalVariableTextField.getText());
293            } else if (_tabbedPaneVariableOperation.getSelectedComponent() == _copyReference) {
294                action.setVariableOperation(VariableOperation.CopyReferenceToVariable);
295                action.setReference(_copyReferenceTextField.getText());
296            } else if (_tabbedPaneVariableOperation.getSelectedComponent() == _calculateFormula) {
297                action.setVariableOperation(VariableOperation.CalculateFormula);
298                action.setFormula(_calculateFormulaTextField.getText());
299            } else {
300                throw new IllegalArgumentException("_tabbedPaneVariableOperation has unknown selection");
301            }
302        } catch (ParserException e) {
303            throw new RuntimeException("ParserException: "+e.getMessage(), e);
304        }
305
306        selectTableSwing.updateObject(action.getSelectTable());
307
308        action.setListenToMemory(_listenOnMemory.isSelected());
309        action.setListenToBlock(_listenOnBlock.isSelected());
310        action.setListenToReporter(_listenOnReporter.isSelected());
311    }
312
313    /** {@inheritDoc} */
314    @Override
315    public String toString() {
316        return Bundle.getMessage("ActionTable_Short");
317    }
318
319    /** {@inheritDoc} */
320    @Override
321    public boolean canClose() {
322        return selectTableToSetSwing.canClose() && selectTableSwing.canClose();
323    }
324
325    @Override
326    public void dispose() {
327        selectTableToSetSwing.dispose();
328        selectTableSwing.dispose();
329    }
330
331//    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ActionTableSwing.class);
332
333}