001package jmri.jmrit.ctc.editor.gui;
002
003import jmri.jmrit.ctc.NBHSensor;
004import jmri.jmrit.ctc.editor.code.AwtWindowProperties;
005import jmri.jmrit.ctc.editor.code.CheckJMRIObject;
006import jmri.jmrit.ctc.editor.code.CodeButtonHandlerDataRoutines;
007import jmri.jmrit.ctc.editor.code.CommonSubs;
008import jmri.jmrit.ctc.editor.code.ProgramProperties;
009import java.util.ArrayList;
010import jmri.jmrit.ctc.ctcserialdata.CTCSerialData;
011import jmri.jmrit.ctc.ctcserialdata.CodeButtonHandlerData;
012import jmri.jmrit.ctc.ctcserialdata.ProjectsCommonSubs;
013
014/**
015 *
016 * @author Gregory J. Bedlek Copyright (C) 2018, 2019
017 */
018public class FrmCB extends javax.swing.JFrame {
019
020    /**
021     *
022     */
023    private static final String FORM_PROPERTIES = "DlgCB";  // NOI18N
024    private static final String PREFIX = "_mOS";            // NOI18N
025    private final AwtWindowProperties _mAwtWindowProperties;
026    private boolean _mClosedNormally = false;
027    public boolean closedNormally() { return _mClosedNormally; }
028    private final CodeButtonHandlerData _mCodeButtonHandlerData;
029    private final ProgramProperties _mProgramProperties;
030    private final CTCSerialData _mCTCSerialData;
031    private final CheckJMRIObject _mCheckJMRIObject;
032    private final ArrayList<Integer> _mArrayListOfSelectableOSSectionUniqueIDs;
033
034    private String _mOSSectionOccupiedExternalSensorOrig;
035    private String _mOSSectionOccupiedExternalSensor2Orig;
036    private int _mOSSectionSwitchSlavedToUniqueIDIndexOrig;
037    private int _mCodeButtonDelayTimeOrig;
038    private void initOrig() {
039        _mOSSectionOccupiedExternalSensorOrig = _mCodeButtonHandlerData._mOSSectionOccupiedExternalSensor.getHandleName();
040        _mOSSectionOccupiedExternalSensor2Orig = _mCodeButtonHandlerData._mOSSectionOccupiedExternalSensor2.getHandleName();
041        _mOSSectionSwitchSlavedToUniqueIDIndexOrig = _mOSSectionSwitchSlavedToUniqueID.getSelectedIndex();
042        _mCodeButtonDelayTimeOrig = _mCodeButtonHandlerData._mCodeButtonDelayTime;
043    }
044    private boolean dataChanged() {
045        if (!_mOSSectionOccupiedExternalSensorOrig.equals(_mOSSectionOccupiedExternalSensor.getSelectedItem())) return true;
046        if (!_mOSSectionOccupiedExternalSensor2Orig.equals(_mOSSectionOccupiedExternalSensor2.getSelectedItem())) return true;
047        if (_mOSSectionSwitchSlavedToUniqueIDIndexOrig != _mOSSectionSwitchSlavedToUniqueID.getSelectedIndex()) return true;
048        if (CommonSubs.getIntFromJTextFieldNoThrow(_mCodeButtonDelayTime) != _mCodeButtonDelayTimeOrig) return true;
049        return false;
050    }
051
052    public FrmCB(   AwtWindowProperties awtWindowProperties, CodeButtonHandlerData codeButtonHandlerData, ProgramProperties programProperties,
053                    CTCSerialData ctcSerialData, CheckJMRIObject checkJMRIObject) {
054        super();
055        initComponents();
056        CommonSubs.addHelpMenu(this, "package.jmri.jmrit.ctc.CTC_frmCB", true);  // NOI18N
057        _mAwtWindowProperties = awtWindowProperties;
058        _mCodeButtonHandlerData = codeButtonHandlerData;
059        _mProgramProperties = programProperties;
060        _mCTCSerialData = ctcSerialData;
061        _mCheckJMRIObject = checkJMRIObject;
062        _mArrayListOfSelectableOSSectionUniqueIDs = CommonSubs.getArrayListOfSelectableOSSectionUniqueIDs(_mCTCSerialData.getCodeButtonHandlerDataArrayList());
063        CommonSubs.populateJComboBoxWithBeans(_mCodeButtonInternalSensor, "Sensor", _mCodeButtonHandlerData._mCodeButtonInternalSensor.getHandleName(), false);   // NOI18N
064        CommonSubs.populateJComboBoxWithBeans(_mOSSectionOccupiedExternalSensor, "Sensor", _mCodeButtonHandlerData._mOSSectionOccupiedExternalSensor.getHandleName(), true);   // NOI18N
065        CommonSubs.populateJComboBoxWithBeans(_mOSSectionOccupiedExternalSensor2, "Sensor", _mCodeButtonHandlerData._mOSSectionOccupiedExternalSensor2.getHandleName(), true);  // NOI18N
066        CommonSubs.populateJComboBoxWithColumnDescriptionsAndSelectViaUniqueID(_mOSSectionSwitchSlavedToUniqueID, _mCTCSerialData, _mCodeButtonHandlerData._mOSSectionSwitchSlavedToUniqueID);
067        CommonSubs.setMillisecondsEdit(_mCodeButtonDelayTime);
068        _mCodeButtonDelayTime.setText(Integer.toString(_mCodeButtonHandlerData._mCodeButtonDelayTime));
069        initOrig();
070        _mAwtWindowProperties.setWindowState(this, FORM_PROPERTIES);
071        this.getRootPane().setDefaultButton(_mSaveAndClose);
072    }
073
074    public static boolean dialogCodeButtonHandlerDataValid(CheckJMRIObject checkJMRIObject, CodeButtonHandlerData codeButtonHandlerData) {
075//  Checks:
076        if (ProjectsCommonSubs.isNullOrEmptyString(codeButtonHandlerData._mOSSectionOccupiedExternalSensor.getHandleName())) return false;
077        return checkJMRIObject.validClassWithPrefix(PREFIX, codeButtonHandlerData);
078    }
079
080//  Validate all internal fields as much as possible:
081    private ArrayList<String> formFieldsValid() {
082        ArrayList<String> errors = new ArrayList<>();
083//  Checks:
084        CommonSubs.checkJComboBoxNotEmpty(_mOSSectionOccupiedExternalSensor, _mOSSectionOccupiedExternalSensorPrompt, errors);
085        _mCheckJMRIObject.analyzeForm(PREFIX, this, errors);
086        return errors;
087    }
088
089    /**
090     * This method is called from within the constructor to initialize the form.
091     * WARNING: Do NOT modify this code. The content of this method is always
092     * regenerated by the Form Editor.
093     */
094    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
095    private void initComponents() {
096
097        _mCodeButtonInternalSensorPrompt = new javax.swing.JLabel();
098        _mCodeButtonInternalSensor = new javax.swing.JComboBox<>();
099        _mSaveAndClose = new javax.swing.JButton();
100        jButton2 = new javax.swing.JButton();
101        _mOSSectionOccupiedExternalSensorPrompt = new javax.swing.JLabel();
102        _mOSSectionSwitchSlavedToUniqueID = new javax.swing.JComboBox<>();
103        jLabel3 = new javax.swing.JLabel();
104        jLabel4 = new javax.swing.JLabel();
105        jLabel9 = new javax.swing.JLabel();
106        _mCodeButtonDelayTime = new javax.swing.JFormattedTextField();
107        jLabel5 = new javax.swing.JLabel();
108        jLabel6 = new javax.swing.JLabel();
109        jLabel7 = new javax.swing.JLabel();
110        jLabel1 = new javax.swing.JLabel();
111        _mOSSectionOccupiedExternalSensorPrompt1 = new javax.swing.JLabel();
112        jLabel2 = new javax.swing.JLabel();
113        jLabel8 = new javax.swing.JLabel();
114        jLabel10 = new javax.swing.JLabel();
115        _mOSSectionOccupiedExternalSensor = new javax.swing.JComboBox<>();
116        _mOSSectionOccupiedExternalSensor2 = new javax.swing.JComboBox<>();
117
118        setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
119        setTitle(Bundle.getMessage("TitleDlgCB"));
120        addWindowListener(new java.awt.event.WindowAdapter() {
121            @Override
122            public void windowClosing(java.awt.event.WindowEvent evt) {
123                formWindowClosing(evt);
124            }
125        });
126
127        _mCodeButtonInternalSensorPrompt.setText(Bundle.getMessage("LabelDlgCBSensor"));
128
129        _mCodeButtonInternalSensor.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
130
131        _mSaveAndClose.setText(Bundle.getMessage("ButtonSaveClose"));
132        _mSaveAndClose.addActionListener(new java.awt.event.ActionListener() {
133            @Override
134            public void actionPerformed(java.awt.event.ActionEvent evt) {
135                _mSaveAndCloseActionPerformed(evt);
136            }
137        });
138
139        jButton2.setText(Bundle.getMessage("ButtonReapply"));
140        jButton2.addActionListener(new java.awt.event.ActionListener() {
141            @Override
142            public void actionPerformed(java.awt.event.ActionEvent evt) {
143                jButton2ActionPerformed(evt);
144            }
145        });
146
147        _mOSSectionOccupiedExternalSensorPrompt.setText(Bundle.getMessage("LabelDlgCBPriSensor"));
148
149        _mOSSectionSwitchSlavedToUniqueID.addActionListener(new java.awt.event.ActionListener() {
150            @Override
151            public void actionPerformed(java.awt.event.ActionEvent evt) {
152                _mOSSectionSwitchSlavedToUniqueIDActionPerformed(evt);
153            }
154        });
155
156        jLabel3.setText(Bundle.getMessage("LabelDlgCBSwitch"));
157
158        jLabel4.setText(Bundle.getMessage("InfoDlgCBNormal"));
159
160        jLabel9.setText(Bundle.getMessage("InfoBlank"));
161
162        _mCodeButtonDelayTime.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(new javax.swing.text.NumberFormatter(new java.text.DecimalFormat("#0"))));
163
164        jLabel5.setText(Bundle.getMessage("LabelDlgCBDelay"));
165
166        jLabel6.setText(Bundle.getMessage("InfoDlgCBZero"));
167
168        jLabel7.setText(Bundle.getMessage("InfoDlgCBDelay"));
169
170        jLabel1.setText(Bundle.getMessage("InfoRequired"));
171
172        _mOSSectionOccupiedExternalSensorPrompt1.setText(Bundle.getMessage("LabelDlgCBSecSensor"));
173
174        jLabel2.setText(Bundle.getMessage("InfoOptional"));
175
176        jLabel8.setText(Bundle.getMessage("InfoDlgCBLockAll"));
177
178        jLabel10.setText(Bundle.getMessage("InfoDlgCBLockTO"));
179
180        _mOSSectionOccupiedExternalSensor.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
181
182        _mOSSectionOccupiedExternalSensor2.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
183
184        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
185        getContentPane().setLayout(layout);
186        layout.setHorizontalGroup(
187            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
188            .addGroup(layout.createSequentialGroup()
189                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
190                    .addGroup(layout.createSequentialGroup()
191                        .addContainerGap()
192                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
193                            .addGroup(layout.createSequentialGroup()
194                                .addGap(5, 5, 5)
195                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
196                                    .addComponent(_mOSSectionOccupiedExternalSensorPrompt1)
197                                    .addComponent(_mOSSectionOccupiedExternalSensorPrompt)
198                                    .addComponent(_mCodeButtonInternalSensorPrompt)
199                                    .addComponent(jLabel8)
200                                    .addComponent(jLabel10))
201                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
202                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
203                                    .addGroup(layout.createSequentialGroup()
204                                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
205                                            .addComponent(_mCodeButtonInternalSensor, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
206                                            .addComponent(_mOSSectionOccupiedExternalSensor2, javax.swing.GroupLayout.PREFERRED_SIZE, 222, javax.swing.GroupLayout.PREFERRED_SIZE))
207                                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
208                                        .addComponent(jLabel2))
209                                    .addGroup(layout.createSequentialGroup()
210                                        .addComponent(_mOSSectionOccupiedExternalSensor, javax.swing.GroupLayout.PREFERRED_SIZE, 222, javax.swing.GroupLayout.PREFERRED_SIZE)
211                                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
212                                        .addComponent(jLabel1))))
213                            .addGroup(layout.createSequentialGroup()
214                                .addGap(21, 21, 21)
215                                .addComponent(jLabel3)
216                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
217                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
218                                    .addComponent(jLabel4)
219                                    .addGroup(layout.createSequentialGroup()
220                                        .addComponent(_mOSSectionSwitchSlavedToUniqueID, javax.swing.GroupLayout.PREFERRED_SIZE, 126, javax.swing.GroupLayout.PREFERRED_SIZE)
221                                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
222                                        .addComponent(jLabel9))))
223                            .addGroup(layout.createSequentialGroup()
224                                .addComponent(jLabel5)
225                                .addGap(35, 35, 35)
226                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
227                                    .addComponent(jLabel7)
228                                    .addComponent(jLabel6)
229                                    .addComponent(_mCodeButtonDelayTime, javax.swing.GroupLayout.PREFERRED_SIZE, 93, javax.swing.GroupLayout.PREFERRED_SIZE)))))
230                    .addGroup(layout.createSequentialGroup()
231                        .addGap(170, 170, 170)
232                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
233                            .addComponent(_mSaveAndClose)
234                            .addComponent(jButton2))))
235                .addContainerGap(125, Short.MAX_VALUE))
236        );
237        layout.setVerticalGroup(
238            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
239            .addGroup(layout.createSequentialGroup()
240                .addContainerGap()
241                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
242                    .addComponent(_mCodeButtonInternalSensorPrompt)
243                    .addComponent(_mCodeButtonInternalSensor, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
244                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
245                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
246                    .addComponent(_mOSSectionOccupiedExternalSensorPrompt)
247                    .addComponent(jLabel1)
248                    .addComponent(_mOSSectionOccupiedExternalSensor, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
249                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
250                .addComponent(jLabel8)
251                .addGap(18, 18, 18)
252                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
253                    .addComponent(_mOSSectionOccupiedExternalSensorPrompt1)
254                    .addComponent(jLabel2)
255                    .addComponent(_mOSSectionOccupiedExternalSensor2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
256                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
257                .addComponent(jLabel10)
258                .addGap(26, 26, 26)
259                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
260                    .addComponent(_mOSSectionSwitchSlavedToUniqueID, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
261                    .addComponent(jLabel3)
262                    .addComponent(jLabel9))
263                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
264                .addComponent(jLabel4)
265                .addGap(18, 18, 18)
266                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
267                    .addComponent(_mCodeButtonDelayTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
268                    .addComponent(jLabel5))
269                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
270                .addComponent(jLabel6)
271                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
272                .addComponent(jLabel7)
273                .addGap(29, 29, 29)
274                .addComponent(_mSaveAndClose)
275                .addGap(18, 18, 18)
276                .addComponent(jButton2)
277                .addGap(19, 19, 19))
278        );
279
280        pack();
281    }// </editor-fold>//GEN-END:initComponents
282
283    private void _mSaveAndCloseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event__mSaveAndCloseActionPerformed
284        if (CommonSubs.missingFieldsErrorDialogDisplayed(this, formFieldsValid(), false)) {
285            return; // Do not allow exit or transfer of data.
286        }
287
288        _mCodeButtonHandlerData._mCodeButtonInternalSensor = CommonSubs.getNBHSensor((String) _mCodeButtonInternalSensor.getSelectedItem(), false);
289
290        NBHSensor newSensor = CommonSubs.getNBHSensor((String) _mOSSectionOccupiedExternalSensor.getSelectedItem(), false);
291        if (newSensor != null) _mCodeButtonHandlerData._mOSSectionOccupiedExternalSensor = newSensor;
292
293        newSensor = CommonSubs.getNBHSensor((String) _mOSSectionOccupiedExternalSensor2.getSelectedItem(), false);
294        if (newSensor != null) _mCodeButtonHandlerData._mOSSectionOccupiedExternalSensor2 = newSensor;
295
296        int selectedIndex = _mOSSectionSwitchSlavedToUniqueID.getSelectedIndex();
297        if (selectedIndex > 0) { // None and skip blank entry
298            _mCodeButtonHandlerData._mOSSectionSwitchSlavedToUniqueID = _mArrayListOfSelectableOSSectionUniqueIDs.get(selectedIndex - 1);  // Correct for blank entry
299        } else if (selectedIndex == 0) { // Blank entry:
300            _mCodeButtonHandlerData._mOSSectionSwitchSlavedToUniqueID = CodeButtonHandlerData.SWITCH_NOT_SLAVED;
301        }
302        _mCodeButtonHandlerData._mCodeButtonDelayTime = CommonSubs.getIntFromJTextFieldNoThrow(_mCodeButtonDelayTime);
303        _mClosedNormally = true;
304        _mAwtWindowProperties.saveWindowState(this, FORM_PROPERTIES);
305        dispose();
306    }//GEN-LAST:event__mSaveAndCloseActionPerformed
307
308    private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing
309        _mAwtWindowProperties.saveWindowState(this, FORM_PROPERTIES);
310        if (CommonSubs.allowClose(this, dataChanged())) dispose();
311    }//GEN-LAST:event_formWindowClosing
312
313    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed
314        CodeButtonHandlerData temp = _mCodeButtonHandlerData;
315        temp = CodeButtonHandlerDataRoutines.uECBHDWSD_CodeButton(_mProgramProperties, temp);
316        CommonSubs.populateJComboBoxWithBeans(_mCodeButtonInternalSensor, "Sensor", temp._mCodeButtonInternalSensor.getHandleName(), false);   // NOI18N
317    }//GEN-LAST:event_jButton2ActionPerformed
318
319    private void _mOSSectionSwitchSlavedToUniqueIDActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event__mOSSectionSwitchSlavedToUniqueIDActionPerformed
320//  Verify user didn't select "self", since I don't want to screw up array indexes by eliminating it:
321        int selectedIndex = _mOSSectionSwitchSlavedToUniqueID.getSelectedIndex();
322        if (selectedIndex > 0) { // None and skip blank entry
323            int osSectionSelectedUniqueID = _mArrayListOfSelectableOSSectionUniqueIDs.get(selectedIndex - 1);  // Correct for blank entry
324            if (osSectionSelectedUniqueID == _mCodeButtonHandlerData._mUniqueID) {
325                _mOSSectionSwitchSlavedToUniqueID.setSelectedIndex(0); // Back to blank!
326            }
327        }
328    }//GEN-LAST:event__mOSSectionSwitchSlavedToUniqueIDActionPerformed
329
330    // Variables declaration - do not modify//GEN-BEGIN:variables
331    private javax.swing.JFormattedTextField _mCodeButtonDelayTime;
332    private javax.swing.JComboBox<String> _mCodeButtonInternalSensor;
333    private javax.swing.JLabel _mCodeButtonInternalSensorPrompt;
334    private javax.swing.JComboBox<String> _mOSSectionOccupiedExternalSensor;
335    private javax.swing.JComboBox<String> _mOSSectionOccupiedExternalSensor2;
336    private javax.swing.JLabel _mOSSectionOccupiedExternalSensorPrompt;
337    private javax.swing.JLabel _mOSSectionOccupiedExternalSensorPrompt1;
338    private javax.swing.JComboBox<String> _mOSSectionSwitchSlavedToUniqueID;
339    private javax.swing.JButton _mSaveAndClose;
340    private javax.swing.JButton jButton2;
341    private javax.swing.JLabel jLabel1;
342    private javax.swing.JLabel jLabel10;
343    private javax.swing.JLabel jLabel2;
344    private javax.swing.JLabel jLabel3;
345    private javax.swing.JLabel jLabel4;
346    private javax.swing.JLabel jLabel5;
347    private javax.swing.JLabel jLabel6;
348    private javax.swing.JLabel jLabel7;
349    private javax.swing.JLabel jLabel8;
350    private javax.swing.JLabel jLabel9;
351    // End of variables declaration//GEN-END:variables
352}