001package jmri.jmrit.operations.trains.gui;
002
003import java.awt.*;
004import java.util.List;
005
006import javax.swing.*;
007
008import org.slf4j.Logger;
009import org.slf4j.LoggerFactory;
010
011import jmri.InstanceManager;
012import jmri.jmrit.operations.*;
013import jmri.jmrit.operations.rollingstock.RollingStockManager;
014import jmri.jmrit.operations.rollingstock.cars.*;
015import jmri.jmrit.operations.rollingstock.engines.EngineManager;
016import jmri.jmrit.operations.setup.Control;
017import jmri.jmrit.operations.setup.Setup;
018import jmri.jmrit.operations.trains.Train;
019
020/**
021 * Frame for user edit of a train's road options
022 *
023 * @author Dan Boudreau Copyright (C) 2013, 2022
024 * 
025 */
026public class TrainRoadOptionsFrame extends OperationsFrame implements java.beans.PropertyChangeListener {
027
028    Train _train = null;
029
030    JPanel pCarRoadControls = new JPanel();
031    JPanel panelCarRoads = new JPanel();
032    JScrollPane paneCarRoads = new JScrollPane(panelCarRoads);
033    
034    JPanel pCabooseRoadControls = new JPanel();
035    JPanel panelCabooseRoads = new JPanel();
036    JScrollPane paneCabooseRoads = new JScrollPane(panelCabooseRoads);
037
038    JPanel pLocoRoadControls = new JPanel();
039    JPanel panelLocoRoads = new JPanel();
040    JScrollPane paneLocoRoads = new JScrollPane(panelLocoRoads);
041
042    // labels
043    JLabel trainName = new JLabel();
044    JLabel trainDescription = new JLabel();
045
046    // major buttons
047    JButton addCarRoadButton = new JButton(Bundle.getMessage("AddRoad"));
048    JButton deleteCarRoadButton = new JButton(Bundle.getMessage("DeleteRoad"));
049    JButton deleteCarAllRoadsButton = new JButton(Bundle.getMessage("DeleteAll"));
050
051    JButton addCabooseRoadButton = new JButton(Bundle.getMessage("AddRoad"));
052    JButton deleteCabooseRoadButton = new JButton(Bundle.getMessage("DeleteRoad"));
053    JButton deleteCabooseAllRoadsButton = new JButton(Bundle.getMessage("DeleteAll"));
054
055    JButton addLocoRoadButton = new JButton(Bundle.getMessage("AddRoad"));
056    JButton deleteLocoRoadButton = new JButton(Bundle.getMessage("DeleteRoad"));
057    JButton deleteLocoAllRoadsButton = new JButton(Bundle.getMessage("DeleteAll"));
058
059    JButton saveTrainButton = new JButton(Bundle.getMessage("SaveTrain"));
060
061    // radio buttons
062    JRadioButton carRoadNameAll = new JRadioButton(Bundle.getMessage("AcceptAll"));
063    JRadioButton carRoadNameInclude = new JRadioButton(Bundle.getMessage("AcceptOnly"));
064    JRadioButton carRoadNameExclude = new JRadioButton(Bundle.getMessage("Exclude"));
065
066    JRadioButton cabooseRoadNameAll = new JRadioButton(Bundle.getMessage("AcceptAll"));
067    JRadioButton cabooseRoadNameInclude = new JRadioButton(Bundle.getMessage("AcceptOnly"));
068    JRadioButton cabooseRoadNameExclude = new JRadioButton(Bundle.getMessage("Exclude"));
069
070    JRadioButton locoRoadNameAll = new JRadioButton(Bundle.getMessage("AcceptAll"));
071    JRadioButton locoRoadNameInclude = new JRadioButton(Bundle.getMessage("AcceptOnly"));
072    JRadioButton locoRoadNameExclude = new JRadioButton(Bundle.getMessage("Exclude"));
073
074    // combo boxes
075    JComboBox<String> comboBoxCarRoads = InstanceManager.getDefault(CarRoads.class).getComboBox();
076    JComboBox<String> comboBoxCabooseRoads = new JComboBox<String>();
077    JComboBox<String> comboBoxLocoRoads = new JComboBox<String>();
078
079    public static final String DISPOSE = "dispose"; // NOI18N
080
081    public TrainRoadOptionsFrame() {
082        super(Bundle.getMessage("MenuItemRoadOptions"));
083    }
084
085    public void initComponents(TrainEditFrame parent) {
086
087        parent.setChildFrame(this);
088        _train = parent._train;
089
090        getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
091
092        // Layout the panel by rows
093        JPanel p1 = new JPanel();
094        p1.setLayout(new BoxLayout(p1, BoxLayout.X_AXIS));
095        p1.setMaximumSize(new Dimension(2000, 250));
096
097        // Layout the panel by rows
098        // row 1a
099        JPanel pName = new JPanel();
100        pName.setLayout(new GridBagLayout());
101        pName.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Name")));
102        addItem(pName, trainName, 0, 0);
103
104        // row 1b
105        JPanel pDesc = new JPanel();
106        pDesc.setLayout(new GridBagLayout());
107        pDesc.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Description")));
108        addItem(pDesc, trainDescription, 0, 0);
109
110        p1.add(pName);
111        p1.add(pDesc);
112
113        // row 3 Car Roads
114        JPanel pCarRoad = new JPanel();
115        pCarRoad.setLayout(new BoxLayout(pCarRoad, BoxLayout.Y_AXIS));
116        JScrollPane paneCar = new JScrollPane(pCarRoad);
117        paneCar.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("CarRoadsTrain")));
118        paneCar.setMaximumSize(new Dimension(2000, 400));
119
120        JPanel pCarRoadRadioButtons = new JPanel();
121        pCarRoadRadioButtons.setLayout(new FlowLayout());
122
123        pCarRoadRadioButtons.add(carRoadNameAll);
124        pCarRoadRadioButtons.add(carRoadNameInclude);
125        pCarRoadRadioButtons.add(carRoadNameExclude);
126
127        pCarRoadControls.setLayout(new FlowLayout());
128
129        pCarRoadControls.add(comboBoxCarRoads);
130        pCarRoadControls.add(addCarRoadButton);
131        pCarRoadControls.add(deleteCarRoadButton);
132        pCarRoadControls.add(deleteCarAllRoadsButton);
133
134        pCarRoadControls.setVisible(false);
135
136        pCarRoad.add(pCarRoadRadioButtons);
137        pCarRoad.add(pCarRoadControls);
138
139        // row 4
140        panelCarRoads.setLayout(new GridBagLayout());
141        paneCarRoads.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("RoadsCar")));
142
143        ButtonGroup carRoadGroup = new ButtonGroup();
144        carRoadGroup.add(carRoadNameAll);
145        carRoadGroup.add(carRoadNameInclude);
146        carRoadGroup.add(carRoadNameExclude);
147        
148        // row 5 Caboose Roads
149        JPanel pCabooseRoad = new JPanel();
150        pCabooseRoad.setLayout(new BoxLayout(pCabooseRoad, BoxLayout.Y_AXIS));
151        JScrollPane paneCaboose = new JScrollPane(pCabooseRoad);
152        paneCaboose.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("CabooseRoadsTrain")));
153        paneCaboose.setMaximumSize(new Dimension(2000, 400));
154
155        JPanel pCabooseRoadRadioButtons = new JPanel();
156        pCabooseRoadRadioButtons.setLayout(new FlowLayout());
157
158        pCabooseRoadRadioButtons.add(cabooseRoadNameAll);
159        pCabooseRoadRadioButtons.add(cabooseRoadNameInclude);
160        pCabooseRoadRadioButtons.add(cabooseRoadNameExclude);
161
162        pCabooseRoadControls.setLayout(new FlowLayout());
163
164        pCabooseRoadControls.add(comboBoxCabooseRoads);
165        pCabooseRoadControls.add(addCabooseRoadButton);
166        pCabooseRoadControls.add(deleteCabooseRoadButton);
167        pCabooseRoadControls.add(deleteCabooseAllRoadsButton);
168
169        pCabooseRoadControls.setVisible(false);
170
171        pCabooseRoad.add(pCabooseRoadRadioButtons);
172        pCabooseRoad.add(pCabooseRoadControls);
173
174        // row 6
175        panelCabooseRoads.setLayout(new GridBagLayout());
176        paneCabooseRoads.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("RoadsCaboose")));
177
178        ButtonGroup cabooseRoadGroup = new ButtonGroup();
179        cabooseRoadGroup.add(cabooseRoadNameAll);
180        cabooseRoadGroup.add(cabooseRoadNameInclude);
181        cabooseRoadGroup.add(cabooseRoadNameExclude);
182
183        // row 7 Engine Roads
184        JPanel pLocoRoad = new JPanel();
185        pLocoRoad.setLayout(new BoxLayout(pLocoRoad, BoxLayout.Y_AXIS));
186        JScrollPane paneLoco = new JScrollPane(pLocoRoad);
187        paneLoco.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("LocoRoadsTrain")));
188        paneLoco.setMaximumSize(new Dimension(2000, 400));
189
190        JPanel pLocoRoadRadioButtons = new JPanel();
191        pLocoRoadRadioButtons.setLayout(new FlowLayout());
192
193        pLocoRoadRadioButtons.add(locoRoadNameAll);
194        pLocoRoadRadioButtons.add(locoRoadNameInclude);
195        pLocoRoadRadioButtons.add(locoRoadNameExclude);
196
197        pLocoRoadControls.setLayout(new FlowLayout());
198
199        pLocoRoadControls.add(comboBoxLocoRoads);
200        pLocoRoadControls.add(addLocoRoadButton);
201        pLocoRoadControls.add(deleteLocoRoadButton);
202        pLocoRoadControls.add(deleteLocoAllRoadsButton);
203
204        pLocoRoadControls.setVisible(false);
205
206        pLocoRoad.add(pLocoRoadRadioButtons);
207        pLocoRoad.add(pLocoRoadControls);
208
209        // row 8
210        panelLocoRoads.setLayout(new GridBagLayout());
211        paneLocoRoads.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("RoadsLoco")));
212
213        ButtonGroup locoRoadGroup = new ButtonGroup();
214        locoRoadGroup.add(locoRoadNameAll);
215        locoRoadGroup.add(locoRoadNameInclude);
216        locoRoadGroup.add(locoRoadNameExclude);
217
218        // row 12
219        JPanel panelButtons = new JPanel();
220        panelButtons.setLayout(new GridBagLayout());
221        panelButtons.setBorder(BorderFactory.createTitledBorder(""));
222        panelButtons.setMaximumSize(new Dimension(2000, 200));
223
224        // row 13
225        addItem(panelButtons, saveTrainButton, 0, 0);
226
227        getContentPane().add(p1);
228        getContentPane().add(paneCar);
229        getContentPane().add(paneCarRoads);
230        getContentPane().add(paneCaboose);
231        getContentPane().add(paneCabooseRoads);
232        getContentPane().add(paneLoco);
233        getContentPane().add(paneLocoRoads);
234        getContentPane().add(panelButtons);
235
236        // setup buttons
237        addButtonAction(saveTrainButton);
238
239        addButtonAction(deleteCarRoadButton);
240        addButtonAction(deleteCarAllRoadsButton);
241        addButtonAction(addCarRoadButton);
242
243        addRadioButtonAction(carRoadNameAll);
244        addRadioButtonAction(carRoadNameInclude);
245        addRadioButtonAction(carRoadNameExclude);
246        
247        addButtonAction(deleteCabooseRoadButton);
248        addButtonAction(deleteCabooseAllRoadsButton);
249        addButtonAction(addCabooseRoadButton);
250
251        addRadioButtonAction(cabooseRoadNameAll);
252        addRadioButtonAction(cabooseRoadNameInclude);
253        addRadioButtonAction(cabooseRoadNameExclude);
254
255        addButtonAction(deleteLocoRoadButton);
256        addButtonAction(deleteLocoAllRoadsButton);
257        addButtonAction(addLocoRoadButton);
258
259        addRadioButtonAction(locoRoadNameAll);
260        addRadioButtonAction(locoRoadNameInclude);
261        addRadioButtonAction(locoRoadNameExclude);
262
263        if (_train != null) {
264            trainName.setText(_train.getName());
265            trainDescription.setText(_train.getDescription());
266            updateButtons(true);
267            // listen for train changes
268            _train.addPropertyChangeListener(this);
269        } else {
270            updateButtons(false);
271        }
272        addHelpMenu("package.jmri.jmrit.operations.Operations_TrainRoadOptions", true); // NOI18N
273        updateRoadComboBoxes();
274        updateCarRoadNames();
275        updateCabooseRoadNames();
276        updateLocoRoadNames();
277
278        // get notified if car types or roads gets modified
279        InstanceManager.getDefault(CarTypes.class).addPropertyChangeListener(this);
280        InstanceManager.getDefault(CarRoads.class).addPropertyChangeListener(this);
281        // get notified if there's a change in the engine roster
282        InstanceManager.getDefault(EngineManager.class).addPropertyChangeListener(this);
283        InstanceManager.getDefault(CarManager.class).addPropertyChangeListener(this);
284
285        initMinimumSize(new Dimension(Control.panelWidth500, Control.panelHeight500));
286    }
287
288    // Save
289    @Override
290    public void buttonActionPerformed(java.awt.event.ActionEvent ae) {
291        if (_train != null) {
292            if (ae.getSource() == saveTrainButton) {
293                log.debug("train save button activated");
294                saveTrain();
295            }
296            if (ae.getSource() == addCarRoadButton) {
297                String roadName = (String) comboBoxCarRoads.getSelectedItem();
298                if (_train.addCarRoadName(roadName)) {
299                    updateCarRoadNames();
300                }
301                selectNextItemComboBox(comboBoxCarRoads);
302            }
303            if (ae.getSource() == deleteCarRoadButton) {
304                String roadName = (String) comboBoxCarRoads.getSelectedItem();
305                if (_train.deleteCarRoadName(roadName)) {
306                    updateCarRoadNames();
307                }
308                selectNextItemComboBox(comboBoxCarRoads);
309            }
310            if (ae.getSource() == deleteCarAllRoadsButton) {
311                deleteAllCarRoads();
312            }
313            // cabooses
314            if (ae.getSource() == addCabooseRoadButton) {
315                String roadName = (String) comboBoxCabooseRoads.getSelectedItem();
316                if (_train.addCabooseRoadName(roadName)) {
317                    updateCabooseRoadNames();
318                }
319                selectNextItemComboBox(comboBoxCabooseRoads);
320            }
321            if (ae.getSource() == deleteCabooseRoadButton) {
322                String roadName = (String) comboBoxCabooseRoads.getSelectedItem();
323                if (_train.deleteCabooseRoadName(roadName)) {
324                    updateCabooseRoadNames();
325                }
326                selectNextItemComboBox(comboBoxCabooseRoads);
327            }
328            if (ae.getSource() == deleteCabooseAllRoadsButton) {
329                deleteAllCabooseRoads();
330            }
331            // locos
332            if (ae.getSource() == addLocoRoadButton) {
333                String roadName = (String) comboBoxLocoRoads.getSelectedItem();
334                if (_train.addLocoRoadName(roadName)) {
335                    updateLocoRoadNames();
336                }
337                selectNextItemComboBox(comboBoxLocoRoads);
338            }
339
340            if (ae.getSource() == deleteLocoRoadButton) {
341                String roadName = (String) comboBoxLocoRoads.getSelectedItem();
342                if (_train.deleteLocoRoadName(roadName)) {
343                    updateLocoRoadNames();
344                }
345                selectNextItemComboBox(comboBoxLocoRoads);
346            }
347            if (ae.getSource() == deleteLocoAllRoadsButton) {
348                deleteAllLocoRoads();
349            }
350        }
351    }
352
353    @Override
354    public void radioButtonActionPerformed(java.awt.event.ActionEvent ae) {
355        log.debug("radio button activated");
356        if (_train != null) {
357            if (ae.getSource() == carRoadNameAll) {
358                _train.setCarRoadOption(Train.ALL_LOADS);
359                updateCarRoadNames();
360            }
361            if (ae.getSource() == carRoadNameInclude) {
362                _train.setCarRoadOption(Train.INCLUDE_LOADS);
363                updateCarRoadNames();
364            }
365            if (ae.getSource() == carRoadNameExclude) {
366                _train.setCarRoadOption(Train.EXCLUDE_LOADS);
367                updateCarRoadNames();
368            }
369
370            if (ae.getSource() == cabooseRoadNameAll) {
371                _train.setCabooseRoadOption(Train.ALL_LOADS);
372                updateCabooseRoadNames();
373            }
374            if (ae.getSource() == cabooseRoadNameInclude) {
375                _train.setCabooseRoadOption(Train.INCLUDE_LOADS);
376                updateCabooseRoadNames();
377            }
378            if (ae.getSource() == cabooseRoadNameExclude) {
379                _train.setCabooseRoadOption(Train.EXCLUDE_LOADS);
380                updateCabooseRoadNames();
381            }
382
383            if (ae.getSource() == locoRoadNameAll) {
384                _train.setLocoRoadOption(Train.ALL_LOADS);
385                updateLocoRoadNames();
386            }
387            if (ae.getSource() == locoRoadNameInclude) {
388                _train.setLocoRoadOption(Train.INCLUDE_LOADS);
389                updateLocoRoadNames();
390            }
391            if (ae.getSource() == locoRoadNameExclude) {
392                _train.setLocoRoadOption(Train.EXCLUDE_LOADS);
393                updateLocoRoadNames();
394            }
395        }
396    }
397
398    protected void updateButtons(boolean enabled) {
399        saveTrainButton.setEnabled(enabled);
400
401        carRoadNameAll.setEnabled(enabled);
402        carRoadNameInclude.setEnabled(enabled);
403        carRoadNameExclude.setEnabled(enabled);
404        
405        locoRoadNameAll.setEnabled(enabled);
406        locoRoadNameInclude.setEnabled(enabled);
407        locoRoadNameExclude.setEnabled(enabled);
408    }
409
410    private static final int NUMBER_ROADS_PER_LINE = 6;
411
412    private void updateCarRoadNames() {
413        log.debug("Update car road names");
414        panelCarRoads.removeAll();
415        if (_train != null) {
416            // set radio button
417            carRoadNameAll.setSelected(_train.getCarRoadOption().equals(Train.ALL_LOADS));
418            carRoadNameInclude.setSelected(_train.getCarRoadOption().equals(Train.INCLUDE_ROADS));
419            carRoadNameExclude.setSelected(_train.getCarRoadOption().equals(Train.EXCLUDE_ROADS));
420
421            pCarRoadControls.setVisible(!carRoadNameAll.isSelected());
422
423            if (!carRoadNameAll.isSelected()) {
424                int x = 0;
425                int y = 0; // vertical position in panel
426
427                for (String roadName : _train.getCarRoadNames()) {
428                    JLabel road = new JLabel();
429                    road.setText(roadName);
430                    addItemTop(panelCarRoads, road, x++, y);
431                    // limit the number of roads per line
432                    if (x > NUMBER_ROADS_PER_LINE) {
433                        y++;
434                        x = 0;
435                    }
436                }
437                revalidate();
438            }
439        } else {
440            carRoadNameAll.setSelected(true);
441        }
442        panelCarRoads.repaint();
443        panelCarRoads.revalidate();
444    }
445    
446    private void updateCabooseRoadNames() {
447        log.debug("Update caboose road names");
448        panelCabooseRoads.removeAll();
449        if (_train != null) {
450            // set radio button
451            cabooseRoadNameAll.setSelected(_train.getCabooseRoadOption().equals(Train.ALL_LOADS));
452            cabooseRoadNameInclude.setSelected(_train.getCabooseRoadOption().equals(Train.INCLUDE_ROADS));
453            cabooseRoadNameExclude.setSelected(_train.getCabooseRoadOption().equals(Train.EXCLUDE_ROADS));
454
455            pCabooseRoadControls.setVisible(!cabooseRoadNameAll.isSelected());
456
457            if (!cabooseRoadNameAll.isSelected()) {
458                int x = 0;
459                int y = 0; // vertical position in panel
460
461                for (String roadName : _train.getCabooseRoadNames()) {
462                    JLabel road = new JLabel();
463                    road.setText(roadName);
464                    addItemTop(panelCabooseRoads, road, x++, y);
465                    // limit the number of roads per line
466                    if (x > NUMBER_ROADS_PER_LINE) {
467                        y++;
468                        x = 0;
469                    }
470                }
471                revalidate();
472            }
473        } else {
474            cabooseRoadNameAll.setSelected(true);
475        }
476        panelCabooseRoads.repaint();
477        panelCabooseRoads.revalidate();
478    }
479
480    private void updateLocoRoadNames() {
481        log.debug("Update loco road names");
482        panelLocoRoads.removeAll();
483        if (_train != null) {
484            // set radio button
485            locoRoadNameAll.setSelected(_train.getLocoRoadOption().equals(Train.ALL_LOADS));
486            locoRoadNameInclude.setSelected(_train.getLocoRoadOption().equals(Train.INCLUDE_ROADS));
487            locoRoadNameExclude.setSelected(_train.getLocoRoadOption().equals(Train.EXCLUDE_ROADS));
488
489            pLocoRoadControls.setVisible(!locoRoadNameAll.isSelected());
490
491            if (!locoRoadNameAll.isSelected()) {
492                int x = 0;
493                int y = 0; // vertical position in panel
494
495                for (String roadName : _train.getLocoRoadNames()) {
496                    JLabel road = new JLabel();
497                    road.setText(roadName);
498                    addItemTop(panelLocoRoads, road, x++, y);
499                    // limit the number of roads per line
500                    if (x > NUMBER_ROADS_PER_LINE) {
501                        y++;
502                        x = 0;
503                    }
504                }
505                revalidate();
506            }
507        } else {
508            locoRoadNameAll.setSelected(true);
509        }
510        panelLocoRoads.repaint();
511        panelLocoRoads.revalidate();
512    }
513
514    private void deleteAllCarRoads() {
515        if (_train != null) {
516            for (String road : _train.getCarRoadNames()) {
517                _train.deleteCarRoadName(road);
518            }
519        }
520        updateCarRoadNames();
521    }
522    
523    private void deleteAllCabooseRoads() {
524        if (_train != null) {
525            for (String road : _train.getCabooseRoadNames()) {
526                _train.deleteCabooseRoadName(road);
527            }
528        }
529        updateCabooseRoadNames();
530    }
531
532    private void deleteAllLocoRoads() {
533        if (_train != null) {
534            for (String road : _train.getLocoRoadNames()) {
535                _train.deleteLocoRoadName(road);
536            }
537        }
538        updateLocoRoadNames();
539    }
540
541    private void saveTrain() {
542        OperationsXml.save();
543        if (Setup.isCloseWindowOnSaveEnabled()) {
544            dispose();
545        }
546    }
547
548    private void updateRoadComboBoxes() {
549        InstanceManager.getDefault(CarRoads.class).updateComboBox(comboBoxCarRoads);
550        updateCabooseRoadComboBox();
551        InstanceManager.getDefault(EngineManager.class).updateEngineRoadComboBox(NONE, comboBoxLocoRoads);
552    }
553
554    private void updateCabooseRoadComboBox() {
555        comboBoxCabooseRoads.removeAllItems();
556        List<String> roads = InstanceManager.getDefault(CarManager.class).getCabooseRoadNames();
557        for (String road : roads) {
558            comboBoxCabooseRoads.addItem(road);
559        }
560        OperationsPanel.padComboBox(comboBoxCabooseRoads);
561    }
562
563    @Override
564    public void dispose() {
565        InstanceManager.getDefault(CarTypes.class).removePropertyChangeListener(this);
566        InstanceManager.getDefault(CarRoads.class).removePropertyChangeListener(this);
567        if (_train != null) {
568            _train.removePropertyChangeListener(this);
569        }
570        super.dispose();
571    }
572
573    @Override
574    public void propertyChange(java.beans.PropertyChangeEvent e) {
575        if (Control.SHOW_PROPERTY) {
576            log.debug("Property change: ({}) old: ({}) new: ({})", e.getPropertyName(), e.getOldValue(), e
577                    .getNewValue());
578        }
579        if (e.getPropertyName().equals(CarRoads.CARROADS_CHANGED_PROPERTY)
580                || e.getPropertyName().equals(RollingStockManager.LISTLENGTH_CHANGED_PROPERTY)) {
581            updateRoadComboBoxes();
582            updateCarRoadNames();
583            updateCabooseRoadNames();
584            updateLocoRoadNames();
585        }
586    }
587
588    private final static Logger log = LoggerFactory.getLogger(TrainRoadOptionsFrame.class);
589}