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.addItem(Train.AUTO_HPT);
248        numEngines1Box.setMinimumSize(new Dimension(50, 20));
249        modelEngine1Box.insertItemAt("", 0);
250        modelEngine1Box.setSelectedIndex(0);
251        modelEngine1Box.setMinimumSize(new Dimension(120, 20));
252        modelEngine1Box.setToolTipText(Bundle.getMessage("ModelEngineTip"));
253        roadEngine1Box.insertItemAt("", 0);
254        roadEngine1Box.setSelectedIndex(0);
255        roadEngine1Box.setMinimumSize(new Dimension(120, 20));
256        roadEngine1Box.setToolTipText(Bundle.getMessage("RoadEngineTip"));
257        panelTrainReq1.add(engine1Option);
258
259        // caboose options
260        engine1caboose.setLayout(new GridBagLayout());
261        engine1caboose.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("ChangeCaboose")));
262        roadCaboose1Box.setMinimumSize(new Dimension(120, 20));
263        roadCaboose1Box.setToolTipText(Bundle.getMessage("RoadCabooseTip"));
264        panelTrainReq1.add(engine1caboose);
265
266        cabooseOption1Group.add(remove1Caboose);
267        cabooseOption1Group.add(keep1Caboose);
268        cabooseOption1Group.add(change1Caboose);
269
270        // drop engine panel
271        addItem(engine1DropOption, new JLabel(Bundle.getMessage("DropEnginesAt")), 0, 0);
272        addItem(engine1DropOption, routeDrop1Box, 1, 0);
273        panelTrainReq1.add(engine1DropOption);
274
275        // row 13
276        panelTrainReq2.setLayout(new BoxLayout(panelTrainReq2, BoxLayout.Y_AXIS));
277
278        JPanel trainOption2 = new JPanel();
279        trainOption2.add(none2);
280        trainOption2.add(change2Engine);
281        trainOption2.add(modify2Caboose);
282        trainOption2.add(helper2Service);
283        panelTrainReq2.add(trainOption2);
284
285        trainReq2Group.add(none2);
286        trainReq2Group.add(change2Engine);
287        trainReq2Group.add(modify2Caboose);
288        trainReq2Group.add(helper2Service);
289
290        // engine options
291        engine2Option.setLayout(new GridBagLayout());
292
293        for (int i = 0; i < Setup.getMaxNumberEngines() + 1; i++) {
294            numEngines2Box.addItem(Integer.toString(i));
295        }
296        numEngines2Box.addItem(Train.AUTO_HPT);
297        numEngines2Box.setMinimumSize(new Dimension(50, 20));
298        modelEngine2Box.insertItemAt("", 0);
299        modelEngine2Box.setSelectedIndex(0);
300        modelEngine2Box.setMinimumSize(new Dimension(120, 20));
301        modelEngine2Box.setToolTipText(Bundle.getMessage("ModelEngineTip"));
302        roadEngine2Box.insertItemAt("", 0);
303        roadEngine2Box.setSelectedIndex(0);
304        roadEngine2Box.setMinimumSize(new Dimension(120, 20));
305        roadEngine2Box.setToolTipText(Bundle.getMessage("RoadEngineTip"));
306        panelTrainReq2.add(engine2Option);
307
308        // caboose options
309        engine2caboose.setLayout(new GridBagLayout());
310        engine2caboose.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("ChangeCaboose")));
311        roadCaboose2Box.setMinimumSize(new Dimension(120, 20));
312        roadCaboose2Box.setToolTipText(Bundle.getMessage("RoadCabooseTip"));
313        panelTrainReq2.add(engine2caboose);
314
315        cabooseOption2Group.add(remove2Caboose);
316        cabooseOption2Group.add(keep2Caboose);
317        cabooseOption2Group.add(change2Caboose);
318
319        // drop engine panel
320        addItem(engine2DropOption, new JLabel(Bundle.getMessage("DropEnginesAt")), 0, 0);
321        addItem(engine2DropOption, routeDrop2Box, 1, 0);
322        panelTrainReq2.add(engine2DropOption);
323
324        // row 15 buttons
325        JPanel pB = new JPanel();
326        pB.setLayout(new GridBagLayout());
327        //  pB.setMaximumSize(new Dimension(2000, 250));
328        addItem(pB, saveTrainButton, 3, 0);
329
330        getContentPane().add(p1);
331        getContentPane().add(pOption);
332        getContentPane().add(ownerPane);
333        getContentPane().add(builtPane);
334        getContentPane().add(trainReq1Pane);
335        getContentPane().add(trainReq2Pane);
336        getContentPane().add(pB);
337
338        // setup buttons
339        addButtonAction(deleteOwnerButton);
340        addButtonAction(addOwnerButton);
341        addButtonAction(saveTrainButton);
342
343        addRadioButtonAction(ownerNameAll);
344        addRadioButtonAction(ownerNameInclude);
345        addRadioButtonAction(ownerNameExclude);
346
347        addRadioButtonAction(builtDateAll);
348        addRadioButtonAction(builtDateAfter);
349        addRadioButtonAction(builtDateBefore);
350        addRadioButtonAction(builtDateRange);
351
352        addRadioButtonAction(none1);
353        addRadioButtonAction(change1Engine);
354        addRadioButtonAction(modify1Caboose);
355        addRadioButtonAction(helper1Service);
356        addRadioButtonAction(remove1Caboose);
357        addRadioButtonAction(keep1Caboose);
358        addRadioButtonAction(change1Caboose);
359
360        addRadioButtonAction(none2);
361        addRadioButtonAction(change2Engine);
362        addRadioButtonAction(modify2Caboose);
363        addRadioButtonAction(helper2Service);
364        addRadioButtonAction(remove2Caboose);
365        addRadioButtonAction(keep2Caboose);
366        addRadioButtonAction(change2Caboose);
367
368        addComboBoxAction(numEngines1Box);
369        addComboBoxAction(modelEngine1Box);
370        addComboBoxAction(numEngines2Box);
371        addComboBoxAction(modelEngine2Box);
372
373        if (_train != null) {
374            trainName.setText(_train.getName());
375            trainDescription.setText(_train.getDescription());
376            buildNormalCheckBox.setSelected(_train.isBuildTrainNormalEnabled());
377            sendToTerminalCheckBox.setSelected(_train.isSendCarsToTerminalEnabled());
378            allowLocalMovesCheckBox.setSelected(_train.isAllowLocalMovesEnabled());
379            allowThroughCarsCheckBox.setSelected(_train.isAllowThroughCarsEnabled());
380            serviceAllCarsCheckBox.setSelected(_train.isServiceAllCarsWithFinalDestinationsEnabled());
381            sendCustomStagngCheckBox.setSelected(_train.isSendCarsWithCustomLoadsToStagingEnabled());
382            buildConsistCheckBox.setSelected(_train.isBuildConsistEnabled());
383            sendToTerminalCheckBox.setText(MessageFormat.format(Bundle.getMessage("SendToTerminal"),
384                    new Object[]{_train.getTrainTerminatesName()}));
385            builtAfterTextField.setText(_train.getBuiltStartYear());
386            builtBeforeTextField.setText(_train.getBuiltEndYear());
387            setBuiltRadioButton();
388            enableButtons(true);
389            // does train depart and return to same staging location?
390            updateReturnToStagingCheckbox();
391            // listen for train changes
392            _train.addPropertyChangeListener(this);
393        } else {
394            enableButtons(false);
395        }
396        addHelpMenu("package.jmri.jmrit.operations.Operations_TrainBuildOptions", true); // NOI18N
397        updateOwnerNames();
398        updateBuilt();
399        updateTrainRequires1Option();
400        updateTrainRequires2Option();
401
402        // get notified if car owners or engine models gets modified
403        InstanceManager.getDefault(CarOwners.class).addPropertyChangeListener(this);
404        InstanceManager.getDefault(EngineModels.class).addPropertyChangeListener(this);
405
406        // get notified if return to staging option changes
407        Setup.getDefault().addPropertyChangeListener(this);
408
409        initMinimumSize(new Dimension(Control.panelWidth600, Control.panelHeight600));
410    }
411
412    // Save
413    @Override
414    public void buttonActionPerformed(java.awt.event.ActionEvent ae) {
415        if (_train != null) {
416            if (ae.getSource() == saveTrainButton) {
417                log.debug("train save button activated");
418                saveTrain();
419            }
420            if (ae.getSource() == addOwnerButton) {
421                if (_train.addOwnerName((String) ownerBox.getSelectedItem())) {
422                    updateOwnerNames();
423                }
424                selectNextItemComboBox(ownerBox);
425            }
426            if (ae.getSource() == deleteOwnerButton) {
427                if (_train.deleteOwnerName((String) ownerBox.getSelectedItem())) {
428                    updateOwnerNames();
429                }
430                selectNextItemComboBox(ownerBox);
431            }
432        }
433    }
434
435    @Override
436    public void radioButtonActionPerformed(java.awt.event.ActionEvent ae) {
437        log.debug("radio button activated");
438        if (_train != null) {
439            if (ae.getSource() == ownerNameAll) {
440                _train.setOwnerOption(Train.ALL_OWNERS);
441                updateOwnerNames();
442            }
443            if (ae.getSource() == ownerNameInclude) {
444                _train.setOwnerOption(Train.INCLUDE_OWNERS);
445                updateOwnerNames();
446            }
447            if (ae.getSource() == ownerNameExclude) {
448                _train.setOwnerOption(Train.EXCLUDE_OWNERS);
449                updateOwnerNames();
450            }
451            if (ae.getSource() == builtDateAll ||
452                    ae.getSource() == builtDateAfter ||
453                    ae.getSource() == builtDateBefore ||
454                    ae.getSource() == builtDateRange) {
455                updateBuilt();
456            }
457            if (ae.getSource() == none1) {
458                _train.setSecondLegOptions(Train.NO_CABOOSE_OR_FRED);
459                updateTrainRequires1Option();
460                updateTrainRequires2Option();
461            }
462            if (ae.getSource() == change1Engine) {
463                _train.setSecondLegOptions(Train.CHANGE_ENGINES);
464                updateTrainRequires1Option();
465                updateTrainRequires2Option();
466            }
467            if (ae.getSource() == modify1Caboose) {
468                _train.setSecondLegOptions(Train.ADD_CABOOSE);
469                updateTrainRequires1Option();
470                updateTrainRequires2Option();
471            }
472            if (ae.getSource() == helper1Service) {
473                _train.setSecondLegOptions(Train.HELPER_ENGINES);
474                updateTrainRequires1Option();
475            }
476            if (ae.getSource() == keep1Caboose ||
477                    ae.getSource() == change1Caboose ||
478                    ae.getSource() == remove1Caboose) {
479                roadCaboose1Box.setEnabled(change1Caboose.isSelected());
480                updateTrainRequires2Option();
481            }
482            if (ae.getSource() == none2) {
483                _train.setThirdLegOptions(Train.NO_CABOOSE_OR_FRED);
484                updateTrainRequires2Option();
485            }
486            if (ae.getSource() == change2Engine) {
487                _train.setThirdLegOptions(Train.CHANGE_ENGINES);
488                updateTrainRequires2Option();
489            }
490            if (ae.getSource() == modify2Caboose) {
491                _train.setThirdLegOptions(Train.ADD_CABOOSE);
492                updateTrainRequires2Option();
493            }
494            if (ae.getSource() == helper2Service) {
495                _train.setThirdLegOptions(Train.HELPER_ENGINES);
496                updateTrainRequires2Option();
497            }
498            if (ae.getSource() == keep2Caboose ||
499                    ae.getSource() == change2Caboose ||
500                    ae.getSource() == remove2Caboose) {
501                roadCaboose2Box.setEnabled(change2Caboose.isSelected());
502            }
503        }
504    }
505
506    // Car type combo box has been changed, show loads associated with this car type
507    @Override
508    public void comboBoxActionPerformed(java.awt.event.ActionEvent ae) {
509        if (ae.getSource() == numEngines1Box) {
510            modelEngine1Box.setEnabled(!numEngines1Box.getSelectedItem().equals("0"));
511            roadEngine1Box.setEnabled(!numEngines1Box.getSelectedItem().equals("0"));
512        }
513        if (ae.getSource() == modelEngine1Box) {
514            updateEngineRoadComboBox(roadEngine1Box, (String) modelEngine1Box.getSelectedItem());
515            if (_train != null) {
516                roadEngine1Box.setSelectedItem(_train.getSecondLegEngineRoad());
517            }
518        }
519        if (ae.getSource() == numEngines2Box) {
520            modelEngine2Box.setEnabled(!numEngines2Box.getSelectedItem().equals("0"));
521            roadEngine2Box.setEnabled(!numEngines2Box.getSelectedItem().equals("0"));
522        }
523        if (ae.getSource() == modelEngine2Box) {
524            updateEngineRoadComboBox(roadEngine2Box, (String) modelEngine2Box.getSelectedItem());
525            if (_train != null) {
526                roadEngine2Box.setSelectedItem(_train.getThirdLegEngineRoad());
527            }
528        }
529    }
530
531    private void updateOwnerNames() {
532        panelOwnerNames.removeAll();
533
534        JPanel p = new JPanel();
535        p.setLayout(new GridBagLayout());
536        p.add(ownerNameAll, 0);
537        p.add(ownerNameInclude, 1);
538        p.add(ownerNameExclude, 2);
539        GridBagConstraints gc = new GridBagConstraints();
540        gc.gridwidth = 6;
541        panelOwnerNames.add(p, gc);
542
543        int y = 1; // vertical position in panel
544
545        if (_train != null) {
546            // set radio button
547            ownerNameAll.setSelected(_train.getOwnerOption().equals(Train.ALL_OWNERS));
548            ownerNameInclude.setSelected(_train.getOwnerOption().equals(Train.INCLUDE_OWNERS));
549            ownerNameExclude.setSelected(_train.getOwnerOption().equals(Train.EXCLUDE_OWNERS));
550
551            if (!ownerNameAll.isSelected()) {
552                p = new JPanel();
553                p.setLayout(new FlowLayout());
554                p.add(ownerBox);
555                p.add(addOwnerButton);
556                p.add(deleteOwnerButton);
557                gc.gridy = y++;
558                panelOwnerNames.add(p, gc);
559
560                int x = 0;
561                for (String ownerName : _train.getOwnerNames()) {
562                    JLabel owner = new JLabel();
563                    owner.setText(ownerName);
564                    addItem(panelOwnerNames, owner, x++, y);
565                    if (x > 6) {
566                        y++;
567                        x = 0;
568                    }
569                }
570            }
571        } else {
572            ownerNameAll.setSelected(true);
573        }
574        panelOwnerNames.revalidate();
575        panelOwnerNames.repaint();
576        revalidate();
577    }
578
579    private void setBuiltRadioButton() {
580        if (_train.getBuiltStartYear().equals(Train.NONE) && _train.getBuiltEndYear().equals(Train.NONE)) {
581            builtDateAll.setSelected(true);
582        } else if (!_train.getBuiltStartYear().equals(Train.NONE) && !_train.getBuiltEndYear().equals(Train.NONE)) {
583            builtDateRange.setSelected(true);
584        } else if (!_train.getBuiltStartYear().equals(Train.NONE)) {
585            builtDateAfter.setSelected(true);
586        } else if (!_train.getBuiltEndYear().equals(Train.NONE)) {
587            builtDateBefore.setSelected(true);
588        }
589    }
590
591    private void updateBuilt() {
592        builtAfterTextField.setVisible(false);
593        builtBeforeTextField.setVisible(false);
594        after.setVisible(false);
595        before.setVisible(false);
596        if (builtDateAll.isSelected()) {
597            builtAfterTextField.setText("");
598            builtBeforeTextField.setText("");
599        } else if (builtDateAfter.isSelected()) {
600            builtBeforeTextField.setText("");
601            builtAfterTextField.setVisible(true);
602            after.setVisible(true);
603        } else if (builtDateBefore.isSelected()) {
604            builtAfterTextField.setText("");
605            builtBeforeTextField.setVisible(true);
606            before.setVisible(true);
607        } else if (builtDateRange.isSelected()) {
608            after.setVisible(true);
609            before.setVisible(true);
610            builtAfterTextField.setVisible(true);
611            builtBeforeTextField.setVisible(true);
612        }
613        revalidate();
614    }
615
616    private void updateTrainRequires1Option() {
617        none1.setSelected(true);
618        if (_train != null) {
619
620            updateCabooseRoadComboBox(roadCaboose1Box);
621            updateEngineRoadComboBox(roadEngine1Box, (String) modelEngine1Box.getSelectedItem());
622            if (_train.getRoute() != null) {
623                _train.getRoute().updateComboBox(routePickup1Box);
624                _train.getRoute().updateComboBox(routeDrop1Box);
625            }
626
627            change1Engine.setSelected((_train.getSecondLegOptions() & Train.CHANGE_ENGINES) == Train.CHANGE_ENGINES);
628            helper1Service.setSelected((_train.getSecondLegOptions() & Train.HELPER_ENGINES) == Train.HELPER_ENGINES);
629            if (!change1Engine.isSelected() && !helper1Service.isSelected()) {
630                modify1Caboose.setSelected((_train.getSecondLegOptions() & Train.ADD_CABOOSE) == Train.ADD_CABOOSE ||
631                        (_train.getSecondLegOptions() & Train.REMOVE_CABOOSE) == Train.REMOVE_CABOOSE);
632            }
633            numEngines1Box.setSelectedItem(_train.getSecondLegNumberEngines());
634            modelEngine1Box.setSelectedItem(_train.getSecondLegEngineModel());
635            routePickup1Box.setSelectedItem(_train.getSecondLegStartRouteLocation());
636            routeDrop1Box.setSelectedItem(_train.getSecondLegEndRouteLocation());
637            roadEngine1Box.setSelectedItem(_train.getSecondLegEngineRoad());
638            keep1Caboose.setSelected(true);
639            remove1Caboose.setSelected((_train.getSecondLegOptions() & Train.REMOVE_CABOOSE) == Train.REMOVE_CABOOSE);
640            change1Caboose.setSelected((_train.getSecondLegOptions() & Train.ADD_CABOOSE) == Train.ADD_CABOOSE);
641            roadCaboose1Box.setEnabled(change1Caboose.isSelected());
642            roadCaboose1Box.setSelectedItem(_train.getSecondLegCabooseRoad());
643            // adjust radio button text
644            if (_train.isCabooseNeeded()) {
645                change1Caboose.setText(Bundle.getMessage("ChangeCaboose"));
646                remove1Caboose.setEnabled(true);
647            } else {
648                change1Caboose.setText(Bundle.getMessage("AddCaboose"));
649                remove1Caboose.setEnabled(false);
650            }
651        }
652        engine1Option.setVisible(change1Engine.isSelected() || helper1Service.isSelected());
653        engine1caboose.setVisible(change1Engine.isSelected() || modify1Caboose.isSelected());
654        engine1DropOption.setVisible(helper1Service.isSelected());
655        engine1Option.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("EngineChange")));
656        if (change1Engine.isSelected() || helper1Service.isSelected()) {
657            createEngine1Panel();
658        }
659        if (change1Engine.isSelected() || modify1Caboose.isSelected()) {
660            createCaboose1Panel(modify1Caboose.isSelected());
661        }
662        if (helper1Service.isSelected()) {
663            engine1Option.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("AddHelpers")));
664        }
665        revalidate();
666    }
667
668    private void updateTrainRequires2Option() {
669        none2.setSelected(true);
670        if (_train != null) {
671
672            updateCabooseRoadComboBox(roadCaboose2Box);
673            updateEngineRoadComboBox(roadEngine2Box, (String) modelEngine2Box.getSelectedItem());
674            if (_train.getRoute() != null) {
675                _train.getRoute().updateComboBox(routePickup2Box);
676                _train.getRoute().updateComboBox(routeDrop2Box);
677            }
678
679            change2Engine.setSelected((_train.getThirdLegOptions() & Train.CHANGE_ENGINES) == Train.CHANGE_ENGINES);
680            helper2Service.setSelected((_train.getThirdLegOptions() & Train.HELPER_ENGINES) == Train.HELPER_ENGINES);
681            if (!change2Engine.isSelected() && !helper2Service.isSelected()) {
682                modify2Caboose.setSelected((_train.getThirdLegOptions() & Train.ADD_CABOOSE) == Train.ADD_CABOOSE ||
683                        (_train.getThirdLegOptions() & Train.REMOVE_CABOOSE) == Train.REMOVE_CABOOSE);
684            }
685            numEngines2Box.setSelectedItem(_train.getThirdLegNumberEngines());
686            modelEngine2Box.setSelectedItem(_train.getThirdLegEngineModel());
687            routePickup2Box.setSelectedItem(_train.getThirdLegStartRouteLocation());
688            routeDrop2Box.setSelectedItem(_train.getThirdLegEndRouteLocation());
689            roadEngine2Box.setSelectedItem(_train.getThirdLegEngineRoad());
690            keep2Caboose.setSelected(true);
691            remove2Caboose.setSelected((_train.getThirdLegOptions() & Train.REMOVE_CABOOSE) == Train.REMOVE_CABOOSE);
692            change2Caboose.setSelected((_train.getThirdLegOptions() & Train.ADD_CABOOSE) == Train.ADD_CABOOSE);
693            roadCaboose2Box.setEnabled(change2Caboose.isSelected());
694            roadCaboose2Box.setSelectedItem(_train.getThirdLegCabooseRoad());
695            // adjust radio button text
696            if ((_train.isCabooseNeeded() || change1Caboose.isSelected()) &&
697                    !remove1Caboose.isSelected()) {
698                change2Caboose.setText(Bundle.getMessage("ChangeCaboose"));
699                remove2Caboose.setEnabled(true);
700            } else {
701                change2Caboose.setText(Bundle.getMessage("AddCaboose"));
702                remove2Caboose.setEnabled(false);
703            }
704        }
705        engine2Option.setVisible(change2Engine.isSelected() || helper2Service.isSelected());
706        engine2caboose.setVisible(change2Engine.isSelected() || modify2Caboose.isSelected());
707        engine2DropOption.setVisible(helper2Service.isSelected());
708        engine2Option.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("EngineChange")));
709        if (change2Engine.isSelected() || helper2Service.isSelected()) {
710            createEngine2Panel();
711        }
712        if (change2Engine.isSelected() || modify2Caboose.isSelected()) {
713            createCaboose2Panel(modify2Caboose.isSelected());
714        }
715        if (helper2Service.isSelected()) {
716            engine2Option.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("AddHelpers")));
717        }
718        revalidate();
719    }
720
721    private void saveTrain() {
722        if (!checkInput()) {
723            return;
724        }
725        _train.setBuildTrainNormalEnabled(buildNormalCheckBox.isSelected());
726        _train.setSendCarsToTerminalEnabled(sendToTerminalCheckBox.isSelected());
727        if (returnStagingCheckBox.isEnabled()) {
728            _train.setAllowReturnToStagingEnabled(returnStagingCheckBox.isSelected());
729        }
730        _train.setAllowLocalMovesEnabled(allowLocalMovesCheckBox.isSelected());
731        _train.setAllowThroughCarsEnabled(allowThroughCarsCheckBox.isSelected());
732        _train.setServiceAllCarsWithFinalDestinationsEnabled(serviceAllCarsCheckBox.isSelected());
733        _train.setSendCarsWithCustomLoadsToStagingEnabled(sendCustomStagngCheckBox.isSelected());
734        _train.setBuildConsistEnabled(buildConsistCheckBox.isSelected());
735        _train.setBuiltStartYear(builtAfterTextField.getText().trim());
736        _train.setBuiltEndYear(builtBeforeTextField.getText().trim());
737
738        int options1 = Train.NO_CABOOSE_OR_FRED;
739        if (change1Engine.isSelected()) {
740            options1 = options1 | Train.CHANGE_ENGINES;
741        }
742        if (remove1Caboose.isSelected()) {
743            options1 = options1 | Train.REMOVE_CABOOSE;
744        } else if (change1Caboose.isSelected()) {
745            options1 = options1 | Train.ADD_CABOOSE | Train.REMOVE_CABOOSE;
746        }
747        if (helper1Service.isSelected()) {
748            options1 = options1 | Train.HELPER_ENGINES;
749        }
750        _train.setSecondLegOptions(options1);
751        if (routePickup1Box.getSelectedItem() != null) {
752            _train.setSecondLegStartRouteLocation((RouteLocation) routePickup1Box.getSelectedItem());
753        } else {
754            _train.setSecondLegStartRouteLocation(null);
755        }
756        if (routeDrop1Box.getSelectedItem() != null) {
757            _train.setSecondLegEndRouteLocation((RouteLocation) routeDrop1Box.getSelectedItem());
758        } else {
759            _train.setSecondLegEndRouteLocation(null);
760        }
761        _train.setSecondLegNumberEngines((String) numEngines1Box.getSelectedItem());
762        _train.setSecondLegEngineModel((String) modelEngine1Box.getSelectedItem());
763        _train.setSecondLegEngineRoad((String) roadEngine1Box.getSelectedItem());
764        _train.setSecondLegCabooseRoad((String) roadCaboose1Box.getSelectedItem());
765
766        int options2 = Train.NO_CABOOSE_OR_FRED;
767        if (change2Engine.isSelected()) {
768            options2 = options2 | Train.CHANGE_ENGINES;
769        }
770        if (remove2Caboose.isSelected()) {
771            options2 = options2 | Train.REMOVE_CABOOSE;
772        } else if (change2Caboose.isSelected()) {
773            options2 = options2 | Train.ADD_CABOOSE | Train.REMOVE_CABOOSE;
774        }
775        if (helper2Service.isSelected()) {
776            options2 = options2 | Train.HELPER_ENGINES;
777        }
778        _train.setThirdLegOptions(options2);
779        if (routePickup2Box.getSelectedItem() != null) {
780            _train.setThirdLegStartRouteLocation((RouteLocation) routePickup2Box.getSelectedItem());
781        } else {
782            _train.setThirdLegStartRouteLocation(null);
783        }
784        if (routeDrop2Box.getSelectedItem() != null) {
785            _train.setThirdLegEndRouteLocation((RouteLocation) routeDrop2Box.getSelectedItem());
786        } else {
787            _train.setThirdLegEndRouteLocation(null);
788        }
789        _train.setThirdLegNumberEngines((String) numEngines2Box.getSelectedItem());
790        _train.setThirdLegEngineModel((String) modelEngine2Box.getSelectedItem());
791        _train.setThirdLegEngineRoad((String) roadEngine2Box.getSelectedItem());
792        _train.setThirdLegCabooseRoad((String) roadCaboose2Box.getSelectedItem());
793
794        OperationsXml.save();
795        if (Setup.isCloseWindowOnSaveEnabled()) {
796            dispose();
797        }
798    }
799
800    private boolean checkInput() {
801        if ((!none1.isSelected() && routePickup1Box.getSelectedItem() == null) ||
802                (!none2.isSelected() && routePickup2Box.getSelectedItem() == null)) {
803            JOptionPane.showMessageDialog(this, Bundle.getMessage("SelectLocationEngChange"), Bundle
804                    .getMessage("CanNotSave"), JOptionPane.ERROR_MESSAGE);
805            return false;
806        }
807        if ((helper1Service.isSelected() && routeDrop1Box.getSelectedItem() == null) ||
808                (helper2Service.isSelected() && routeDrop2Box.getSelectedItem() == null)) {
809            JOptionPane.showMessageDialog(this, Bundle.getMessage("SelectLocationEndHelper"), Bundle
810                    .getMessage("CanNotSave"), JOptionPane.ERROR_MESSAGE);
811            return false;
812        }
813        try {
814            if (!builtAfterTextField.getText().trim().isEmpty()) {
815                Integer.parseInt(builtAfterTextField.getText().trim());
816            }
817            if (!builtBeforeTextField.getText().trim().isEmpty()) {
818                Integer.parseInt(builtBeforeTextField.getText().trim());
819            }
820        } catch (NumberFormatException e) {
821            JOptionPane.showMessageDialog(this, Bundle.getMessage("EnterFourDigitYear"), Bundle
822                    .getMessage("CanNotSave"), JOptionPane.ERROR_MESSAGE);
823            return false;
824        }
825        return true;
826    }
827
828    private void enableButtons(boolean enabled) {
829        ownerNameAll.setEnabled(enabled);
830        ownerNameInclude.setEnabled(enabled);
831        ownerNameExclude.setEnabled(enabled);
832
833        builtDateAll.setEnabled(enabled);
834        builtDateAfter.setEnabled(enabled);
835        builtDateBefore.setEnabled(enabled);
836        builtDateRange.setEnabled(enabled);
837
838        none1.setEnabled(enabled);
839        change1Engine.setEnabled(enabled);
840        modify1Caboose.setEnabled(enabled);
841        helper1Service.setEnabled(enabled);
842
843        none2.setEnabled(enabled);
844        change2Engine.setEnabled(enabled);
845        modify2Caboose.setEnabled(enabled);
846        helper2Service.setEnabled(enabled);
847
848        saveTrainButton.setEnabled(enabled);
849    }
850
851    private void updateModelComboBoxes() {
852        InstanceManager.getDefault(EngineModels.class).updateComboBox(modelEngine1Box);
853        InstanceManager.getDefault(EngineModels.class).updateComboBox(modelEngine2Box);
854        modelEngine1Box.insertItemAt("", 0);
855        modelEngine2Box.insertItemAt("", 0);
856        if (_train != null) {
857            modelEngine1Box.setSelectedItem(_train.getSecondLegEngineModel());
858            modelEngine2Box.setSelectedItem(_train.getThirdLegEngineModel());
859        }
860    }
861
862    private void updateOwnerComboBoxes() {
863        InstanceManager.getDefault(CarOwners.class).updateComboBox(ownerBox);
864    }
865
866    // update caboose road box based on radio selection
867    private void updateCabooseRoadComboBox(JComboBox<String> box) {
868        box.removeAllItems();
869        box.addItem("");
870        List<String> roads = InstanceManager.getDefault(CarManager.class).getCabooseRoadNames();
871        for (String road : roads) {
872            box.addItem(road);
873        }
874    }
875
876    private void updateEngineRoadComboBox(JComboBox<String> box, String engineModel) {
877        if (engineModel == null) {
878            return;
879        }
880        box.removeAllItems();
881        box.addItem("");
882        List<String> roads = InstanceManager.getDefault(EngineManager.class).getEngineRoadNames(engineModel);
883        for (String road : roads) {
884            box.addItem(road);
885        }
886    }
887
888    private void updateReturnToStagingCheckbox() {
889        if (_train != null &&
890                _train.getTrainDepartsRouteLocation() != null &&
891                _train.getTrainTerminatesRouteLocation() != null &&
892                _train.getTrainTerminatesRouteLocation().getLocation() != null &&
893                _train.getTrainTerminatesRouteLocation().getLocation().isStaging() &&
894                _train.getTrainDepartsRouteLocation().getName().equals(
895                        _train.getTrainTerminatesRouteLocation().getName())) {
896            allowThroughCarsCheckBox.setEnabled(false);
897            if (Setup.isStagingAllowReturnEnabled()) {
898                returnStagingCheckBox.setEnabled(false);
899                returnStagingCheckBox.setSelected(true);
900                returnStagingCheckBox.setToolTipText(Bundle.getMessage("TipReturnToStaging"));
901            } else {
902                returnStagingCheckBox.setEnabled(true);
903                returnStagingCheckBox.setSelected(_train.isAllowReturnToStagingEnabled());
904                returnStagingCheckBox.setToolTipText("");
905            }
906        }
907    }
908
909    private void createEngine1Panel() {
910        engine1Option.removeAll();
911        addItem(engine1Option, new JLabel(Bundle.getMessage("ChangeEnginesAt")), 0, 0);
912        addItem(engine1Option, routePickup1Box, 1, 0);
913        addItem(engine1Option, new JLabel(Bundle.getMessage("Engines")), 2, 0);
914        addItem(engine1Option, numEngines1Box, 3, 0);
915        addItem(engine1Option, new JLabel(Bundle.getMessage("Model")), 4, 0);
916        addItem(engine1Option, modelEngine1Box, 5, 0);
917        addItem(engine1Option, new JLabel(Bundle.getMessage("Road")), 6, 0);
918        addItem(engine1Option, roadEngine1Box, 7, 0);
919    }
920
921    private void createEngine2Panel() {
922        engine2Option.removeAll();
923        addItem(engine2Option, new JLabel(Bundle.getMessage("ChangeEnginesAt")), 0, 0);
924        addItem(engine2Option, routePickup2Box, 1, 0);
925        addItem(engine2Option, new JLabel(Bundle.getMessage("Engines")), 2, 0);
926        addItem(engine2Option, numEngines2Box, 3, 0);
927        addItem(engine2Option, new JLabel(Bundle.getMessage("Model")), 4, 0);
928        addItem(engine2Option, modelEngine2Box, 5, 0);
929        addItem(engine2Option, new JLabel(Bundle.getMessage("Road")), 6, 0);
930        addItem(engine2Option, roadEngine2Box, 7, 0);
931    }
932
933    private void createCaboose1Panel(boolean withCombox) {
934        engine1caboose.removeAll();
935        addItem(engine1caboose, remove1Caboose, 2, 6);
936        addItem(engine1caboose, change1Caboose, 4, 6);
937        addItem(engine1caboose, new JLabel(Bundle.getMessage("Road")), 5, 6);
938        addItem(engine1caboose, roadCaboose1Box, 6, 6);
939        if (withCombox) {
940            addItem(engine1caboose, new JLabel(Bundle.getMessage("ChangeEnginesAt")), 0, 6);
941            addItem(engine1caboose, routePickup1Box, 1, 6);
942        } else {
943            addItem(engine1caboose, keep1Caboose, 3, 6);
944        }
945    }
946
947    private void createCaboose2Panel(boolean withCombox) {
948        engine2caboose.removeAll();
949        addItem(engine2caboose, remove2Caboose, 2, 6);
950        addItem(engine2caboose, change2Caboose, 4, 6);
951        addItem(engine2caboose, new JLabel(Bundle.getMessage("Road")), 5, 6);
952        addItem(engine2caboose, roadCaboose2Box, 6, 6);
953        if (withCombox) {
954            addItem(engine2caboose, new JLabel(Bundle.getMessage("ChangeEnginesAt")), 0, 6);
955            addItem(engine2caboose, routePickup2Box, 1, 6);
956        } else {
957            addItem(engine2caboose, keep2Caboose, 3, 6);
958        }
959    }
960
961    /*
962     * private boolean checkModel(String model, String numberEngines){ if
963     * (numberEngines.equals("0") || model.equals("")) return true; String type
964     * = InstanceManager.getDefault(EngineModels.class).getModelType(model);
965     * if(_train.acceptsTypeName(type)) return true;
966     * JOptionPane.showMessageDialog(this,
967     * MessageFormat.format(Bundle.getMessage("TrainModelService"), new Object[]
968     * {model, type}), MessageFormat.format(Bundle.getMessage("CanNot"), new
969     * Object[] {Bundle.getMessage("save")}), JOptionPane.ERROR_MESSAGE); return
970     * false; }
971     */
972    @Override
973    public void dispose() {
974        InstanceManager.getDefault(CarOwners.class).removePropertyChangeListener(this);
975        InstanceManager.getDefault(EngineModels.class).removePropertyChangeListener(this);
976        Setup.getDefault().removePropertyChangeListener(this);
977        if (_train != null) {
978            _train.removePropertyChangeListener(this);
979        }
980        super.dispose();
981    }
982
983    @Override
984    public void propertyChange(java.beans.PropertyChangeEvent e) {
985        if (Control.SHOW_PROPERTY) {
986            log.debug("Property change: ({}) old: ({}) new: ({})", e.getPropertyName(), e.getOldValue(), e
987                    .getNewValue());
988        }
989        if (e.getPropertyName().equals(CarOwners.CAROWNERS_CHANGED_PROPERTY)) {
990            updateOwnerComboBoxes();
991            updateOwnerNames();
992        }
993        if (e.getPropertyName().equals(EngineModels.ENGINEMODELS_CHANGED_PROPERTY) ||
994                e.getPropertyName().equals(Train.TYPES_CHANGED_PROPERTY)) {
995            updateModelComboBoxes();
996        }
997        if (e.getPropertyName().equals(Train.TRAIN_REQUIREMENTS_CHANGED_PROPERTY)) {
998            updateTrainRequires1Option();
999            updateTrainRequires2Option();
1000        }
1001        if (e.getPropertyName().equals(Setup.ALLOW_CARS_TO_RETURN_PROPERTY_CHANGE)) {
1002            updateReturnToStagingCheckbox();
1003        }
1004    }
1005
1006    private final static Logger log = LoggerFactory.getLogger(TrainEditBuildOptionsFrame.class);
1007}