001package jmri.jmrit.logixng.implementation.swing;
002
003import java.awt.*;
004import java.awt.event.ActionEvent;
005import java.util.List;
006
007import javax.annotation.CheckForNull;
008import javax.annotation.Nonnull;
009import javax.swing.*;
010
011import jmri.NamedBean;
012import jmri.jmrit.logixng.*;
013import jmri.jmrit.logixng.Module;
014import jmri.jmrit.logixng.Module.Parameter;
015import jmri.jmrit.logixng.implementation.DefaultSymbolTable.DefaultParameter;
016import jmri.jmrit.logixng.swing.AbstractSwingConfigurator;
017import jmri.jmrit.logixng.swing.SwingConfiguratorInterface;
018import jmri.jmrit.logixng.swing.SwingTools;
019import jmri.jmrit.logixng.tools.swing.swing.ModuleParametersTableModel;
020
021/**
022 * Configures an DefaultModule object with a Swing JPanel.
023 */
024public class DefaultModuleSwing extends AbstractSwingConfigurator {
025
026    static final java.util.ResourceBundle rbx =
027            java.util.ResourceBundle.getBundle("jmri.jmrit.logixng.tools.swing.LogixNGSwingBundle");  // NOI18N
028
029    protected JPanel panel;
030    ModuleParametersTableModel _moduleParametersTableModel;
031
032    /** {@inheritDoc} */
033    @Override
034    public String getExecuteEvaluateMenuText() {
035        return Bundle.getMessage("MenuText_ExecuteEvaluate");
036    }
037
038    /** {@inheritDoc} */
039    @Override
040    public void executeEvaluate(@Nonnull Base object) {
041
042        if (! (object instanceof MaleSocket)) {
043            throw new IllegalArgumentException("object is not a MaleSocket");
044        }
045        if (! (((MaleSocket)object).getObject() instanceof Module)) {
046            throw new IllegalArgumentException("((MaleSocket)object).getObject() is not a Module");
047        }
048        Module module = (Module)((MaleSocket)object).getObject();
049
050        FemaleSocket femaleSocket = module.getRootSocket();
051        if (!femaleSocket.isConnected()) {
052            // Nothing to do since nothing is connected to the female socket
053            jmri.util.ThreadingUtil.runOnGUIEventually(() -> {
054                JOptionPane.showMessageDialog(null,
055                        Bundle.getMessage("ExecuteEvaluate_ActionCompleted"),
056                        Bundle.getMessage("ExecuteEvaluate_Title"),
057                        JOptionPane.PLAIN_MESSAGE);
058            });
059            return;
060        }
061
062        Base obj = femaleSocket.getConnectedSocket();
063        if (obj == null) throw new NullPointerException("object is null");
064        while (obj instanceof MaleSocket) {
065            obj = ((MaleSocket)obj).getObject();
066        }
067        SwingConfiguratorInterface swi =
068                SwingTools.getSwingConfiguratorForClass(obj.getClass());
069
070        swi.executeEvaluate(femaleSocket.getConnectedSocket());
071    }
072
073    /** {@inheritDoc} */
074    @Override
075    public BaseManager<? extends NamedBean> getManager() {
076        return null;
077    }
078
079    /** {@inheritDoc} */
080    @Override
081    public JPanel getConfigPanel(@Nonnull JPanel buttonPanel) throws IllegalArgumentException {
082        // This method is used to create a new item.
083        throw new UnsupportedOperationException("Not supported");
084    }
085
086    /** {@inheritDoc} */
087    @Override
088    public JPanel getConfigPanel(@Nonnull Base object, @Nonnull JPanel buttonPanel) throws IllegalArgumentException {
089        createPanel(object, buttonPanel);
090        return panel;
091    }
092
093    /** {@inheritDoc} */
094    @Override
095    public String getExampleSystemName() {
096        throw new UnsupportedOperationException("Not supported");
097    }
098
099    /** {@inheritDoc} */
100    @Override
101    public String getAutoSystemName() {
102        throw new UnsupportedOperationException("Not supported");
103    }
104
105    protected void createPanel(@CheckForNull Base object, @Nonnull JPanel buttonPanel) {
106        // This method is never used to create a module so we expect to have a module
107        if (! (object instanceof Module)) {
108            throw new IllegalArgumentException("object is not a Module: " + object.getClass().getName());
109        }
110        Module module = (Module)object;
111
112        panel = new JPanel();
113
114        panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
115
116        JTable table = new JTable();
117        _moduleParametersTableModel = new ModuleParametersTableModel(module);
118        table.setModel(_moduleParametersTableModel);
119        table.setDefaultRenderer(SymbolTable.InitialValueType.class,
120                new ModuleParametersTableModel.TypeCellRenderer());
121        table.setDefaultEditor(SymbolTable.InitialValueType.class,
122                new ModuleParametersTableModel.TypeCellEditor());
123        table.setDefaultRenderer(ModuleParametersTableModel.Menu.class,
124                new ModuleParametersTableModel.MenuCellRenderer());
125        table.setDefaultEditor(ModuleParametersTableModel.Menu.class,
126                new ModuleParametersTableModel.MenuCellEditor(table, _moduleParametersTableModel));
127        _moduleParametersTableModel.setColumnForMenu(table);
128        JScrollPane scrollpane = new JScrollPane(table);
129        scrollpane.setPreferredSize(new Dimension(400, 200));
130        panel.add(scrollpane);
131
132        // Add parameter
133        JButton add = new JButton(Bundle.getMessage("TableAddParameter"));
134        buttonPanel.add(add);
135        add.addActionListener((ActionEvent e) -> {
136            _moduleParametersTableModel.add();
137        });
138    }
139
140    /** {@inheritDoc} */
141    @Override
142    public boolean validate(@Nonnull List<String> errorMessages) {
143        boolean hasErrors = false;
144        for (DefaultParameter p : _moduleParametersTableModel.getParameters()) {
145            if (p.getName().isEmpty()) {
146                errorMessages.add(Bundle.getMessage("ParameterNameIsEmpty", p.getName()));
147                hasErrors = true;
148            } else if (! SymbolTable.validateName(p.getName())) {
149                errorMessages.add(Bundle.getMessage("ParameterNameIsNotValid", p.getName()));
150                hasErrors = true;
151            }
152            if (!p.isInput() && !p.isOutput()) {
153                errorMessages.add(Bundle.getMessage("ParameterIsNotInNorOut", p.getName()));
154                hasErrors = true;
155            }
156        }
157
158        return !hasErrors;
159    }
160
161    /** {@inheritDoc} */
162    @Override
163    public MaleSocket createNewObject(@Nonnull String systemName, @CheckForNull String userName) {
164        throw new UnsupportedOperationException("Not supported");
165    }
166
167    /** {@inheritDoc} */
168    @Override
169    public void updateObject(@Nonnull Base object) {
170        // This method is never used to create a module so we expect to have a module
171        if (! (object instanceof Module)) {
172            throw new IllegalArgumentException("object is not a Module: " + object.getClass().getName());
173        }
174        Module module = (Module)object;
175
176        module.getParameters().clear();
177        for (Parameter p : _moduleParametersTableModel.getParameters()) {
178            module.addParameter(p);
179        }
180    }
181
182    /** {@inheritDoc} */
183    @Override
184    public String toString() {
185        return Bundle.getMessage("DefaultModule_Short");
186    }
187
188    @Override
189    public void dispose() {
190    }
191
192}