001package jmri.jmrit.display.logixng.swing;
002
003import java.awt.GridBagConstraints;
004import java.awt.GridBagLayout;
005import java.util.*;
006
007import javax.annotation.CheckForNull;
008import javax.annotation.Nonnull;
009import javax.swing.*;
010
011import jmri.InstanceManager;
012import jmri.jmrit.logixng.*;
013import jmri.jmrit.display.logixng.WindowManagement;
014import jmri.jmrit.display.logixng.WindowManagement.HideOrShow;
015import jmri.jmrit.display.logixng.WindowManagement.MaximizeMinimizeNormalize;
016import jmri.jmrit.display.logixng.WindowManagement.BringToFrontOrBack;
017import jmri.jmrit.logixng.actions.swing.AbstractDigitalActionSwing;
018import jmri.jmrit.logixng.util.parser.ParserException;
019import jmri.jmrit.logixng.util.swing.LogixNG_SelectEnumSwing;
020import jmri.util.JmriJFrame;
021import jmri.util.swing.JComboBoxUtil;
022
023/**
024 * Configures an WindowManagement object with a Swing JPanel.
025 *
026 * @author Daniel Bergqvist Copyright (C) 2024
027 */
028public class WindowManagementSwing extends AbstractDigitalActionSwing {
029
030    private JComboBox<JmriJFrameItem> _jmriJFrameComboBox;
031    private JTabbedPane _tabbedPaneJmriJFrame;
032    private JPanel _panelJmriJFrameDirect;
033    private JPanel _panelJmriJFrameReference;
034    private JPanel _panelJmriJFrameLocalVariable;
035    private JPanel _panelJmriJFrameFormula;
036    private JTextField _jmriJFrameReferenceTextField;
037    private JTextField _jmriJFrameLocalVariableTextField;
038    private JTextField _jmriJFrameFormulaTextField;
039    private JCheckBox _ignoreWindowNotFoundCheckBox;
040
041    private LogixNG_SelectEnumSwing<HideOrShow> _selectEnumHideOrShowSwing;
042    private LogixNG_SelectEnumSwing<MaximizeMinimizeNormalize> _selectEnumMaximizeMinimizeNormalizeSwing;
043    private LogixNG_SelectEnumSwing<BringToFrontOrBack> _selectEnumBringToFrontOrBackSwing;
044
045
046    @Override
047    protected void createPanel(@CheckForNull Base object, @Nonnull JPanel buttonPanel) {
048        WindowManagement action = (WindowManagement)object;
049
050        _selectEnumHideOrShowSwing = new LogixNG_SelectEnumSwing<>(getJDialog(), this);
051        _selectEnumMaximizeMinimizeNormalizeSwing = new LogixNG_SelectEnumSwing<>(getJDialog(), this);
052        _selectEnumBringToFrontOrBackSwing = new LogixNG_SelectEnumSwing<>(getJDialog(), this);
053
054        panel = new JPanel();
055
056        String _selectedJmriJFrameTitle = action != null ? action.getJmriJFrameTitle() : null;
057
058        _tabbedPaneJmriJFrame = new JTabbedPane();
059        _panelJmriJFrameDirect = new javax.swing.JPanel();
060        _panelJmriJFrameReference = new javax.swing.JPanel();
061        _panelJmriJFrameLocalVariable = new javax.swing.JPanel();
062        _panelJmriJFrameFormula = new javax.swing.JPanel();
063
064        _tabbedPaneJmriJFrame.addTab(NamedBeanAddressing.Direct.toString(), _panelJmriJFrameDirect);
065        _tabbedPaneJmriJFrame.addTab(NamedBeanAddressing.Reference.toString(), _panelJmriJFrameReference);
066        _tabbedPaneJmriJFrame.addTab(NamedBeanAddressing.LocalVariable.toString(), _panelJmriJFrameLocalVariable);
067        _tabbedPaneJmriJFrame.addTab(NamedBeanAddressing.Formula.toString(), _panelJmriJFrameFormula);
068
069        _jmriJFrameComboBox = new JComboBox<>();
070        JComboBoxUtil.setupComboBoxMaxRows(_jmriJFrameComboBox);
071        for (JmriJFrame jmriJFrame : JmriJFrame.getFrameList()) {
072            JmriJFrameItem item = new JmriJFrameItem(jmriJFrame);
073            _jmriJFrameComboBox.addItem(item);
074            if (jmriJFrame.getTitle().equals(_selectedJmriJFrameTitle)) {
075                _jmriJFrameComboBox.setSelectedItem(item);
076            }
077        }
078        _panelJmriJFrameDirect.add(_jmriJFrameComboBox);
079
080        _jmriJFrameReferenceTextField = new JTextField();
081        _jmriJFrameReferenceTextField.setColumns(30);
082        _panelJmriJFrameReference.add(_jmriJFrameReferenceTextField);
083
084        _jmriJFrameLocalVariableTextField = new JTextField();
085        _jmriJFrameLocalVariableTextField.setColumns(30);
086        _panelJmriJFrameLocalVariable.add(_jmriJFrameLocalVariableTextField);
087
088        _jmriJFrameFormulaTextField = new JTextField();
089        _jmriJFrameFormulaTextField.setColumns(30);
090        _panelJmriJFrameFormula.add(_jmriJFrameFormulaTextField);
091
092
093        _ignoreWindowNotFoundCheckBox = new JCheckBox(Bundle.getMessage("WindowManagement_IgnoreWindowNotFound"));
094
095
096        JPanel panelHideOrShow;
097        JPanel panelMaximizeMinimizeNormalize;
098        JPanel panelBringToFrontOrBack;
099        if (action != null) {
100            panelHideOrShow = _selectEnumHideOrShowSwing.createPanel(
101                    action.getSelectEnumHideOrShow(), HideOrShow.values());
102            panelMaximizeMinimizeNormalize = _selectEnumMaximizeMinimizeNormalizeSwing
103                    .createPanel(action.getSelectEnumMaximizeMinimizeNormalize(),
104                            MaximizeMinimizeNormalize.values());
105            panelBringToFrontOrBack = _selectEnumBringToFrontOrBackSwing
106                    .createPanel(action.getSelectEnumBringToFrontOrBack(),
107                            BringToFrontOrBack.values());
108        } else {
109            panelHideOrShow = _selectEnumHideOrShowSwing
110                    .createPanel(null, HideOrShow.values());
111            panelMaximizeMinimizeNormalize = _selectEnumMaximizeMinimizeNormalizeSwing
112                    .createPanel(null, MaximizeMinimizeNormalize.values());
113            panelBringToFrontOrBack = _selectEnumBringToFrontOrBackSwing
114                    .createPanel(null, BringToFrontOrBack.values());
115        }
116
117        if (action != null) {
118            switch (action.getAddressing()) {
119                case Direct: _tabbedPaneJmriJFrame.setSelectedComponent(_panelJmriJFrameDirect); break;
120                case Reference: _tabbedPaneJmriJFrame.setSelectedComponent(_panelJmriJFrameReference); break;
121                case LocalVariable: _tabbedPaneJmriJFrame.setSelectedComponent(_panelJmriJFrameLocalVariable); break;
122                case Formula: _tabbedPaneJmriJFrame.setSelectedComponent(_panelJmriJFrameFormula); break;
123                default: throw new IllegalArgumentException("invalid _addressing state: " + action.getAddressing().name());
124            }
125            _jmriJFrameReferenceTextField.setText(action.getReference());
126            _jmriJFrameLocalVariableTextField.setText(action.getLocalVariable());
127            _jmriJFrameFormulaTextField.setText(action.getFormula());
128            _ignoreWindowNotFoundCheckBox.setSelected(action.isIgnoreWindowNotFound());
129        }
130
131        panel.setLayout(new GridBagLayout());
132        GridBagConstraints constraint = new GridBagConstraints();
133        constraint.gridwidth = 1;
134        constraint.gridheight = 1;
135        constraint.gridx = 0;
136        constraint.gridy = 0;
137        constraint.anchor = GridBagConstraints.EAST;
138        panel.add(new JLabel(Bundle.getMessage("WindowToFrontSwing_Window")), constraint);
139        constraint.gridy = 4;
140        panel.add(new JLabel(Bundle.getMessage("WindowToFrontSwing_HideOrShow")), constraint);
141        constraint.gridy = 5;
142        panel.add(new JLabel(Bundle.getMessage("WindowToFrontSwing_MaximizeMinimizeNormalize")), constraint);
143        constraint.gridy = 6;
144        panel.add(new JLabel(Bundle.getMessage("WindowToFrontSwing_BringToFrontOrBack")), constraint);
145
146        constraint.gridx = 1;
147        constraint.gridy = 0;
148        constraint.anchor = GridBagConstraints.WEST;
149        panel.add(_tabbedPaneJmriJFrame, constraint);
150        constraint.gridy = 1;
151        panel.add(Box.createVerticalStrut(3), constraint);
152        constraint.gridy = 2;
153        panel.add(_ignoreWindowNotFoundCheckBox, constraint);
154        constraint.gridy = 3;
155        panel.add(Box.createVerticalStrut(5), constraint);
156        constraint.gridy = 4;
157        panel.add(panelHideOrShow, constraint);
158        constraint.gridy = 5;
159        panel.add(panelMaximizeMinimizeNormalize, constraint);
160        constraint.gridy = 6;
161        panel.add(panelBringToFrontOrBack, constraint);
162    }
163
164    /** {@inheritDoc} */
165    @Override
166    public boolean validate(@Nonnull List<String> errorMessages) {
167        // Create a temporary action to test formula
168        WindowManagement action = new WindowManagement("IQDA1", null);
169
170        try {
171            if (_tabbedPaneJmriJFrame.getSelectedComponent() == _panelJmriJFrameReference) {
172                action.setReference(_jmriJFrameReferenceTextField.getText());
173            }
174        } catch (IllegalArgumentException e) {
175            errorMessages.add(e.getMessage());
176            return false;
177        }
178
179        try {
180            action.setFormula(_jmriJFrameFormulaTextField.getText());
181            if (_tabbedPaneJmriJFrame.getSelectedComponent() == _panelJmriJFrameDirect) {
182                action.setAddressing(NamedBeanAddressing.Direct);
183            } else if (_tabbedPaneJmriJFrame.getSelectedComponent() == _panelJmriJFrameReference) {
184                action.setAddressing(NamedBeanAddressing.Reference);
185            } else if (_tabbedPaneJmriJFrame.getSelectedComponent() == _panelJmriJFrameLocalVariable) {
186                action.setAddressing(NamedBeanAddressing.LocalVariable);
187            } else if (_tabbedPaneJmriJFrame.getSelectedComponent() == _panelJmriJFrameFormula) {
188                action.setAddressing(NamedBeanAddressing.Formula);
189            } else {
190                throw new IllegalArgumentException("_tabbedPane has unknown selection");
191            }
192        } catch (ParserException e) {
193            errorMessages.add("Cannot parse formula: " + e.getMessage());
194        }
195
196        _selectEnumHideOrShowSwing.validate(action.getSelectEnumHideOrShow(), errorMessages);
197        _selectEnumMaximizeMinimizeNormalizeSwing.validate(action.getSelectEnumMaximizeMinimizeNormalize(), errorMessages);
198        _selectEnumBringToFrontOrBackSwing.validate(action.getSelectEnumBringToFrontOrBack(), errorMessages);
199
200        return errorMessages.isEmpty();
201    }
202
203    /** {@inheritDoc} */
204    @Override
205    public MaleSocket createNewObject(@Nonnull String systemName, @CheckForNull String userName) {
206        WindowManagement action = new WindowManagement(systemName, userName);
207        updateObject(action);
208        return InstanceManager.getDefault(DigitalActionManager.class).registerAction(action);
209    }
210
211    /** {@inheritDoc} */
212    @Override
213    public void updateObject(@Nonnull Base object) {
214        if (! (object instanceof WindowManagement)) {
215            throw new IllegalArgumentException("object must be an WindowToFront but is a: "+object.getClass().getName());
216        }
217        WindowManagement action = (WindowManagement)object;
218        if (_tabbedPaneJmriJFrame.getSelectedComponent() == _panelJmriJFrameDirect) {
219            if (_jmriJFrameComboBox.getSelectedIndex() != -1) {
220                action.setJmriJFrame(_jmriJFrameComboBox.getItemAt(_jmriJFrameComboBox.getSelectedIndex())._frame);
221            }
222        }
223        try {
224            if (_tabbedPaneJmriJFrame.getSelectedComponent() == _panelJmriJFrameDirect) {
225                action.setAddressing(NamedBeanAddressing.Direct);
226            } else if (_tabbedPaneJmriJFrame.getSelectedComponent() == _panelJmriJFrameReference) {
227                action.setAddressing(NamedBeanAddressing.Reference);
228                action.setReference(_jmriJFrameReferenceTextField.getText());
229            } else if (_tabbedPaneJmriJFrame.getSelectedComponent() == _panelJmriJFrameLocalVariable) {
230                action.setAddressing(NamedBeanAddressing.LocalVariable);
231                action.setLocalVariable(_jmriJFrameLocalVariableTextField.getText());
232            } else if (_tabbedPaneJmriJFrame.getSelectedComponent() == _panelJmriJFrameFormula) {
233                action.setAddressing(NamedBeanAddressing.Formula);
234                action.setFormula(_jmriJFrameFormulaTextField.getText());
235            } else {
236                throw new IllegalArgumentException("_tabbedPaneJmriJFrame has unknown selection");
237            }
238        } catch (ParserException e) {
239            throw new RuntimeException("ParserException: "+e.getMessage(), e);
240        }
241
242        action.setIgnoreWindowNotFound(_ignoreWindowNotFoundCheckBox.isSelected());
243
244        _selectEnumHideOrShowSwing.updateObject(action.getSelectEnumHideOrShow());
245
246        _selectEnumMaximizeMinimizeNormalizeSwing.updateObject(
247                action.getSelectEnumMaximizeMinimizeNormalize());
248
249        _selectEnumBringToFrontOrBackSwing.updateObject(
250                action.getSelectEnumBringToFrontOrBack());
251    }
252
253    /** {@inheritDoc} */
254    @Override
255    public String toString() {
256        return Bundle.getMessage("WindowManagement_Short");
257    }
258
259    @Override
260    public void dispose() {
261        _selectEnumHideOrShowSwing.dispose();
262        _selectEnumMaximizeMinimizeNormalizeSwing.dispose();
263        _selectEnumBringToFrontOrBackSwing.dispose();
264    }
265
266
267
268    private static class JmriJFrameItem {
269
270        private final JmriJFrame _frame;
271
272        public JmriJFrameItem(JmriJFrame frame) {
273            this._frame = frame;
274        }
275
276        @Override
277        public String toString() {
278            return _frame.getTitle();
279        }
280    }
281
282
283//    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(WindowToFrontSwing.class);
284
285}