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