001package jmri.jmrit.ctc.editor.gui;
002
003import java.util.ArrayList;
004import javax.swing.DefaultComboBoxModel;
005import javax.swing.DefaultListModel;
006
007import jmri.*;
008import jmri.jmrit.ctc.NBHSensor;
009import jmri.jmrit.ctc.ctcserialdata.CTCSerialData;
010import jmri.jmrit.ctc.ctcserialdata.CallOnData;
011import jmri.jmrit.ctc.ctcserialdata.CodeButtonHandlerData;
012import jmri.jmrit.ctc.ctcserialdata.ProjectsCommonSubs;
013import jmri.jmrit.ctc.editor.code.AwtWindowProperties;
014import jmri.jmrit.ctc.editor.code.CheckJMRIObject;
015import jmri.jmrit.ctc.editor.code.CodeButtonHandlerDataRoutines;
016import jmri.jmrit.ctc.editor.code.CommonSubs;
017import jmri.jmrit.ctc.editor.code.ProgramProperties;
018import jmri.util.swing.JmriJOptionPane;
019
020/**
021 *
022 * @author Gregory J. Bedlek Copyright (C) 2018, 2019
023 */
024public class FrmCO extends javax.swing.JFrame {
025    /**
026     * Creates new form DlgCO
027     */
028    private static final String FORM_PROPERTIES = "DlgCO";  // NOI18N
029    private static final String PREFIX = "_mCO_";           // NOI18N
030    private final AwtWindowProperties _mAwtWindowProperties;
031    private boolean _mClosedNormally = false;
032    public boolean closedNormally() { return _mClosedNormally; }
033    private final CodeButtonHandlerData _mCodeButtonHandlerData;
034    private final ProgramProperties _mProgramProperties;
035    private final CTCSerialData _mCTCSerialData;
036    private final CheckJMRIObject _mCheckJMRIObject;
037    private final boolean _mSignalHeadSelected;
038    private final DefaultListModel<CallOnData> _mDefaultListModel;
039    private boolean _mAddNewPressed;
040    private ArrayList<CallOnData> _mDefaultListModelOrig = new ArrayList<> ();
041
042    private void initOrig() {
043        int defaultListModelSize = _mDefaultListModel.getSize();
044        for (int index = 0; index < defaultListModelSize; index++) {
045            _mDefaultListModelOrig.add(_mDefaultListModel.get(index));
046        }
047    }
048    private boolean dataChanged() {
049        int defaultListModelSize = _mDefaultListModel.getSize();
050        if (defaultListModelSize != _mDefaultListModelOrig.size()) return true;
051        for (int index = 0; index < defaultListModelSize; index++) {
052            if (!_mDefaultListModel.get(index).equals(_mDefaultListModelOrig.get(index))) return true;
053        }
054        return false;
055    }
056
057    public FrmCO(   AwtWindowProperties awtWindowProperties, CodeButtonHandlerData codeButtonHandlerData, ProgramProperties programProperties,
058                    CTCSerialData ctcSerialData, CheckJMRIObject checkJMRIObject, boolean signalHeadSelected) {
059        super();
060        initComponents();
061        CommonSubs.addHelpMenu(this, "package.jmri.jmrit.ctc.CTC_frmCO", true);  // NOI18N
062        _mSignalFacingDirection.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] {  Bundle.getMessage("InfoDlgCOLeftTraffic"),
063                                                                                                Bundle.getMessage("InfoDlgCORightTraffic") }));
064        _mSignalAspectToDisplay.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] {  Bundle.getMessage("SignalHeadStateDark"),
065                                                                                                Bundle.getMessage("SignalHeadStateRed"),
066                                                                                                Bundle.getMessage("SignalHeadStateYellow"),
067                                                                                                Bundle.getMessage("SignalHeadStateGreen"),
068                                                                                                Bundle.getMessage("SignalHeadStateFlashingRed"),
069                                                                                                Bundle.getMessage("SignalHeadStateFlashingYellow"),
070                                                                                                Bundle.getMessage("SignalHeadStateFlashingGreen"),
071                                                                                                Bundle.getMessage("SignalHeadStateLunar"),
072                                                                                                Bundle.getMessage("SignalHeadStateFlashingLunar") }));
073        _mAwtWindowProperties = awtWindowProperties;
074        _mCodeButtonHandlerData = codeButtonHandlerData;
075        _mProgramProperties = programProperties;
076        _mCTCSerialData = ctcSerialData;
077        _mCheckJMRIObject = checkJMRIObject;
078        _mSignalHeadSelected = signalHeadSelected;
079        CommonSubs.populateJComboBoxWithBeans(_mCO_CallOnToggleInternalSensor, "Sensor", _mCodeButtonHandlerData._mCO_CallOnToggleInternalSensor.getHandleName(), false);   // NOI18N
080
081        _mDefaultListModel = new DefaultListModel<>();
082        _mGroupingsList.setModel(_mDefaultListModel);
083//  Once you specify a model, then functions like JList.setListData may update the screen, but the model
084//  DOES NOT SEE ANY OF THE DATA!  Therefore, I have to load the data via the model instead of directly:
085        _mDefaultListModel.clear(); // Superflous but doesn't hurt in case GUI designer put something in there.....
086        for (CallOnData callOnData : _mCodeButtonHandlerData._mCO_GroupingsList) {
087            _mDefaultListModel.addElement(callOnData);
088        }
089        initOrig();
090
091        ArrayList<String> arrayListOfSelectableSwitchDirectionIndicators = CommonSubs.getArrayListOfSelectableSwitchDirectionIndicators(_mCTCSerialData.getCodeButtonHandlerDataArrayList());
092        arrayListOfSelectableSwitchDirectionIndicators.add(0, "");     // None is always available.
093        String[] arrayOfSelectableSwitchDirectionIndicators = new String[arrayListOfSelectableSwitchDirectionIndicators.size()];
094        arrayOfSelectableSwitchDirectionIndicators = arrayListOfSelectableSwitchDirectionIndicators.toArray(arrayOfSelectableSwitchDirectionIndicators);
095//  If I used "defaultComboBoxModel" in the calls below, that would cause ALL dropdowns to be tied together!  Changing one would change all!
096//      DefaultComboBoxModel<String> defaultComboBoxModel = new DefaultComboBoxModel<>(arrayOfSelectableSwitchDirectionIndicators);
097//  And there is NO copy constructor for "defaultComboBoxModel", ergo the hard way:
098        _mSwitchIndicator1.setModel(new DefaultComboBoxModel<>(arrayOfSelectableSwitchDirectionIndicators));
099        _mSwitchIndicator2.setModel(new DefaultComboBoxModel<>(arrayOfSelectableSwitchDirectionIndicators));
100        _mSwitchIndicator3.setModel(new DefaultComboBoxModel<>(arrayOfSelectableSwitchDirectionIndicators));
101        _mSwitchIndicator4.setModel(new DefaultComboBoxModel<>(arrayOfSelectableSwitchDirectionIndicators));
102        _mSwitchIndicator5.setModel(new DefaultComboBoxModel<>(arrayOfSelectableSwitchDirectionIndicators));
103        _mSwitchIndicator6.setModel(new DefaultComboBoxModel<>(arrayOfSelectableSwitchDirectionIndicators));
104
105        _mAwtWindowProperties.setWindowState(this, FORM_PROPERTIES);
106        enableTopPart(true);
107        _mEditBelow.setEnabled(false);
108        _mDelete.setEnabled(false);
109    }
110
111     public static boolean dialogCodeButtonHandlerDataValid(CheckJMRIObject checkJMRIObject, CodeButtonHandlerData codeButtonHandlerData) {
112         if (!codeButtonHandlerData._mCO_Enabled) return true;  // Not enabled, can be no error!
113 //  Checks:
114         for (CallOnData callOnDataRow : codeButtonHandlerData._mCO_GroupingsList) {
115             if (!checkJMRIObject.validClass(callOnDataRow)) return false;
116         }
117         return checkJMRIObject.validClassWithPrefix(PREFIX, codeButtonHandlerData);
118     }
119
120//  Validate all internal fields as much as possible:
121    private ArrayList<String> formFieldsValid() {
122        ArrayList<String> errors = new ArrayList<>();
123//  Checks:
124        _mCheckJMRIObject.analyzeForm(PREFIX, this, errors);
125        return errors;
126    }
127
128    /**
129     * This method is called from within the constructor to initialize the form.
130     * WARNING: Do NOT modify this code. The content of this method is always
131     * regenerated by the Form Editor.
132     */
133    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
134    private void initComponents() {
135
136        _mSaveAndClose = new javax.swing.JButton();
137        _mCO_CallOnToggleInternalSensorPrompt = new javax.swing.JLabel();
138        _mCO_CallOnToggleInternalSensor = new javax.swing.JComboBox<>();
139        _mGroupingsListPrompt = new javax.swing.JLabel();
140        jLabel5 = new javax.swing.JLabel();
141        jLabel6 = new javax.swing.JLabel();
142        jLabel7 = new javax.swing.JLabel();
143        jLabel8 = new javax.swing.JLabel();
144        jLabel10 = new javax.swing.JLabel();
145        jLabel11 = new javax.swing.JLabel();
146        jLabel12 = new javax.swing.JLabel();
147        jLabel13 = new javax.swing.JLabel();
148        jLabel15 = new javax.swing.JLabel();
149        _mSignalFacingDirection = new javax.swing.JComboBox<>();
150        _mSignalAspectToDisplay = new javax.swing.JComboBox<>();
151        jScrollPane1 = new javax.swing.JScrollPane();
152        _mGroupingsList = new javax.swing.JList<>();
153        _mDelete = new javax.swing.JButton();
154        _mEditBelow = new javax.swing.JButton();
155        _mAddNew = new javax.swing.JButton();
156        jLabel1 = new javax.swing.JLabel();
157        jLabel3 = new javax.swing.JLabel();
158        _mGroupingListAddReplace = new javax.swing.JButton();
159        jButton2 = new javax.swing.JButton();
160        _mCancel = new javax.swing.JButton();
161        jLabel4 = new javax.swing.JLabel();
162        jLabel16 = new javax.swing.JLabel();
163        jLabel17 = new javax.swing.JLabel();
164        jLabel9 = new javax.swing.JLabel();
165        jLabel14 = new javax.swing.JLabel();
166        _mSwitchIndicator1 = new javax.swing.JComboBox<>();
167        _mSwitchIndicator2 = new javax.swing.JComboBox<>();
168        _mSwitchIndicator3 = new javax.swing.JComboBox<>();
169        _mSwitchIndicator4 = new javax.swing.JComboBox<>();
170        _mSwitchIndicator6 = new javax.swing.JComboBox<>();
171        _mSwitchIndicator5 = new javax.swing.JComboBox<>();
172        _mExternalSignal = new javax.swing.JComboBox<>();
173        _mCalledOnExternalSensor = new javax.swing.JComboBox<>();
174        _mExternalBlock = new javax.swing.JComboBox<>();
175        jLabel18 = new javax.swing.JLabel();
176
177        setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
178        setTitle(Bundle.getMessage("TitleDlgCO"));
179        addWindowListener(new java.awt.event.WindowAdapter() {
180            @Override
181            public void windowClosing(java.awt.event.WindowEvent evt) {
182                formWindowClosing(evt);
183            }
184        });
185
186        _mSaveAndClose.setText(Bundle.getMessage("ButtonSaveClose"));
187        _mSaveAndClose.addActionListener(new java.awt.event.ActionListener() {
188            @Override
189            public void actionPerformed(java.awt.event.ActionEvent evt) {
190                _mSaveAndCloseActionPerformed(evt);
191            }
192        });
193
194        _mCO_CallOnToggleInternalSensorPrompt.setText(Bundle.getMessage("LabelDlgCOToggleSensor"));
195
196        _mCO_CallOnToggleInternalSensor.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
197
198        _mGroupingsListPrompt.setText(Bundle.getMessage("LabelDlgCOGroupingList"));
199
200        jLabel5.setText(Bundle.getMessage("InfoDlgCORow1"));
201
202        jLabel6.setText(Bundle.getMessage("InfoDlgCORow2A"));
203
204        jLabel7.setText(Bundle.getMessage("InfoDlgCORow3A"));
205
206        jLabel8.setText(Bundle.getMessage("InfoDlgCORow4A"));
207
208        jLabel10.setText(Bundle.getMessage("InfoDlgCORow5A"));
209
210        jLabel11.setText(Bundle.getMessage("InfoDlgCORow2B"));
211
212        jLabel12.setText(Bundle.getMessage("InfoDlgCORow3B"));
213
214        jLabel13.setText(Bundle.getMessage("InfoDlgCORow4B"));
215
216        jLabel15.setText(Bundle.getMessage("InfoDlgCORow5B"));
217
218        _mGroupingsList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
219        _mGroupingsList.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
220            @Override
221            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
222                _mGroupingsListValueChanged(evt);
223            }
224        });
225        jScrollPane1.setViewportView(_mGroupingsList);
226
227        _mDelete.setText(Bundle.getMessage("ButtonDelete"));
228        _mDelete.addActionListener(new java.awt.event.ActionListener() {
229            @Override
230            public void actionPerformed(java.awt.event.ActionEvent evt) {
231                _mDeleteActionPerformed(evt);
232            }
233        });
234
235        _mEditBelow.setText(Bundle.getMessage("ButtonEditBelow"));
236        _mEditBelow.addActionListener(new java.awt.event.ActionListener() {
237            @Override
238            public void actionPerformed(java.awt.event.ActionEvent evt) {
239                _mEditBelowActionPerformed(evt);
240            }
241        });
242
243        _mAddNew.setText(Bundle.getMessage("ButtonAddNew")
244        );
245        _mAddNew.addActionListener(new java.awt.event.ActionListener() {
246            @Override
247            public void actionPerformed(java.awt.event.ActionEvent evt) {
248                _mAddNewActionPerformed(evt);
249            }
250        });
251
252        jLabel1.setText(Bundle.getMessage("InfoDlgCORow2A"));
253
254        jLabel3.setText(Bundle.getMessage("InfoDlgCORow5A"));
255
256        _mGroupingListAddReplace.setText("      ");
257        _mGroupingListAddReplace.setEnabled(false);
258        _mGroupingListAddReplace.addActionListener(new java.awt.event.ActionListener() {
259            @Override
260            public void actionPerformed(java.awt.event.ActionEvent evt) {
261                _mGroupingListAddReplaceActionPerformed(evt);
262            }
263        });
264
265        jButton2.setText(Bundle.getMessage("ButtonReapply"));
266        jButton2.addActionListener(new java.awt.event.ActionListener() {
267            @Override
268            public void actionPerformed(java.awt.event.ActionEvent evt) {
269                jButton2ActionPerformed(evt);
270            }
271        });
272
273        _mCancel.setText(Bundle.getMessage("ButtonCancel"));
274        _mCancel.addActionListener(new java.awt.event.ActionListener() {
275            @Override
276            public void actionPerformed(java.awt.event.ActionEvent evt) {
277                _mCancelActionPerformed(evt);
278            }
279        });
280
281        jLabel4.setText(Bundle.getMessage("InfoDlgCORow6A"));
282
283        jLabel16.setText(Bundle.getMessage("InfoDlgCORow6A"));
284
285        jLabel17.setText(Bundle.getMessage("InfoDlgCORow6B"));
286
287        jLabel9.setText(Bundle.getMessage("InfoDlgCOSep"));
288
289        jLabel14.setText(Bundle.getMessage("InfoDlgCOSelect"));
290
291        _mSwitchIndicator1.addActionListener(new java.awt.event.ActionListener() {
292            @Override
293            public void actionPerformed(java.awt.event.ActionEvent evt) {
294                _mSwitchIndicator1ActionPerformed(evt);
295            }
296        });
297
298        jLabel18.setText(Bundle.getMessage("InfoDlgCORow4A"));
299
300        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
301        getContentPane().setLayout(layout);
302        layout.setHorizontalGroup(
303            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
304            .addGroup(layout.createSequentialGroup()
305                .addContainerGap()
306                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
307                    .addGroup(layout.createSequentialGroup()
308                        .addGap(34, 34, 34)
309                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
310                            .addComponent(jLabel7)
311                            .addComponent(jLabel8)
312                            .addComponent(jLabel6)
313                            .addComponent(jLabel10)
314                            .addComponent(jLabel16))
315                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
316                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
317                            .addComponent(jLabel11)
318                            .addComponent(jLabel12)
319                            .addComponent(jLabel13)
320                            .addComponent(jLabel15)
321                            .addComponent(jLabel17)))
322                    .addComponent(jLabel5)
323                    .addGroup(layout.createSequentialGroup()
324                        .addComponent(jButton2)
325                        .addGap(252, 252, 252)
326                        .addComponent(_mSaveAndClose))
327                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
328                        .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
329                            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
330                                .addGroup(layout.createSequentialGroup()
331                                    .addComponent(_mCO_CallOnToggleInternalSensorPrompt)
332                                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
333                                    .addComponent(_mCO_CallOnToggleInternalSensor, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
334                                .addComponent(_mGroupingsListPrompt, javax.swing.GroupLayout.Alignment.TRAILING))
335                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
336                            .addComponent(jScrollPane1)
337                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
338                            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
339                                .addComponent(_mEditBelow, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
340                                .addComponent(_mAddNew, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
341                                .addComponent(_mDelete, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
342                        .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
343                            .addGap(9, 9, 9)
344                            .addComponent(jLabel1)
345                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
346                            .addComponent(_mExternalSignal, javax.swing.GroupLayout.PREFERRED_SIZE, 158, javax.swing.GroupLayout.PREFERRED_SIZE)
347                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
348                            .addComponent(_mSignalFacingDirection, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
349                            .addGap(14, 14, 14)
350                            .addComponent(jLabel18)
351                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
352                            .addComponent(_mSignalAspectToDisplay, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
353                            .addGap(18, 18, 18)
354                            .addComponent(jLabel3)
355                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
356                            .addComponent(_mCalledOnExternalSensor, javax.swing.GroupLayout.PREFERRED_SIZE, 165, javax.swing.GroupLayout.PREFERRED_SIZE)
357                            .addGap(12, 12, 12))
358                        .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
359                            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
360                                .addComponent(jLabel9)
361                                .addComponent(jLabel14)
362                                .addGroup(layout.createSequentialGroup()
363                                    .addComponent(_mSwitchIndicator1, javax.swing.GroupLayout.PREFERRED_SIZE, 110, javax.swing.GroupLayout.PREFERRED_SIZE)
364                                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
365                                    .addComponent(_mSwitchIndicator2, javax.swing.GroupLayout.PREFERRED_SIZE, 110, javax.swing.GroupLayout.PREFERRED_SIZE)
366                                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
367                                    .addComponent(_mSwitchIndicator3, javax.swing.GroupLayout.PREFERRED_SIZE, 110, javax.swing.GroupLayout.PREFERRED_SIZE)
368                                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
369                                    .addComponent(_mSwitchIndicator4, javax.swing.GroupLayout.PREFERRED_SIZE, 110, javax.swing.GroupLayout.PREFERRED_SIZE)
370                                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
371                                    .addComponent(_mSwitchIndicator5, javax.swing.GroupLayout.PREFERRED_SIZE, 110, javax.swing.GroupLayout.PREFERRED_SIZE)
372                                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
373                                    .addComponent(_mSwitchIndicator6, javax.swing.GroupLayout.PREFERRED_SIZE, 110, javax.swing.GroupLayout.PREFERRED_SIZE)))
374                            .addGap(18, 18, 18)
375                            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
376                                .addGroup(layout.createSequentialGroup()
377                                    .addComponent(_mGroupingListAddReplace, javax.swing.GroupLayout.PREFERRED_SIZE, 340, javax.swing.GroupLayout.PREFERRED_SIZE)
378                                    .addGap(0, 66, Short.MAX_VALUE))
379                                .addGroup(layout.createSequentialGroup()
380                                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
381                                        .addGroup(layout.createSequentialGroup()
382                                            .addComponent(_mCancel)
383                                            .addGap(0, 0, Short.MAX_VALUE))
384                                        .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
385                                            .addGap(0, 0, Short.MAX_VALUE)
386                                            .addComponent(jLabel4)))
387                                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
388                                    .addComponent(_mExternalBlock, javax.swing.GroupLayout.PREFERRED_SIZE, 165, javax.swing.GroupLayout.PREFERRED_SIZE))))))
389                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
390        );
391        layout.setVerticalGroup(
392            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
393            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
394                .addContainerGap()
395                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
396                    .addGroup(layout.createSequentialGroup()
397                        .addComponent(_mGroupingsListPrompt)
398                        .addGap(45, 45, 45)
399                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
400                            .addComponent(_mCO_CallOnToggleInternalSensorPrompt)
401                            .addComponent(_mCO_CallOnToggleInternalSensor, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
402                    .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 117, javax.swing.GroupLayout.PREFERRED_SIZE)
403                    .addGroup(layout.createSequentialGroup()
404                        .addComponent(_mAddNew)
405                        .addGap(18, 18, 18)
406                        .addComponent(_mEditBelow)
407                        .addGap(18, 18, 18)
408                        .addComponent(_mDelete)))
409                .addGap(18, 18, 18)
410                .addComponent(jLabel5)
411                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
412                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
413                    .addComponent(jLabel6)
414                    .addComponent(jLabel11))
415                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
416                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
417                    .addComponent(jLabel7)
418                    .addComponent(jLabel12))
419                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
420                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
421                    .addComponent(jLabel8)
422                    .addComponent(jLabel13))
423                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
424                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
425                    .addComponent(jLabel10)
426                    .addComponent(jLabel15))
427                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
428                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
429                    .addComponent(jLabel16)
430                    .addComponent(jLabel17))
431                .addGap(18, 18, 18)
432                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
433                    .addComponent(_mSignalFacingDirection, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
434                    .addComponent(_mSignalAspectToDisplay, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
435                    .addComponent(jLabel1)
436                    .addComponent(jLabel3)
437                    .addComponent(jLabel4)
438                    .addComponent(_mExternalSignal, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
439                    .addComponent(_mCalledOnExternalSensor, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
440                    .addComponent(_mExternalBlock, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
441                    .addComponent(jLabel18))
442                .addGap(18, 18, 18)
443                .addComponent(jLabel9)
444                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
445                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
446                    .addComponent(jLabel14)
447                    .addComponent(_mCancel))
448                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
449                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
450                    .addComponent(_mSwitchIndicator1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
451                    .addComponent(_mSwitchIndicator2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
452                    .addComponent(_mSwitchIndicator3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
453                    .addComponent(_mSwitchIndicator4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
454                    .addComponent(_mSwitchIndicator5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
455                    .addComponent(_mSwitchIndicator6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
456                    .addComponent(_mGroupingListAddReplace))
457                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 8, Short.MAX_VALUE)
458                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
459                    .addComponent(_mSaveAndClose)
460                    .addComponent(jButton2))
461                .addGap(18, 18, 18))
462        );
463
464        pack();
465    }// </editor-fold>//GEN-END:initComponents
466
467    private void _mSaveAndCloseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event__mSaveAndCloseActionPerformed
468        if (CommonSubs.missingFieldsErrorDialogDisplayed(this, formFieldsValid(), false)) {
469            return; // Do not allow exit or transfer of data.
470        }
471
472        _mCodeButtonHandlerData._mCO_CallOnToggleInternalSensor = CommonSubs.getNBHSensor((String) _mCO_CallOnToggleInternalSensor.getSelectedItem(), false);
473
474        int size = _mDefaultListModel.getSize();
475        _mCodeButtonHandlerData._mCO_GroupingsList.clear();
476        for (int index = 0; index < size; index++) {
477            CallOnData thisEntry = _mDefaultListModel.getElementAt(index);
478            _mCodeButtonHandlerData._mCO_GroupingsList.add(thisEntry);
479        }
480        _mClosedNormally = true;
481        _mAwtWindowProperties.saveWindowState(this, FORM_PROPERTIES);
482        dispose();
483    }//GEN-LAST:event__mSaveAndCloseActionPerformed
484
485    private void _mAddNewActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event__mAddNewActionPerformed
486        _mAddNewPressed = true;
487        enableTopPart(false);
488        _mGroupingsList.setEnabled(false);
489        _mGroupingsList.clearSelection();
490        _mSignalFacingDirection.setSelectedIndex(0);
491        _mSignalAspectToDisplay.setSelectedIndex(4);    // Flashing Red.
492        _mGroupingListAddReplace.setText(Bundle.getMessage("TextDlgCOAddInstructions"));    // NOI18N
493        _mGroupingListAddReplace.setEnabled(true);
494        _mSwitchIndicator1.setSelectedIndex(0);
495        _mSwitchIndicator2.setSelectedIndex(0);
496        _mSwitchIndicator3.setSelectedIndex(0);
497        _mSwitchIndicator4.setSelectedIndex(0);
498        _mSwitchIndicator5.setSelectedIndex(0);
499        _mSwitchIndicator6.setSelectedIndex(0);
500        _mExternalSignal.requestFocusInWindow();
501        if (_mSignalHeadSelected) {
502            CommonSubs.populateJComboBoxWithBeans(_mExternalSignal, "SignalHead", null, false);
503            CommonSubs.populateJComboBoxWithBeans(_mCalledOnExternalSensor, "Sensor", null, false);
504            CommonSubs.populateJComboBoxWithBeans(_mExternalBlock, "Block", null, true);
505        } else {
506            CommonSubs.populateJComboBoxWithBeans(_mExternalSignal, "SignalMast", null, false);
507            CommonSubs.populateJComboBoxWithBeans(_mCalledOnExternalSensor, "Sensor", null, true);
508            CommonSubs.populateJComboBoxWithBeans(_mExternalBlock, "Block", null, false);
509        }
510    }//GEN-LAST:event__mAddNewActionPerformed
511
512    private void _mEditBelowActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event__mEditBelowActionPerformed
513        _mAddNewPressed = false;
514        int selectedIndex = _mGroupingsList.getSelectedIndex();
515        enableTopPart(false);
516        _mGroupingsList.setEnabled(false);
517        CallOnData callOnData = _mDefaultListModel.get(selectedIndex);
518        _mSignalFacingDirection.setSelectedItem(callOnData._mSignalFacingDirection);
519        _mSignalAspectToDisplay.setSelectedItem(callOnData._mSignalAspectToDisplay);
520        _mGroupingListAddReplace.setText(Bundle.getMessage("TextDlgCOUpdateInstructions")); // NOI18N
521        _mGroupingListAddReplace.setEnabled(true);
522
523        for (int i = 0; i < callOnData._mSwitchIndicators.size(); i++) {
524            if (i == 0) _mSwitchIndicator1.setSelectedItem(callOnData._mSwitchIndicators.get(i).getHandleName());
525            if (i == 1) _mSwitchIndicator2.setSelectedItem(callOnData._mSwitchIndicators.get(i).getHandleName());
526            if (i == 2) _mSwitchIndicator3.setSelectedItem(callOnData._mSwitchIndicators.get(i).getHandleName());
527            if (i == 3) _mSwitchIndicator4.setSelectedItem(callOnData._mSwitchIndicators.get(i).getHandleName());
528            if (i == 4) _mSwitchIndicator5.setSelectedItem(callOnData._mSwitchIndicators.get(i).getHandleName());
529            if (i == 5) _mSwitchIndicator6.setSelectedItem(callOnData._mSwitchIndicators.get(i).getHandleName());
530        }
531
532        _mExternalSignal.requestFocusInWindow();
533        if (_mSignalHeadSelected) {
534            CommonSubs.populateJComboBoxWithBeans(_mExternalSignal, "SignalHead", callOnData._mExternalSignal.getHandleName(), false);
535            CommonSubs.populateJComboBoxWithBeans(_mCalledOnExternalSensor, "Sensor", callOnData._mCalledOnExternalSensor.getHandleName(), false);
536            CommonSubs.populateJComboBoxWithBeans(_mExternalBlock, "Block", null, true);
537        } else {
538            CommonSubs.populateJComboBoxWithBeans(_mExternalSignal, "SignalMast", callOnData._mExternalSignal.getHandleName(), false);
539            CommonSubs.populateJComboBoxWithBeans(_mCalledOnExternalSensor, "Sensor", null, true);
540            CommonSubs.populateJComboBoxWithBeans(_mExternalBlock, "Block", callOnData._mExternalBlock.getName(), false);
541        }
542    }//GEN-LAST:event__mEditBelowActionPerformed
543
544    private void _mDeleteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event__mDeleteActionPerformed
545        _mDefaultListModel.remove(_mGroupingsList.getSelectedIndex());
546        enableTopPart(true);
547    }//GEN-LAST:event__mDeleteActionPerformed
548
549    private void _mGroupingListAddReplaceActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event__mGroupingListAddReplaceActionPerformed
550        if (ProjectsCommonSubs.isNullOrEmptyString((String) _mExternalSignal.getSelectedItem())) {
551            JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("ErrorDlgCOSignalInvalid"),
552                    Bundle.getMessage("ErrorTitle"), JmriJOptionPane.ERROR_MESSAGE); // NOI18N
553            return;
554        }
555        if (_mSignalHeadSelected) {
556            if (ProjectsCommonSubs.isNullOrEmptyString((String) _mCalledOnExternalSensor.getSelectedItem())) {
557                JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("ErrorDlgCOCalledOnSensorInvalid"),
558                        Bundle.getMessage("ErrorTitle"), JmriJOptionPane.ERROR_MESSAGE); // NOI18N
559                return;
560            }
561        } else {
562            if (ProjectsCommonSubs.isNullOrEmptyString((String) _mExternalBlock.getSelectedItem())) {
563                JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("ErrorDlgCOBlockInvalid"),
564                        Bundle.getMessage("ErrorTitle"), JmriJOptionPane.ERROR_MESSAGE); // NOI18N
565                return;
566            }
567        }
568
569        CallOnData newCallOnData = new CallOnData();
570
571        newCallOnData._mExternalSignal = CommonSubs.getNBHSignal((String) _mExternalSignal.getSelectedItem());
572        newCallOnData._mSignalFacingDirection = (_mSignalFacingDirection.getSelectedItem() == null ? null : _mSignalFacingDirection.getSelectedItem().toString());
573        newCallOnData._mSignalAspectToDisplay = (_mSignalAspectToDisplay.getSelectedItem() == null ? null : _mSignalAspectToDisplay.getSelectedItem().toString());
574        newCallOnData._mCalledOnExternalSensor = CommonSubs.getNBHSensor((String) _mCalledOnExternalSensor.getSelectedItem(), false);
575        if (newCallOnData._mCalledOnExternalSensor != null && !newCallOnData._mCalledOnExternalSensor.valid()) newCallOnData._mCalledOnExternalSensor = null;
576
577        NamedBeanHandle<Block> blockHandle = null;
578        String blockName = (String) _mExternalBlock.getSelectedItem();
579        Block block = InstanceManager.getDefault(BlockManager.class).getBlock(blockName);
580        if (block != null) {
581            blockHandle = InstanceManager.getDefault(NamedBeanHandleManager.class).getNamedBeanHandle(blockName, block);
582
583            // Check for permissive setting
584            if (!block.getPermissiveWorking()) {
585                int response = JmriJOptionPane.showConfirmDialog(this,
586                        Bundle.getMessage("WarnDlgCOBlockNotPermissive"),
587                        Bundle.getMessage("WarningTitle"),
588                        JmriJOptionPane.YES_NO_OPTION);
589                if (response == JmriJOptionPane.YES_OPTION ) {
590                    block.setPermissiveWorking(true);
591                }
592            }
593        }
594        newCallOnData._mExternalBlock = blockHandle;
595
596        ArrayList<NBHSensor> indcators = new ArrayList<>();
597        CommonSubs.addSensorToSensorList(indcators, (String)_mSwitchIndicator1.getSelectedItem());
598        CommonSubs.addSensorToSensorList(indcators, (String)_mSwitchIndicator2.getSelectedItem());
599        CommonSubs.addSensorToSensorList(indcators, (String)_mSwitchIndicator3.getSelectedItem());
600        CommonSubs.addSensorToSensorList(indcators, (String)_mSwitchIndicator4.getSelectedItem());
601        CommonSubs.addSensorToSensorList(indcators, (String)_mSwitchIndicator5.getSelectedItem());
602        CommonSubs.addSensorToSensorList(indcators, (String)_mSwitchIndicator6.getSelectedItem());
603        newCallOnData._mSwitchIndicators = indcators;
604
605        CheckJMRIObject.VerifyClassReturnValue verifyClassReturnValue = _mCheckJMRIObject.verifyClass(newCallOnData);
606        if (verifyClassReturnValue != null) { // Error:
607            JmriJOptionPane.showMessageDialog(this, verifyClassReturnValue.toString(),
608                    Bundle.getMessage("ErrorTitle"), JmriJOptionPane.ERROR_MESSAGE);    // NOI18N
609            return;
610        }
611
612        _mGroupingListAddReplace.setEnabled(false);
613        enableTopPart(true);
614        if (_mAddNewPressed) {
615            _mDefaultListModel.addElement(newCallOnData);
616        }
617        else {
618            _mDefaultListModel.set(_mGroupingsList.getSelectedIndex(), newCallOnData);
619        }
620        _mGroupingsList.setEnabled(true);
621    }//GEN-LAST:event__mGroupingListAddReplaceActionPerformed
622
623    private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing
624        _mAwtWindowProperties.saveWindowState(this, FORM_PROPERTIES);
625        if (CommonSubs.allowClose(this, dataChanged())) dispose();
626    }//GEN-LAST:event_formWindowClosing
627
628    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed
629        CodeButtonHandlerData temp = _mCodeButtonHandlerData;
630        temp = CodeButtonHandlerDataRoutines.uECBHDWSD_CallOn(_mProgramProperties, temp);
631        CommonSubs.populateJComboBoxWithBeans(_mCO_CallOnToggleInternalSensor, "Sensor", temp._mCO_CallOnToggleInternalSensor.getHandleName(), false);   // NOI18N
632    }//GEN-LAST:event_jButton2ActionPerformed
633
634    private void _mGroupingsListValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event__mGroupingsListValueChanged
635        if (_mGroupingsList.isSelectionEmpty()) {
636            _mEditBelow.setEnabled(false);
637            _mDelete.setEnabled(false);
638        } else {
639            _mEditBelow.setEnabled(true);
640            _mDelete.setEnabled(true);
641        }
642    }//GEN-LAST:event__mGroupingsListValueChanged
643
644    private void _mCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event__mCancelActionPerformed
645        enableTopPart(true);
646        _mGroupingsList.setEnabled(true);
647    }//GEN-LAST:event__mCancelActionPerformed
648
649    private void _mSwitchIndicator1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event__mSwitchIndicator1ActionPerformed
650        // TODO add your handling code here:
651    }//GEN-LAST:event__mSwitchIndicator1ActionPerformed
652
653    private void enableTopPart(boolean enabled) {
654        _mAddNew.setEnabled(enabled);
655        _mSwitchIndicator1.setEnabled(!enabled);
656        _mSwitchIndicator2.setEnabled(!enabled);
657        _mSwitchIndicator3.setEnabled(!enabled);
658        _mSwitchIndicator4.setEnabled(!enabled);
659        _mSwitchIndicator5.setEnabled(!enabled);
660        _mSwitchIndicator6.setEnabled(!enabled);
661
662        _mExternalSignal.setEnabled(!enabled);
663        _mSignalFacingDirection.setEnabled(!enabled);
664        _mSignalAspectToDisplay.setEnabled(!enabled && _mSignalHeadSelected);
665        _mCalledOnExternalSensor.setEnabled(!enabled && _mSignalHeadSelected);
666        _mExternalBlock.setEnabled(!enabled && !_mSignalHeadSelected);
667
668        _mGroupingListAddReplace.setEnabled(!enabled);
669        _mCancel.setEnabled(!enabled);
670        _mSaveAndClose.setEnabled(enabled);
671
672        if (enabled) this.getRootPane().setDefaultButton(_mSaveAndClose);
673        else this.getRootPane().setDefaultButton(_mGroupingListAddReplace);
674    }
675
676    // Variables declaration - do not modify//GEN-BEGIN:variables
677    private javax.swing.JButton _mAddNew;
678    private javax.swing.JComboBox<String> _mCO_CallOnToggleInternalSensor;
679    private javax.swing.JLabel _mCO_CallOnToggleInternalSensorPrompt;
680    private javax.swing.JComboBox<String> _mCalledOnExternalSensor;
681    private javax.swing.JButton _mCancel;
682    private javax.swing.JButton _mDelete;
683    private javax.swing.JButton _mEditBelow;
684    private javax.swing.JComboBox<String> _mExternalBlock;
685    private javax.swing.JComboBox<String> _mExternalSignal;
686    private javax.swing.JButton _mGroupingListAddReplace;
687    private javax.swing.JList<CallOnData> _mGroupingsList;
688    private javax.swing.JLabel _mGroupingsListPrompt;
689    private javax.swing.JButton _mSaveAndClose;
690    private javax.swing.JComboBox<String> _mSignalAspectToDisplay;
691    private javax.swing.JComboBox<String> _mSignalFacingDirection;
692    private javax.swing.JComboBox<String> _mSwitchIndicator1;
693    private javax.swing.JComboBox<String> _mSwitchIndicator2;
694    private javax.swing.JComboBox<String> _mSwitchIndicator3;
695    private javax.swing.JComboBox<String> _mSwitchIndicator4;
696    private javax.swing.JComboBox<String> _mSwitchIndicator5;
697    private javax.swing.JComboBox<String> _mSwitchIndicator6;
698    private javax.swing.JButton jButton2;
699    private javax.swing.JLabel jLabel1;
700    private javax.swing.JLabel jLabel10;
701    private javax.swing.JLabel jLabel11;
702    private javax.swing.JLabel jLabel12;
703    private javax.swing.JLabel jLabel13;
704    private javax.swing.JLabel jLabel14;
705    private javax.swing.JLabel jLabel15;
706    private javax.swing.JLabel jLabel16;
707    private javax.swing.JLabel jLabel17;
708    private javax.swing.JLabel jLabel18;
709    private javax.swing.JLabel jLabel3;
710    private javax.swing.JLabel jLabel4;
711    private javax.swing.JLabel jLabel5;
712    private javax.swing.JLabel jLabel6;
713    private javax.swing.JLabel jLabel7;
714    private javax.swing.JLabel jLabel8;
715    private javax.swing.JLabel jLabel9;
716    private javax.swing.JScrollPane jScrollPane1;
717    // End of variables declaration//GEN-END:variables
718
719//     private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(FrmCO.class);
720}