001package jmri.jmrit.logixng.actions.swing;
002
003import java.awt.GridBagConstraints;
004import java.awt.GridBagLayout;
005import java.util.List;
006
007import javax.annotation.CheckForNull;
008import javax.annotation.Nonnull;
009import javax.swing.*;
010
011import jmri.*;
012import jmri.jmrit.logixng.*;
013import jmri.jmrit.logixng.actions.ProgramOnMain;
014import jmri.jmrit.logixng.util.swing.LogixNG_SelectComboBoxSwing;
015import jmri.jmrit.logixng.util.swing.LogixNG_SelectIntegerSwing;
016
017/**
018 * Configures an ProgramOnMain object with a Swing JPanel.
019 *
020 * @author Daniel Bergqvist Copyright 2024
021 */
022public class ProgramOnMainSwing extends AbstractDigitalActionSwing {
023
024    private LogixNG_SelectComboBoxSwing _selectProgrammingModeSwing;
025    private LogixNG_SelectIntegerSwing _selectAddressSwing;
026    private LogixNG_SelectIntegerSwing _selectCVSwing;
027    private LogixNG_SelectIntegerSwing _selectValueSwing;
028    private JComboBox<Connection> _connection;
029    private JTextField _localVariableForStatus;
030
031    @Override
032    protected void createPanel(@CheckForNull Base object, @Nonnull JPanel buttonPanel) {
033        ProgramOnMain action = (ProgramOnMain)object;
034        if (action == null) {
035            // Create a temporary action
036            action = new ProgramOnMain("IQDA1", null);
037        }
038
039        JLabel addressLabel = new JLabel(Bundle.getMessage("ProgramOnMainSwing_Address"));
040        JLabel cvLabel = new JLabel(Bundle.getMessage("ProgramOnMainSwing_CV"));
041        JLabel valueLabel = new JLabel(Bundle.getMessage("ProgramOnMainSwing_Value"));
042        JLabel connectionLabel = new JLabel(Bundle.getMessage("ProgramOnMainSwing_Connection"));
043        JLabel programmingModeLabel = new JLabel(Bundle.getMessage("ProgramOnMainSwing_ProgrammingMode"));
044        JLabel localVariableForStatusLabel = new JLabel(Bundle.getMessage("ProgramOnMainSwing_LocalVariableStatus"));
045
046        _selectProgrammingModeSwing = new LogixNG_SelectComboBoxSwing(getJDialog(), this);
047        _selectAddressSwing = new LogixNG_SelectIntegerSwing(getJDialog(), this);
048        _selectCVSwing = new LogixNG_SelectIntegerSwing(getJDialog(), this);
049        _selectValueSwing = new LogixNG_SelectIntegerSwing(getJDialog(), this);
050
051        panel = new JPanel();
052        panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
053
054        JPanel panelProgrammingMode;
055        JPanel panelAddress;
056        JPanel panelCV;
057        JPanel panelValue;
058
059        panelProgrammingMode = _selectProgrammingModeSwing.createPanel(
060                action.getSelectProgrammingMode());
061        panelAddress = _selectAddressSwing.createPanel(action.getSelectAddress());
062        panelCV = _selectCVSwing.createPanel(action.getSelectCV());
063        panelValue = _selectValueSwing.createPanel(action.getSelectValue());
064
065
066        _connection = new JComboBox<>();
067        _connection.addItem(new Connection(null));
068        List<SystemConnectionMemo> systemConnections =
069                jmri.InstanceManager.getList(SystemConnectionMemo.class);
070        for (SystemConnectionMemo connection : systemConnections) {
071            if (!connection.provides(ThrottleManager.class)) continue;
072            Connection c = new Connection(connection);
073            _connection.addItem(c);
074            if ((object != null) && (action.getMemo() == connection)) {
075                _connection.setSelectedItem(c);
076            }
077        }
078
079        _connection.addActionListener((e) -> { updateProgrammingModes(); });
080
081
082        _localVariableForStatus = new JTextField(20);
083        _localVariableForStatus.setText(action.getLocalVariableForStatus());
084
085
086        panel = new JPanel();
087        panel.setLayout(new GridBagLayout());
088        GridBagConstraints constraint = new GridBagConstraints();
089        constraint.gridwidth = 1;
090        constraint.gridheight = 1;
091        constraint.gridx = 0;
092        constraint.gridy = 0;
093        constraint.anchor = GridBagConstraints.EAST;
094        panel.add(addressLabel, constraint);
095        addressLabel.setLabelFor(panelAddress);
096        constraint.gridy = 1;
097        panel.add(cvLabel, constraint);
098        cvLabel.setLabelFor(panelCV);
099        constraint.gridy = 2;
100        panel.add(valueLabel, constraint);
101        valueLabel.setLabelFor(panelValue);
102        constraint.gridy = 3;
103        panel.add(connectionLabel, constraint);
104        connectionLabel.setLabelFor(_connection);
105        constraint.gridy = 4;
106        panel.add(programmingModeLabel, constraint);
107        programmingModeLabel.setLabelFor(panelProgrammingMode);
108        constraint.gridy = 5;
109        panel.add(localVariableForStatusLabel, constraint);
110        localVariableForStatusLabel.setLabelFor(_localVariableForStatus);
111
112        // Add some space
113        constraint.gridx = 1;
114        constraint.gridy = 0;
115        panel.add(new JLabel(" "), constraint);
116
117        constraint.gridx = 2;
118        constraint.gridy = 0;
119        constraint.anchor = GridBagConstraints.WEST;
120        panel.add(panelAddress, constraint);
121        constraint.gridy = 1;
122        panel.add(panelCV, constraint);
123        constraint.gridy = 2;
124        panel.add(panelValue, constraint);
125        constraint.gridy = 3;
126        panel.add(_connection, constraint);
127        constraint.gridy = 4;
128        panel.add(panelProgrammingMode, constraint);
129        constraint.gridy = 5;
130        panel.add(_localVariableForStatus, constraint);
131    }
132
133    private void updateProgrammingModes() {
134        // Create a temporary action to get programming modes
135        ProgramOnMain action = new ProgramOnMain("IQDA1", null);
136        action.setMemo(_connection.getItemAt(_connection.getSelectedIndex())._memo);
137        _selectProgrammingModeSwing.setValues(action.getSelectProgrammingMode().getValues());
138    }
139
140    /** {@inheritDoc} */
141    @Override
142    public boolean validate(@Nonnull List<String> errorMessages) {
143        // Create a temporary action to test formula
144        ProgramOnMain action = new ProgramOnMain("IQDA1", null);
145
146        _selectProgrammingModeSwing.validate(action.getSelectProgrammingMode(), errorMessages);
147        _selectAddressSwing.validate(action.getSelectAddress(), errorMessages);
148        _selectCVSwing.validate(action.getSelectCV(), errorMessages);
149        _selectValueSwing.validate(action.getSelectValue(), errorMessages);
150
151        return errorMessages.isEmpty();
152    }
153
154    /** {@inheritDoc} */
155    @Override
156    public MaleSocket createNewObject(@Nonnull String systemName, @CheckForNull String userName) {
157        ProgramOnMain action = new ProgramOnMain(systemName, userName);
158        updateObject(action);
159        return InstanceManager.getDefault(DigitalActionManager.class).registerAction(action);
160    }
161
162    /** {@inheritDoc} */
163    @Override
164    public void updateObject(@Nonnull Base object) {
165        if (! (object instanceof ProgramOnMain)) {
166            throw new IllegalArgumentException("object must be an ProgramOnMain but is a: "+object.getClass().getName());
167        }
168        ProgramOnMain action = (ProgramOnMain)object;
169        _selectProgrammingModeSwing.updateObject(action.getSelectProgrammingMode());
170        _selectAddressSwing.updateObject(action.getSelectAddress());
171        _selectCVSwing.updateObject(action.getSelectCV());
172        _selectValueSwing.updateObject(action.getSelectValue());
173
174        action.setMemo(_connection.getItemAt(_connection.getSelectedIndex())._memo);
175
176        action.setLocalVariableForStatus(_localVariableForStatus.getText());
177    }
178
179    /** {@inheritDoc} */
180    @Override
181    public String toString() {
182        return Bundle.getMessage("ProgramOnMain_Short");
183    }
184
185    @Override
186    public void dispose() {
187        _selectProgrammingModeSwing.dispose();
188        _selectAddressSwing.dispose();
189        _selectCVSwing.dispose();
190        _selectValueSwing.dispose();
191    }
192
193
194
195    private static class Connection {
196
197        private SystemConnectionMemo _memo;
198
199        public Connection(SystemConnectionMemo memo) {
200            _memo = memo;
201        }
202
203        @Override
204        public String toString() {
205            if (_memo == null) {
206                return Bundle.getMessage("ProgramOnMainSwing_DefaultConnection");
207            }
208            return _memo.getUserName();
209        }
210    }
211
212}