001package jmri.jmrit.logixng.actions.swing;
002
003import java.awt.*;
004import java.util.ArrayList;
005import java.util.List;
006
007import javax.annotation.CheckForNull;
008import javax.annotation.Nonnull;
009import javax.swing.*;
010
011import jmri.InstanceManager;
012import jmri.jmrit.logixng.*;
013import jmri.jmrit.logixng.Module;
014import jmri.jmrit.logixng.Module.ParameterData;
015import jmri.jmrit.logixng.Module.ReturnValueType;
016import jmri.jmrit.logixng.SymbolTable.InitialValueType;
017import jmri.jmrit.logixng.actions.DigitalCallModule;
018import jmri.jmrit.logixng.tools.swing.CallModuleParameterTableModel;
019import jmri.util.swing.JComboBoxUtil;
020
021/**
022 * Configures an ModuleDigitalAction object with a Swing JPanel.
023 *
024 * @author Daniel Bergqvist Copyright 2021
025 */
026public class DigitalCallModuleSwing extends AbstractDigitalActionSwing {
027
028    private JComboBox<ModuleItem> _moduleComboBox;
029    private CallModuleParameterTableModel _moduleParametersTableModel;
030
031    @Override
032    protected void createPanel(@CheckForNull Base object, @Nonnull JPanel buttonPanel) {
033        if ((object != null) && (! (object instanceof DigitalCallModule))) {
034            throw new IllegalArgumentException("object is not a Module: " + object.getClass().getName());
035        }
036        DigitalCallModule callModule = (DigitalCallModule)object;
037
038        panel = new JPanel();
039
040        panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
041
042        JPanel beanPanel = new JPanel();
043        beanPanel.add(new JLabel("Module:"));
044        _moduleComboBox = new JComboBox<>();
045        _moduleComboBox.addItem(new ModuleItem(null));
046        for (Module m : InstanceManager.getDefault(ModuleManager.class).getNamedBeanSet()) {
047//            System.out.format("Root socket type: %s%n", m.getRootSocketType().getName());
048            if ("DefaultFemaleDigitalActionSocket".equals(m.getRootSocketType().getName())
049                    && m.isVisible()) {
050                ModuleItem mi = new ModuleItem(m);
051                _moduleComboBox.addItem(mi);
052                if ((callModule != null)
053                        && (callModule.getSelectNamedBean().getNamedBean() != null)
054                        && (callModule.getSelectNamedBean().getNamedBean().getBean() == m)) {
055                    _moduleComboBox.setSelectedItem(mi);
056                }
057            }
058        }
059        JComboBoxUtil.setupComboBoxMaxRows(_moduleComboBox);
060        beanPanel.add(_moduleComboBox);
061        panel.add(beanPanel);
062
063        Module module = null;
064        List<ParameterData> parameterData;
065        if (callModule != null) {
066            if (callModule.getSelectNamedBean().getNamedBean() != null) {
067                module = callModule.getSelectNamedBean().getNamedBean().getBean();
068            }
069            parameterData = callModule.getParameterData();
070        } else {
071            parameterData = new ArrayList<>();
072        }
073        JTable table = new JTable();
074        _moduleParametersTableModel = new CallModuleParameterTableModel(module, parameterData);
075        table.setModel(_moduleParametersTableModel);
076        table.setDefaultRenderer(InitialValueType.class,
077                new CallModuleParameterTableModel.TypeCellRenderer());
078        table.setDefaultEditor(InitialValueType.class,
079                new CallModuleParameterTableModel.InitialValueCellEditor());
080        table.setDefaultRenderer(ReturnValueType.class,
081                new CallModuleParameterTableModel.TypeCellRenderer());
082        table.setDefaultEditor(ReturnValueType.class,
083                new CallModuleParameterTableModel.ReturnValueCellEditor());
084        _moduleParametersTableModel.setColumnsForComboBoxes(table);
085        JScrollPane scrollpane = new JScrollPane(table);
086        scrollpane.setPreferredSize(new Dimension(400, 200));
087        panel.add(scrollpane);
088    }
089
090    /** {@inheritDoc} */
091    @Override
092    public boolean validate(@Nonnull List<String> errorMessages) {
093        return true;
094    }
095
096    /** {@inheritDoc} */
097    @Override
098    public MaleSocket createNewObject(@Nonnull String systemName, @CheckForNull String userName) {
099        DigitalCallModule action = new DigitalCallModule(systemName, userName);
100        updateObject(action);
101        return InstanceManager.getDefault(DigitalActionManager.class).registerAction(action);
102    }
103
104    /** {@inheritDoc} */
105    @Override
106    public void updateObject(@Nonnull Base object) {
107        if (! (object instanceof DigitalCallModule)) {
108            throw new IllegalArgumentException("object is not a Module: " + object.getClass().getName());
109        }
110        DigitalCallModule callModule = (DigitalCallModule)object;
111
112        ModuleItem mi = _moduleComboBox.getItemAt(_moduleComboBox.getSelectedIndex());
113        if (mi._module != null) {
114            callModule.getSelectNamedBean().setNamedBean(mi._module);
115            callModule.getParameterData().clear();
116            callModule.getParameterData().addAll(_moduleParametersTableModel.getParameters());
117        }
118        else {
119            callModule.getSelectNamedBean().removeNamedBean();
120        }
121    }
122
123    /** {@inheritDoc} */
124    @Override
125    public String toString() {
126        return Bundle.getMessage("DigitalCallModule_Short");
127    }
128
129    @Override
130    public void dispose() {
131    }
132
133
134    private static class ModuleItem {
135
136        private final Module _module;
137
138        public ModuleItem(Module m) {
139            _module = m;
140        }
141
142        @Override
143        public String toString() {
144            if (_module == null) return "";
145            else return _module.getDisplayName();
146        }
147    }
148
149}