001package jmri.jmrit.operations.trains;
002
003import java.awt.Dimension;
004import java.awt.FlowLayout;
005import java.awt.GridBagConstraints;
006import java.awt.GridBagLayout;
007import java.text.MessageFormat;
008import java.util.List;
009
010import javax.swing.*;
011
012import org.slf4j.Logger;
013import org.slf4j.LoggerFactory;
014
015import jmri.InstanceManager;
016import jmri.jmrit.operations.OperationsFrame;
017import jmri.jmrit.operations.OperationsXml;
018import jmri.jmrit.operations.rollingstock.cars.CarManager;
019import jmri.jmrit.operations.rollingstock.cars.CarOwners;
020import jmri.jmrit.operations.rollingstock.cars.CarRoads;
021import jmri.jmrit.operations.rollingstock.engines.EngineManager;
022import jmri.jmrit.operations.rollingstock.engines.EngineModels;
023import jmri.jmrit.operations.routes.RouteLocation;
024import jmri.jmrit.operations.setup.Control;
025import jmri.jmrit.operations.setup.Setup;
026
027/**
028 * Frame for user edit of a train's build options
029 *
030 * @author Dan Boudreau Copyright (C) 2010, 2012, 2013
031 */
032public class TrainEditBuildOptionsFrame extends OperationsFrame implements java.beans.PropertyChangeListener {
033
034    Train _train = null;
035
036    JPanel panelOwnerNames = new JPanel();
037    JPanel panelBuilt = new JPanel();
038    JPanel panelTrainReq1 = new JPanel();
039    JPanel panelTrainReq2 = new JPanel();
040
041    JScrollPane ownerPane;
042    JScrollPane builtPane;
043    JScrollPane trainReq1Pane;
044    JScrollPane trainReq2Pane;
045
046    JPanel engine1Option = new JPanel();
047    JPanel engine1DropOption = new JPanel();
048    JPanel engine1caboose = new JPanel();
049
050    JPanel engine2Option = new JPanel();
051    JPanel engine2DropOption = new JPanel();
052    JPanel engine2caboose = new JPanel();
053
054    // labels
055    JLabel trainName = new JLabel();
056    JLabel trainDescription = new JLabel();
057    JLabel before = new JLabel(Bundle.getMessage("Before"));
058    JLabel after = new JLabel(Bundle.getMessage("After"));
059
060    // major buttons
061    JButton addOwnerButton = new JButton(Bundle.getMessage("AddOwner"));
062    JButton deleteOwnerButton = new JButton(Bundle.getMessage("DeleteOwner"));
063    JButton saveTrainButton = new JButton(Bundle.getMessage("SaveTrain"));
064
065    // radio buttons
066    JRadioButton ownerNameAll = new JRadioButton(Bundle.getMessage("AcceptAll"));
067    JRadioButton ownerNameInclude = new JRadioButton(Bundle.getMessage("AcceptOnly"));
068    JRadioButton ownerNameExclude = new JRadioButton(Bundle.getMessage("Exclude"));
069
070    JRadioButton builtDateAll = new JRadioButton(Bundle.getMessage("AcceptAll"));
071    JRadioButton builtDateAfter = new JRadioButton(Bundle.getMessage("After"));
072    JRadioButton builtDateBefore = new JRadioButton(Bundle.getMessage("Before"));
073    JRadioButton builtDateRange = new JRadioButton(Bundle.getMessage("Range"));
074
075    ButtonGroup ownerGroup = new ButtonGroup();
076    ButtonGroup builtGroup = new ButtonGroup();
077
078    // train requirements 1st set
079    JRadioButton none1 = new JRadioButton(Bundle.getMessage("None"));
080    JRadioButton change1Engine = new JRadioButton(Bundle.getMessage("EngineChange"));
081    JRadioButton modify1Caboose = new JRadioButton(Bundle.getMessage("ChangeCaboose"));
082    JRadioButton helper1Service = new JRadioButton(Bundle.getMessage("HelperService"));
083    JRadioButton remove1Caboose = new JRadioButton(Bundle.getMessage("RemoveCaboose"));
084    JRadioButton keep1Caboose = new JRadioButton(Bundle.getMessage("KeepCaboose"));
085    JRadioButton change1Caboose = new JRadioButton(Bundle.getMessage("ChangeCaboose"));
086
087    ButtonGroup trainReq1Group = new ButtonGroup();
088    ButtonGroup cabooseOption1Group = new ButtonGroup();
089
090    // train requirements 2nd set
091    JRadioButton none2 = new JRadioButton(Bundle.getMessage("None"));
092    JRadioButton change2Engine = new JRadioButton(Bundle.getMessage("EngineChange"));
093    JRadioButton modify2Caboose = new JRadioButton(Bundle.getMessage("ChangeCaboose"));
094    JRadioButton helper2Service = new JRadioButton(Bundle.getMessage("HelperService"));
095    JRadioButton remove2Caboose = new JRadioButton(Bundle.getMessage("RemoveCaboose"));
096    JRadioButton keep2Caboose = new JRadioButton(Bundle.getMessage("KeepCaboose"));
097    JRadioButton change2Caboose = new JRadioButton(Bundle.getMessage("ChangeCaboose"));
098
099    ButtonGroup trainReq2Group = new ButtonGroup();
100    ButtonGroup cabooseOption2Group = new ButtonGroup();
101
102    // check boxes
103    JCheckBox buildNormalCheckBox = new JCheckBox(Bundle.getMessage("NormalModeWhenBuilding"));
104    JCheckBox sendToTerminalCheckBox = new JCheckBox();
105    JCheckBox returnStagingCheckBox = new JCheckBox(Bundle.getMessage("AllowCarsToReturn"));
106    JCheckBox allowLocalMovesCheckBox = new JCheckBox(Bundle.getMessage("AllowLocalMoves"));
107    JCheckBox allowThroughCarsCheckBox = new JCheckBox(Bundle.getMessage("AllowThroughCars"));
108    JCheckBox serviceAllCarsCheckBox = new JCheckBox(Bundle.getMessage("ServiceAllCars"));
109    JCheckBox sendCustomStagngCheckBox = new JCheckBox(Bundle.getMessage("SendCustomToStaging"));
110    JCheckBox buildConsistCheckBox = new JCheckBox(Bundle.getMessage("BuildConsist"));
111
112    // text field
113    JTextField builtAfterTextField = new JTextField(10);
114    JTextField builtBeforeTextField = new JTextField(10);
115
116    // combo boxes
117    JComboBox<String> ownerBox = InstanceManager.getDefault(CarOwners.class).getComboBox();
118
119    // train requirements 1st set
120    JComboBox<RouteLocation> routePickup1Box = new JComboBox<>();
121    JComboBox<RouteLocation> routeDrop1Box = new JComboBox<>();
122    JComboBox<String> roadCaboose1Box = new JComboBox<>();
123    JComboBox<String> roadEngine1Box = InstanceManager.getDefault(CarRoads.class).getComboBox();
124    JComboBox<String> modelEngine1Box = InstanceManager.getDefault(EngineModels.class).getComboBox();
125    JComboBox<String> numEngines1Box = new JComboBox<>();
126
127    // train requirements 2nd set
128    JComboBox<RouteLocation> routePickup2Box = new JComboBox<>();
129    JComboBox<RouteLocation> routeDrop2Box = new JComboBox<>();
130    JComboBox<String> roadCaboose2Box = new JComboBox<>();
131    JComboBox<String> roadEngine2Box = InstanceManager.getDefault(CarRoads.class).getComboBox();
132    JComboBox<String> modelEngine2Box = InstanceManager.getDefault(EngineModels.class).getComboBox();
133    JComboBox<String> numEngines2Box = new JComboBox<>();
134
135    public static final String DISPOSE = "dispose"; // NOI18N
136
137    public TrainEditBuildOptionsFrame() {
138        super(Bundle.getMessage("MenuItemBuildOptions"));
139    }
140
141    public void initComponents(TrainEditFrame parent) {
142
143        ownerPane = new JScrollPane(panelOwnerNames);
144        ownerPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
145        ownerPane.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("OwnersTrain")));
146
147        builtPane = new JScrollPane(panelBuilt);
148        builtPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
149        builtPane.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("BuiltDatesTrain")));
150
151        trainReq1Pane = new JScrollPane(panelTrainReq1);
152        trainReq1Pane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
153        trainReq1Pane.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("TrainRequires")));
154
155        trainReq2Pane = new JScrollPane(panelTrainReq2);
156        trainReq2Pane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
157        trainReq2Pane.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("TrainRequires")));
158
159        parent.setChildFrame(this);
160        _train = parent._train;
161
162        getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
163
164        // Layout the panel by rows
165        JPanel p1 = new JPanel();
166        p1.setLayout(new BoxLayout(p1, BoxLayout.X_AXIS));
167        p1.setMaximumSize(new Dimension(2000, 250));
168
169        // Layout the panel by rows
170        // row 1a
171        JPanel pName = new JPanel();
172        pName.setLayout(new GridBagLayout());
173        pName.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Name")));
174        addItem(pName, trainName, 0, 0);
175
176        // row 1b
177        JPanel pDesc = new JPanel();
178        pDesc.setLayout(new GridBagLayout());
179        pDesc.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Description")));
180        addItem(pDesc, trainDescription, 0, 0);
181
182        p1.add(pName);
183        p1.add(pDesc);
184
185        // row 2
186        JPanel pOption = new JPanel();
187        pOption.setLayout(new GridBagLayout());
188        pOption.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Options")));
189        addItemLeft(pOption, buildNormalCheckBox, 0, 0);
190        addItemLeft(pOption, sendToTerminalCheckBox, 1, 0);
191        addItemLeft(pOption, returnStagingCheckBox, 0, 1);
192        addItemLeft(pOption, allowLocalMovesCheckBox, 1, 1);
193        addItemLeft(pOption, allowThroughCarsCheckBox, 0, 2);
194        addItemLeft(pOption, serviceAllCarsCheckBox, 1, 2);
195        addItemLeft(pOption, sendCustomStagngCheckBox, 0, 3);
196        addItemLeft(pOption, buildConsistCheckBox, 1, 3);
197        pOption.setMaximumSize(new Dimension(2000, 250));
198
199
200        buildNormalCheckBox.setEnabled(Setup.isBuildAggressive());
201        returnStagingCheckBox.setEnabled(false); // only enable if train departs and returns to same staging loc
202
203        // row 7
204        panelOwnerNames.setLayout(new GridBagLayout());
205        ownerGroup.add(ownerNameAll);
206        ownerGroup.add(ownerNameInclude);
207        ownerGroup.add(ownerNameExclude);
208
209        // row 9
210        panelBuilt.setLayout(new GridBagLayout());
211        builtAfterTextField.setToolTipText(Bundle.getMessage("EnterYearTip"));
212        builtBeforeTextField.setToolTipText(Bundle.getMessage("EnterYearTip"));
213        addItem(panelBuilt, builtDateAll, 0, 0);
214        addItem(panelBuilt, builtDateAfter, 1, 0);
215        addItem(panelBuilt, builtDateBefore, 2, 0);
216        addItem(panelBuilt, builtDateRange, 3, 0);
217        addItem(panelBuilt, after, 1, 1);
218        addItem(panelBuilt, builtAfterTextField, 2, 1);
219        addItem(panelBuilt, before, 1, 2);
220        addItem(panelBuilt, builtBeforeTextField, 2, 2);
221        builtGroup.add(builtDateAll);
222        builtGroup.add(builtDateAfter);
223        builtGroup.add(builtDateBefore);
224        builtGroup.add(builtDateRange);
225
226        // row 11
227        panelTrainReq1.setLayout(new BoxLayout(panelTrainReq1, BoxLayout.Y_AXIS));
228
229        JPanel trainOption1 = new JPanel();
230        trainOption1.add(none1);
231        trainOption1.add(change1Engine);
232        trainOption1.add(modify1Caboose);
233        trainOption1.add(helper1Service);
234        panelTrainReq1.add(trainOption1);
235
236        trainReq1Group.add(none1);
237        trainReq1Group.add(change1Engine);
238        trainReq1Group.add(modify1Caboose);
239        trainReq1Group.add(helper1Service);
240
241        // engine options
242        engine1Option.setLayout(new GridBagLayout());
243
244        for (int i = 0; i < Setup.getMaxNumberEngines() + 1; i++) {
245            numEngines1Box.addItem(Integer.toString(i));
246        }
247        numEngines1Box.setMinimumSize(new Dimension(50, 20));
248        modelEngine1Box.insertItemAt("", 0);
249        modelEngine1Box.setSelectedIndex(0);
250        modelEngine1Box.setMinimumSize(new Dimension(120, 20));
251        modelEngine1Box.setToolTipText(Bundle.getMessage("ModelEngineTip"));
252        roadEngine1Box.insertItemAt("", 0);
253        roadEngine1Box.setSelectedIndex(0);
254        roadEngine1Box.setMinimumSize(new Dimension(120, 20));
255        roadEngine1Box.setToolTipText(Bundle.getMessage("RoadEngineTip"));
256        panelTrainReq1.add(engine1Option);
257
258        // caboose options
259        engine1caboose.setLayout(new GridBagLayout());
260        engine1caboose.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("ChangeCaboose")));
261        roadCaboose1Box.setMinimumSize(new Dimension(120, 20));
262        roadCaboose1Box.setToolTipText(Bundle.getMessage("RoadCabooseTip"));
263        panelTrainReq1.add(engine1caboose);
264
265        cabooseOption1Group.add(remove1Caboose);
266        cabooseOption1Group.add(keep1Caboose);
267        cabooseOption1Group.add(change1Caboose);
268
269        // drop engine panel
270        addItem(engine1DropOption, new JLabel(Bundle.getMessage("DropEnginesAt")), 0, 0);
271        addItem(engine1DropOption, routeDrop1Box, 1, 0);
272        panelTrainReq1.add(engine1DropOption);
273
274        // row 13
275        panelTrainReq2.setLayout(new BoxLayout(panelTrainReq2, BoxLayout.Y_AXIS));
276
277        JPanel trainOption2 = new JPanel();
278        trainOption2.add(none2);
279        trainOption2.add(change2Engine);
280        trainOption2.add(modify2Caboose);
281        trainOption2.add(helper2Service);
282        panelTrainReq2.add(trainOption2);
283
284        trainReq2Group.add(none2);
285        trainReq2Group.add(change2Engine);
286        trainReq2Group.add(modify2Caboose);
287        trainReq2Group.add(helper2Service);
288
289        // engine options
290        engine2Option.setLayout(new GridBagLayout());
291
292        for (int i = 0; i < Setup.getMaxNumberEngines() + 1; i++) {
293            numEngines2Box.addItem(Integer.toString(i));
294        }
295        numEngines2Box.setMinimumSize(new Dimension(50, 20));
296        modelEngine2Box.insertItemAt("", 0);
297        modelEngine2Box.setSelectedIndex(0);
298        modelEngine2Box.setMinimumSize(new Dimension(120, 20));
299        modelEngine2Box.setToolTipText(Bundle.getMessage("ModelEngineTip"));
300        roadEngine2Box.insertItemAt("", 0);
301        roadEngine2Box.setSelectedIndex(0);
302        roadEngine2Box.setMinimumSize(new Dimension(120, 20));
303        roadEngine2Box.setToolTipText(Bundle.getMessage("RoadEngineTip"));
304        panelTrainReq2.add(engine2Option);
305
306        // caboose options
307        engine2caboose.setLayout(new GridBagLayout());
308        engine2caboose.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("ChangeCaboose")));
309        roadCaboose2Box.setMinimumSize(new Dimension(120, 20));
310        roadCaboose2Box.setToolTipText(Bundle.getMessage("RoadCabooseTip"));
311        panelTrainReq2.add(engine2caboose);
312
313        cabooseOption2Group.add(remove2Caboose);
314        cabooseOption2Group.add(keep2Caboose);
315        cabooseOption2Group.add(change2Caboose);
316
317        // drop engine panel
318        addItem(engine2DropOption, new JLabel(Bundle.getMessage("DropEnginesAt")), 0, 0);
319        addItem(engine2DropOption, routeDrop2Box, 1, 0);
320        panelTrainReq2.add(engine2DropOption);
321
322        // row 15 buttons
323        JPanel pB = new JPanel();
324        pB.setLayout(new GridBagLayout());
325        //  pB.setMaximumSize(new Dimension(2000, 250));
326        addItem(pB, saveTrainButton, 3, 0);
327
328        getContentPane().add(p1);
329        getContentPane().add(pOption);
330        getContentPane().add(ownerPane);
331        getContentPane().add(builtPane);
332        getContentPane().add(trainReq1Pane);
333        getContentPane().add(trainReq2Pane);
334        getContentPane().add(pB);
335
336        // setup buttons
337        addButtonAction(deleteOwnerButton);
338        addButtonAction(addOwnerButton);
339        addButtonAction(saveTrainButton);
340
341        addRadioButtonAction(ownerNameAll);
342        addRadioButtonAction(ownerNameInclude);
343        addRadioButtonAction(ownerNameExclude);
344
345        addRadioButtonAction(builtDateAll);
346        addRadioButtonAction(builtDateAfter);
347        addRadioButtonAction(builtDateBefore);
348        addRadioButtonAction(builtDateRange);
349
350        addRadioButtonAction(none1);
351        addRadioButtonAction(change1Engine);
352        addRadioButtonAction(modify1Caboose);
353        addRadioButtonAction(helper1Service);
354        addRadioButtonAction(remove1Caboose);
355        addRadioButtonAction(keep1Caboose);
356        addRadioButtonAction(change1Caboose);
357
358        addRadioButtonAction(none2);
359        addRadioButtonAction(change2Engine);
360        addRadioButtonAction(modify2Caboose);
361        addRadioButtonAction(helper2Service);
362        addRadioButtonAction(remove2Caboose);
363        addRadioButtonAction(keep2Caboose);
364        addRadioButtonAction(change2Caboose);
365
366        addComboBoxAction(numEngines1Box);
367        addComboBoxAction(modelEngine1Box);
368        addComboBoxAction(numEngines2Box);
369        addComboBoxAction(modelEngine2Box);
370
371        if (_train != null) {
372            trainName.setText(_train.getName());
373            trainDescription.setText(_train.getDescription());
374            buildNormalCheckBox.setSelected(_train.isBuildTrainNormalEnabled());
375            sendToTerminalCheckBox.setSelected(_train.isSendCarsToTerminalEnabled());
376            allowLocalMovesCheckBox.setSelected(_train.isAllowLocalMovesEnabled());
377            allowThroughCarsCheckBox.setSelected(_train.isAllowThroughCarsEnabled());
378            serviceAllCarsCheckBox.setSelected(_train.isServiceAllCarsWithFinalDestinationsEnabled());
379            sendCustomStagngCheckBox.setSelected(_train.isSendCarsWithCustomLoadsToStagingEnabled());
380            buildConsistCheckBox.setSelected(_train.isBuildConsistEnabled());
381            sendToTerminalCheckBox.setText(MessageFormat.format(Bundle.getMessage("SendToTerminal"),
382                    new Object[]{_train.getTrainTerminatesName()}));
383            builtAfterTextField.setText(_train.getBuiltStartYear());
384            builtBeforeTextField.setText(_train.getBuiltEndYear());
385            setBuiltRadioButton();
386            enableButtons(true);
387            // does train depart and return to same staging location?
388            updateReturnToStagingCheckbox();
389            // listen for train changes
390            _train.addPropertyChangeListener(this);
391        } else {
392            enableButtons(false);
393        }
394        addHelpMenu("package.jmri.jmrit.operations.Operations_TrainBuildOptions", true); // NOI18N
395        updateOwnerNames();
396        updateBuilt();
397        updateTrainRequires1Option();
398        updateTrainRequires2Option();
399
400        // get notified if car owners or engine models gets modified
401        InstanceManager.getDefault(CarOwners.class).addPropertyChangeListener(this);
402        InstanceManager.getDefault(EngineModels.class).addPropertyChangeListener(this);
403
404        // get notified if return to staging option changes
405        Setup.getDefault().addPropertyChangeListener(this);
406
407        initMinimumSize();
408    }
409
410    // Save
411    @Override
412    public void buttonActionPerformed(java.awt.event.ActionEvent ae) {
413        if (_train != null) {
414            if (ae.getSource() == saveTrainButton) {
415                log.debug("train save button activated");
416                saveTrain();
417            }
418            if (ae.getSource() == addOwnerButton) {
419                if (_train.addOwnerName((String) ownerBox.getSelectedItem())) {
420                    updateOwnerNames();
421                }
422                selectNextItemComboBox(ownerBox);
423            }
424            if (ae.getSource() == deleteOwnerButton) {
425                if (_train.deleteOwnerName((String) ownerBox.getSelectedItem())) {
426                    updateOwnerNames();
427                }
428                selectNextItemComboBox(ownerBox);
429            }
430        }
431    }
432
433    @Override
434    public void radioButtonActionPerformed(java.awt.event.ActionEvent ae) {
435        log.debug("radio button activated");
436        if (_train != null) {
437            if (ae.getSource() == ownerNameAll) {
438                _train.setOwnerOption(Train.ALL_OWNERS);
439                updateOwnerNames();
440            }
441            if (ae.getSource() == ownerNameInclude) {
442                _train.setOwnerOption(Train.INCLUDE_OWNERS);
443                updateOwnerNames();
444            }
445            if (ae.getSource() == ownerNameExclude) {
446                _train.setOwnerOption(Train.EXCLUDE_OWNERS);
447                updateOwnerNames();
448            }
449            if (ae.getSource() == builtDateAll ||
450                    ae.getSource() == builtDateAfter ||
451                    ae.getSource() == builtDateBefore ||
452                    ae.getSource() == builtDateRange) {
453                updateBuilt();
454            }
455            if (ae.getSource() == none1) {
456                _train.setSecondLegOptions(Train.NO_CABOOSE_OR_FRED);
457                updateTrainRequires1Option();
458                updateTrainRequires2Option();
459            }
460            if (ae.getSource() == change1Engine) {
461                _train.setSecondLegOptions(Train.CHANGE_ENGINES);
462                updateTrainRequires1Option();
463                updateTrainRequires2Option();
464            }
465            if (ae.getSource() == modify1Caboose) {
466                _train.setSecondLegOptions(Train.ADD_CABOOSE);
467                updateTrainRequires1Option();
468                updateTrainRequires2Option();
469            }
470            if (ae.getSource() == helper1Service) {
471                _train.setSecondLegOptions(Train.HELPER_ENGINES);
472                updateTrainRequires1Option();
473            }
474            if (ae.getSource() == keep1Caboose ||
475                    ae.getSource() == change1Caboose ||
476                    ae.getSource() == remove1Caboose) {
477                roadCaboose1Box.setEnabled(change1Caboose.isSelected());
478                updateTrainRequires2Option();
479            }
480            if (ae.getSource() == none2) {
481                _train.setThirdLegOptions(Train.NO_CABOOSE_OR_FRED);
482                updateTrainRequires2Option();
483            }
484            if (ae.getSource() == change2Engine) {
485                _train.setThirdLegOptions(Train.CHANGE_ENGINES);
486                updateTrainRequires2Option();
487            }
488            if (ae.getSource() == modify2Caboose) {
489                _train.setThirdLegOptions(Train.ADD_CABOOSE);
490                updateTrainRequires2Option();
491            }
492            if (ae.getSource() == helper2Service) {
493                _train.setThirdLegOptions(Train.HELPER_ENGINES);
494                updateTrainRequires2Option();
495            }
496            if (ae.getSource() == keep2Caboose ||
497                    ae.getSource() == change2Caboose ||
498                    ae.getSource() == remove2Caboose) {
499                roadCaboose2Box.setEnabled(change2Caboose.isSelected());
500            }
501        }
502    }
503
504    // Car type combo box has been changed, show loads associated with this car type
505    @Override
506    public void comboBoxActionPerformed(java.awt.event.ActionEvent ae) {
507        if (ae.getSource() == numEngines1Box) {
508            modelEngine1Box.setEnabled(!numEngines1Box.getSelectedItem().equals("0"));
509            roadEngine1Box.setEnabled(!numEngines1Box.getSelectedItem().equals("0"));
510        }
511        if (ae.getSource() == modelEngine1Box) {
512            updateEngineRoadComboBox(roadEngine1Box, (String) modelEngine1Box.getSelectedItem());
513            if (_train != null) {
514                roadEngine1Box.setSelectedItem(_train.getSecondLegEngineRoad());
515            }
516        }
517        if (ae.getSource() == numEngines2Box) {
518            modelEngine2Box.setEnabled(!numEngines2Box.getSelectedItem().equals("0"));
519            roadEngine2Box.setEnabled(!numEngines2Box.getSelectedItem().equals("0"));
520        }
521        if (ae.getSource() == modelEngine2Box) {
522            updateEngineRoadComboBox(roadEngine2Box, (String) modelEngine2Box.getSelectedItem());
523            if (_train != null) {
524                roadEngine2Box.setSelectedItem(_train.getThirdLegEngineRoad());
525            }
526        }
527    }
528
529    private void updateOwnerNames() {
530        panelOwnerNames.removeAll();
531
532        JPanel p = new JPanel();
533        p.setLayout(new GridBagLayout());
534        p.add(ownerNameAll, 0);
535        p.add(ownerNameInclude, 1);
536        p.add(ownerNameExclude, 2);
537        GridBagConstraints gc = new GridBagConstraints();
538        gc.gridwidth = 6;
539        panelOwnerNames.add(p, gc);
540
541        int y = 1; // vertical position in panel
542
543        if (_train != null) {
544            // set radio button
545            ownerNameAll.setSelected(_train.getOwnerOption().equals(Train.ALL_OWNERS));
546            ownerNameInclude.setSelected(_train.getOwnerOption().equals(Train.INCLUDE_OWNERS));
547            ownerNameExclude.setSelected(_train.getOwnerOption().equals(Train.EXCLUDE_OWNERS));
548
549            if (!ownerNameAll.isSelected()) {
550                p = new JPanel();
551                p.setLayout(new FlowLayout());
552                p.add(ownerBox);
553                p.add(addOwnerButton);
554                p.add(deleteOwnerButton);
555                gc.gridy = y++;
556                panelOwnerNames.add(p, gc);
557
558                int x = 0;
559                for (String ownerName : _train.getOwnerNames()) {
560                    JLabel owner = new JLabel();
561                    owner.setText(ownerName);
562                    addItem(panelOwnerNames, owner, x++, y);
563                    if (x > 6) {
564                        y++;
565                        x = 0;
566                    }
567                }
568            }
569        } else {
570            ownerNameAll.setSelected(true);
571        }
572        panelOwnerNames.revalidate();
573        panelOwnerNames.repaint();
574        revalidate();
575    }
576
577    private void setBuiltRadioButton() {
578        if (_train.getBuiltStartYear().equals(Train.NONE) && _train.getBuiltEndYear().equals(Train.NONE)) {
579            builtDateAll.setSelected(true);
580        } else if (!_train.getBuiltStartYear().equals(Train.NONE) && !_train.getBuiltEndYear().equals(Train.NONE)) {
581            builtDateRange.setSelected(true);
582        } else if (!_train.getBuiltStartYear().equals(Train.NONE)) {
583            builtDateAfter.setSelected(true);
584        } else if (!_train.getBuiltEndYear().equals(Train.NONE)) {
585            builtDateBefore.setSelected(true);
586        }
587    }
588
589    private void updateBuilt() {
590        builtAfterTextField.setVisible(false);
591        builtBeforeTextField.setVisible(false);
592        after.setVisible(false);
593        before.setVisible(false);
594        if (builtDateAll.isSelected()) {
595            builtAfterTextField.setText("");
596            builtBeforeTextField.setText("");
597        } else if (builtDateAfter.isSelected()) {
598            builtBeforeTextField.setText("");
599            builtAfterTextField.setVisible(true);
600            after.setVisible(true);
601        } else if (builtDateBefore.isSelected()) {
602            builtAfterTextField.setText("");
603            builtBeforeTextField.setVisible(true);
604            before.setVisible(true);
605        } else if (builtDateRange.isSelected()) {
606            after.setVisible(true);
607            before.setVisible(true);
608            builtAfterTextField.setVisible(true);
609            builtBeforeTextField.setVisible(true);
610        }
611        revalidate();
612    }
613
614    private void updateTrainRequires1Option() {
615        none1.setSelected(true);
616        if (_train != null) {
617
618            updateCabooseRoadComboBox(roadCaboose1Box);
619            updateEngineRoadComboBox(roadEngine1Box, (String) modelEngine1Box.getSelectedItem());
620            if (_train.getRoute() != null) {
621                _train.getRoute().updateComboBox(routePickup1Box);
622                _train.getRoute().updateComboBox(routeDrop1Box);
623            }
624
625            change1Engine.setSelected((_train.getSecondLegOptions() & Train.CHANGE_ENGINES) == Train.CHANGE_ENGINES);
626            helper1Service.setSelected((_train.getSecondLegOptions() & Train.HELPER_ENGINES) == Train.HELPER_ENGINES);
627            if (!change1Engine.isSelected() && !helper1Service.isSelected()) {
628                modify1Caboose.setSelected((_train.getSecondLegOptions() & Train.ADD_CABOOSE) == Train.ADD_CABOOSE ||
629                        (_train.getSecondLegOptions() & Train.REMOVE_CABOOSE) == Train.REMOVE_CABOOSE);
630            }
631            numEngines1Box.setSelectedItem(_train.getSecondLegNumberEngines());
632            modelEngine1Box.setSelectedItem(_train.getSecondLegEngineModel());
633            routePickup1Box.setSelectedItem(_train.getSecondLegStartRouteLocation());
634            routeDrop1Box.setSelectedItem(_train.getSecondLegEndRouteLocation());
635            roadEngine1Box.setSelectedItem(_train.getSecondLegEngineRoad());
636            keep1Caboose.setSelected(true);
637            remove1Caboose.setSelected((_train.getSecondLegOptions() & Train.REMOVE_CABOOSE) == Train.REMOVE_CABOOSE);
638            change1Caboose.setSelected((_train.getSecondLegOptions() & Train.ADD_CABOOSE) == Train.ADD_CABOOSE);
639            roadCaboose1Box.setEnabled(change1Caboose.isSelected());
640            roadCaboose1Box.setSelectedItem(_train.getSecondLegCabooseRoad());
641            // adjust radio button text
642            if (_train.isCabooseNeeded()) {
643                change1Caboose.setText(Bundle.getMessage("ChangeCaboose"));
644                remove1Caboose.setEnabled(true);
645            } else {
646                change1Caboose.setText(Bundle.getMessage("AddCaboose"));
647                remove1Caboose.setEnabled(false);
648            }
649        }
650        engine1Option.setVisible(change1Engine.isSelected() || helper1Service.isSelected());
651        engine1caboose.setVisible(change1Engine.isSelected() || modify1Caboose.isSelected());
652        engine1DropOption.setVisible(helper1Service.isSelected());
653        engine1Option.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("EngineChange")));
654        if (change1Engine.isSelected() || helper1Service.isSelected()) {
655            createEngine1Panel();
656        }
657        if (change1Engine.isSelected() || modify1Caboose.isSelected()) {
658            createCaboose1Panel(modify1Caboose.isSelected());
659        }
660        if (helper1Service.isSelected()) {
661            engine1Option.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("AddHelpers")));
662        }
663        revalidate();
664    }
665
666    private void updateTrainRequires2Option() {
667        none2.setSelected(true);
668        if (_train != null) {
669
670            updateCabooseRoadComboBox(roadCaboose2Box);
671            updateEngineRoadComboBox(roadEngine2Box, (String) modelEngine2Box.getSelectedItem());
672            if (_train.getRoute() != null) {
673                _train.getRoute().updateComboBox(routePickup2Box);
674                _train.getRoute().updateComboBox(routeDrop2Box);
675            }
676
677            change2Engine.setSelected((_train.getThirdLegOptions() & Train.CHANGE_ENGINES) == Train.CHANGE_ENGINES);
678            helper2Service.setSelected((_train.getThirdLegOptions() & Train.HELPER_ENGINES) == Train.HELPER_ENGINES);
679            if (!change2Engine.isSelected() && !helper2Service.isSelected()) {
680                modify2Caboose.setSelected((_train.getThirdLegOptions() & Train.ADD_CABOOSE) == Train.ADD_CABOOSE ||
681                        (_train.getThirdLegOptions() & Train.REMOVE_CABOOSE) == Train.REMOVE_CABOOSE);
682            }
683            numEngines2Box.setSelectedItem(_train.getThirdLegNumberEngines());
684            modelEngine2Box.setSelectedItem(_train.getThirdLegEngineModel());
685            routePickup2Box.setSelectedItem(_train.getThirdLegStartRouteLocation());
686            routeDrop2Box.setSelectedItem(_train.getThirdLegEndRouteLocation());
687            roadEngine2Box.setSelectedItem(_train.getThirdLegEngineRoad());
688            keep2Caboose.setSelected(true);
689            remove2Caboose.setSelected((_train.getThirdLegOptions() & Train.REMOVE_CABOOSE) == Train.REMOVE_CABOOSE);
690            change2Caboose.setSelected((_train.getThirdLegOptions() & Train.ADD_CABOOSE) == Train.ADD_CABOOSE);
691            roadCaboose2Box.setEnabled(change2Caboose.isSelected());
692            roadCaboose2Box.setSelectedItem(_train.getThirdLegCabooseRoad());
693            // adjust radio button text
694            if ((_train.isCabooseNeeded() || change1Caboose.isSelected()) &&
695                    !remove1Caboose.isSelected()) {
696                change2Caboose.setText(Bundle.getMessage("ChangeCaboose"));
697                remove2Caboose.setEnabled(true);
698            } else {
699                change2Caboose.setText(Bundle.getMessage("AddCaboose"));
700                remove2Caboose.setEnabled(false);
701            }
702        }
703        engine2Option.setVisible(change2Engine.isSelected() || helper2Service.isSelected());
704        engine2caboose.setVisible(change2Engine.isSelected() || modify2Caboose.isSelected());
705        engine2DropOption.setVisible(helper2Service.isSelected());
706        engine2Option.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("EngineChange")));
707        if (change2Engine.isSelected() || helper2Service.isSelected()) {
708            createEngine2Panel();
709        }
710        if (change2Engine.isSelected() || modify2Caboose.isSelected()) {
711            createCaboose2Panel(modify2Caboose.isSelected());
712        }
713        if (helper2Service.isSelected()) {
714            engine2Option.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("AddHelpers")));
715        }
716        revalidate();
717    }
718
719    private void saveTrain() {
720        if (!checkInput()) {
721            return;
722        }
723        _train.setBuildTrainNormalEnabled(buildNormalCheckBox.isSelected());
724        _train.setSendCarsToTerminalEnabled(sendToTerminalCheckBox.isSelected());
725        if (returnStagingCheckBox.isEnabled()) {
726            _train.setAllowReturnToStagingEnabled(returnStagingCheckBox.isSelected());
727        }
728        _train.setAllowLocalMovesEnabled(allowLocalMovesCheckBox.isSelected());
729        _train.setAllowThroughCarsEnabled(allowThroughCarsCheckBox.isSelected());
730        _train.setServiceAllCarsWithFinalDestinationsEnabled(serviceAllCarsCheckBox.isSelected());
731        _train.setSendCarsWithCustomLoadsToStagingEnabled(sendCustomStagngCheckBox.isSelected());
732        _train.setBuildConsistEnabled(buildConsistCheckBox.isSelected());
733        _train.setBuiltStartYear(builtAfterTextField.getText().trim());
734        _train.setBuiltEndYear(builtBeforeTextField.getText().trim());
735
736        int options1 = Train.NO_CABOOSE_OR_FRED;
737        if (change1Engine.isSelected()) {
738            options1 = options1 | Train.CHANGE_ENGINES;
739        }
740        if (remove1Caboose.isSelected()) {
741            options1 = options1 | Train.REMOVE_CABOOSE;
742        } else if (change1Caboose.isSelected()) {
743            options1 = options1 | Train.ADD_CABOOSE | Train.REMOVE_CABOOSE;
744        }
745        if (helper1Service.isSelected()) {
746            options1 = options1 | Train.HELPER_ENGINES;
747        }
748        _train.setSecondLegOptions(options1);
749        if (routePickup1Box.getSelectedItem() != null) {
750            _train.setSecondLegStartRouteLocation((RouteLocation) routePickup1Box.getSelectedItem());
751        } else {
752            _train.setSecondLegStartRouteLocation(null);
753        }
754        if (routeDrop1Box.getSelectedItem() != null) {
755            _train.setSecondLegEndRouteLocation((RouteLocation) routeDrop1Box.getSelectedItem());
756        } else {
757            _train.setSecondLegEndRouteLocation(null);
758        }
759        _train.setSecondLegNumberEngines((String) numEngines1Box.getSelectedItem());
760        _train.setSecondLegEngineModel((String) modelEngine1Box.getSelectedItem());
761        _train.setSecondLegEngineRoad((String) roadEngine1Box.getSelectedItem());
762        _train.setSecondLegCabooseRoad((String) roadCaboose1Box.getSelectedItem());
763
764        int options2 = Train.NO_CABOOSE_OR_FRED;
765        if (change2Engine.isSelected()) {
766            options2 = options2 | Train.CHANGE_ENGINES;
767        }
768        if (remove2Caboose.isSelected()) {
769            options2 = options2 | Train.REMOVE_CABOOSE;
770        } else if (change2Caboose.isSelected()) {
771            options2 = options2 | Train.ADD_CABOOSE | Train.REMOVE_CABOOSE;
772        }
773        if (helper2Service.isSelected()) {
774            options2 = options2 | Train.HELPER_ENGINES;
775        }
776        _train.setThirdLegOptions(options2);
777        if (routePickup2Box.getSelectedItem() != null) {
778            _train.setThirdLegStartRouteLocation((RouteLocation) routePickup2Box.getSelectedItem());
779        } else {
780            _train.setThirdLegStartRouteLocation(null);
781        }
782        if (routeDrop2Box.getSelectedItem() != null) {
783            _train.setThirdLegEndRouteLocation((RouteLocation) routeDrop2Box.getSelectedItem());
784        } else {
785            _train.setThirdLegEndRouteLocation(null);
786        }
787        _train.setThirdLegNumberEngines((String) numEngines2Box.getSelectedItem());
788        _train.setThirdLegEngineModel((String) modelEngine2Box.getSelectedItem());
789        _train.setThirdLegEngineRoad((String) roadEngine2Box.getSelectedItem());
790        _train.setThirdLegCabooseRoad((String) roadCaboose2Box.getSelectedItem());
791
792        OperationsXml.save();
793        if (Setup.isCloseWindowOnSaveEnabled()) {
794            dispose();
795        }
796    }
797
798    private boolean checkInput() {
799        if ((!none1.isSelected() && routePickup1Box.getSelectedItem() == null) ||
800                (!none2.isSelected() && routePickup2Box.getSelectedItem() == null)) {
801            JOptionPane.showMessageDialog(this, Bundle.getMessage("SelectLocationEngChange"), Bundle
802                    .getMessage("CanNotSave"), JOptionPane.ERROR_MESSAGE);
803            return false;
804        }
805        if ((helper1Service.isSelected() && routeDrop1Box.getSelectedItem() == null) ||
806                (helper2Service.isSelected() && routeDrop2Box.getSelectedItem() == null)) {
807            JOptionPane.showMessageDialog(this, Bundle.getMessage("SelectLocationEndHelper"), Bundle
808                    .getMessage("CanNotSave"), JOptionPane.ERROR_MESSAGE);
809            return false;
810        }
811        try {
812            if (!builtAfterTextField.getText().trim().isEmpty()) {
813                Integer.parseInt(builtAfterTextField.getText().trim());
814            }
815            if (!builtBeforeTextField.getText().trim().isEmpty()) {
816                Integer.parseInt(builtBeforeTextField.getText().trim());
817            }
818        } catch (NumberFormatException e) {
819            JOptionPane.showMessageDialog(this, Bundle.getMessage("EnterFourDigitYear"), Bundle
820                    .getMessage("CanNotSave"), JOptionPane.ERROR_MESSAGE);
821            return false;
822        }
823        return true;
824    }
825
826    private void enableButtons(boolean enabled) {
827        ownerNameAll.setEnabled(enabled);
828        ownerNameInclude.setEnabled(enabled);
829        ownerNameExclude.setEnabled(enabled);
830
831        builtDateAll.setEnabled(enabled);
832        builtDateAfter.setEnabled(enabled);
833        builtDateBefore.setEnabled(enabled);
834        builtDateRange.setEnabled(enabled);
835
836        none1.setEnabled(enabled);
837        change1Engine.setEnabled(enabled);
838        modify1Caboose.setEnabled(enabled);
839        helper1Service.setEnabled(enabled);
840
841        none2.setEnabled(enabled);
842        change2Engine.setEnabled(enabled);
843        modify2Caboose.setEnabled(enabled);
844        helper2Service.setEnabled(enabled);
845
846        saveTrainButton.setEnabled(enabled);
847    }
848
849    private void updateModelComboBoxes() {
850        InstanceManager.getDefault(EngineModels.class).updateComboBox(modelEngine1Box);
851        InstanceManager.getDefault(EngineModels.class).updateComboBox(modelEngine2Box);
852        modelEngine1Box.insertItemAt("", 0);
853        modelEngine2Box.insertItemAt("", 0);
854        if (_train != null) {
855            modelEngine1Box.setSelectedItem(_train.getSecondLegEngineModel());
856            modelEngine2Box.setSelectedItem(_train.getThirdLegEngineModel());
857        }
858    }
859
860    private void updateOwnerComboBoxes() {
861        InstanceManager.getDefault(CarOwners.class).updateComboBox(ownerBox);
862    }
863
864    // update caboose road box based on radio selection
865    private void updateCabooseRoadComboBox(JComboBox<String> box) {
866        box.removeAllItems();
867        box.addItem("");
868        List<String> roads = InstanceManager.getDefault(CarManager.class).getCabooseRoadNames();
869        for (String road : roads) {
870            box.addItem(road);
871        }
872    }
873
874    private void updateEngineRoadComboBox(JComboBox<String> box, String engineModel) {
875        if (engineModel == null) {
876            return;
877        }
878        box.removeAllItems();
879        box.addItem("");
880        List<String> roads = InstanceManager.getDefault(EngineManager.class).getEngineRoadNames(engineModel);
881        for (String road : roads) {
882            box.addItem(road);
883        }
884    }
885
886    private void updateReturnToStagingCheckbox() {
887        if (_train != null &&
888                _train.getTrainDepartsRouteLocation() != null &&
889                _train.getTrainTerminatesRouteLocation() != null &&
890                _train.getTrainTerminatesRouteLocation().getLocation() != null &&
891                _train.getTrainTerminatesRouteLocation().getLocation().isStaging() &&
892                _train.getTrainDepartsRouteLocation().getName().equals(
893                        _train.getTrainTerminatesRouteLocation().getName())) {
894            allowThroughCarsCheckBox.setEnabled(false);
895            if (Setup.isAllowReturnToStagingEnabled()) {
896                returnStagingCheckBox.setEnabled(false);
897                returnStagingCheckBox.setSelected(true);
898                returnStagingCheckBox.setToolTipText(Bundle.getMessage("TipReturnToStaging"));
899            } else {
900                returnStagingCheckBox.setEnabled(true);
901                returnStagingCheckBox.setSelected(_train.isAllowReturnToStagingEnabled());
902                returnStagingCheckBox.setToolTipText("");
903            }
904        }
905    }
906
907    private void createEngine1Panel() {
908        engine1Option.removeAll();
909        addItem(engine1Option, new JLabel(Bundle.getMessage("ChangeEnginesAt")), 0, 0);
910        addItem(engine1Option, routePickup1Box, 1, 0);
911        addItem(engine1Option, new JLabel(Bundle.getMessage("Engines")), 2, 0);
912        addItem(engine1Option, numEngines1Box, 3, 0);
913        addItem(engine1Option, new JLabel(Bundle.getMessage("Model")), 4, 0);
914        addItem(engine1Option, modelEngine1Box, 5, 0);
915        addItem(engine1Option, new JLabel(Bundle.getMessage("Road")), 6, 0);
916        addItem(engine1Option, roadEngine1Box, 7, 0);
917    }
918
919    private void createEngine2Panel() {
920        engine2Option.removeAll();
921        addItem(engine2Option, new JLabel(Bundle.getMessage("ChangeEnginesAt")), 0, 0);
922        addItem(engine2Option, routePickup2Box, 1, 0);
923        addItem(engine2Option, new JLabel(Bundle.getMessage("Engines")), 2, 0);
924        addItem(engine2Option, numEngines2Box, 3, 0);
925        addItem(engine2Option, new JLabel(Bundle.getMessage("Model")), 4, 0);
926        addItem(engine2Option, modelEngine2Box, 5, 0);
927        addItem(engine2Option, new JLabel(Bundle.getMessage("Road")), 6, 0);
928        addItem(engine2Option, roadEngine2Box, 7, 0);
929    }
930
931    private void createCaboose1Panel(boolean withCombox) {
932        engine1caboose.removeAll();
933        addItem(engine1caboose, remove1Caboose, 2, 6);
934        addItem(engine1caboose, change1Caboose, 4, 6);
935        addItem(engine1caboose, new JLabel(Bundle.getMessage("Road")), 5, 6);
936        addItem(engine1caboose, roadCaboose1Box, 6, 6);
937        if (withCombox) {
938            addItem(engine1caboose, new JLabel(Bundle.getMessage("ChangeEnginesAt")), 0, 6);
939            addItem(engine1caboose, routePickup1Box, 1, 6);
940        } else {
941            addItem(engine1caboose, keep1Caboose, 3, 6);
942        }
943    }
944
945    private void createCaboose2Panel(boolean withCombox) {
946        engine2caboose.removeAll();
947        addItem(engine2caboose, remove2Caboose, 2, 6);
948        addItem(engine2caboose, change2Caboose, 4, 6);
949        addItem(engine2caboose, new JLabel(Bundle.getMessage("Road")), 5, 6);
950        addItem(engine2caboose, roadCaboose2Box, 6, 6);
951        if (withCombox) {
952            addItem(engine2caboose, new JLabel(Bundle.getMessage("ChangeEnginesAt")), 0, 6);
953            addItem(engine2caboose, routePickup2Box, 1, 6);
954        } else {
955            addItem(engine2caboose, keep2Caboose, 3, 6);
956        }
957    }
958
959    /*
960     * private boolean checkModel(String model, String numberEngines){ if
961     * (numberEngines.equals("0") || model.equals("")) return true; String type
962     * = InstanceManager.getDefault(EngineModels.class).getModelType(model);
963     * if(_train.acceptsTypeName(type)) return true;
964     * JOptionPane.showMessageDialog(this,
965     * MessageFormat.format(Bundle.getMessage("TrainModelService"), new Object[]
966     * {model, type}), MessageFormat.format(Bundle.getMessage("CanNot"), new
967     * Object[] {Bundle.getMessage("save")}), JOptionPane.ERROR_MESSAGE); return
968     * false; }
969     */
970    @Override
971    public void dispose() {
972        InstanceManager.getDefault(CarOwners.class).removePropertyChangeListener(this);
973        InstanceManager.getDefault(EngineModels.class).removePropertyChangeListener(this);
974        Setup.getDefault().removePropertyChangeListener(this);
975        if (_train != null) {
976            _train.removePropertyChangeListener(this);
977        }
978        super.dispose();
979    }
980
981    @Override
982    public void propertyChange(java.beans.PropertyChangeEvent e) {
983        if (Control.SHOW_PROPERTY) {
984            log.debug("Property change: ({}) old: ({}) new: ({})", e.getPropertyName(), e.getOldValue(), e
985                    .getNewValue());
986        }
987        if (e.getPropertyName().equals(CarOwners.CAROWNERS_CHANGED_PROPERTY)) {
988            updateOwnerComboBoxes();
989            updateOwnerNames();
990        }
991        if (e.getPropertyName().equals(EngineModels.ENGINEMODELS_CHANGED_PROPERTY) ||
992                e.getPropertyName().equals(Train.TYPES_CHANGED_PROPERTY)) {
993            updateModelComboBoxes();
994        }
995        if (e.getPropertyName().equals(Train.TRAIN_REQUIREMENTS_CHANGED_PROPERTY)) {
996            updateTrainRequires1Option();
997            updateTrainRequires2Option();
998        }
999        if (e.getPropertyName().equals(Setup.ALLOW_CARS_TO_RETURN_PROPERTY_CHANGE)) {
1000            updateReturnToStagingCheckbox();
1001        }
1002    }
1003
1004    private final static Logger log = LoggerFactory.getLogger(TrainEditBuildOptionsFrame.class);
1005}