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