001package jmri.jmrit.operations.locations.tools;
002
003import java.awt.*;
004
005import javax.swing.*;
006
007import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
008import jmri.InstanceManager;
009import jmri.jmrit.operations.OperationsFrame;
010import jmri.jmrit.operations.OperationsXml;
011import jmri.jmrit.operations.locations.Location;
012import jmri.jmrit.operations.locations.Track;
013import jmri.jmrit.operations.rollingstock.cars.*;
014import jmri.jmrit.operations.setup.Control;
015import jmri.jmrit.operations.setup.Setup;
016import jmri.util.swing.JmriJOptionPane;
017
018/**
019 * Frame for user edit of track loads
020 *
021 * @author Dan Boudreau Copyright (C) 2013, 2014, 2015, 2023, 2026
022 * 
023 */
024public class TrackLoadEditFrame extends OperationsFrame implements java.beans.PropertyChangeListener {
025
026    private static boolean loadAndType = false;
027    private static boolean shipLoadAndType = false;
028
029    Location _location = null;
030    Track _track = null;
031    String _type = "";
032    JMenu _toolMenu = null;
033
034    // panels
035    JPanel pLoadControls = new JPanel();
036    JPanel panelLoads = new JPanel();
037    JScrollPane paneLoads = new JScrollPane(panelLoads);
038
039    JPanel pShipLoadControls = new JPanel();
040    JPanel panelShipLoads = new JPanel();
041    JScrollPane paneShipLoadControls;
042    JScrollPane paneShipLoads = new JScrollPane(panelShipLoads);
043
044    // major buttons
045    JButton saveButton = new JButton(Bundle.getMessage("ButtonSave"));
046
047    JButton addLoadButton = new JButton(Bundle.getMessage("AddLoad"));
048    JButton deleteLoadButton = new JButton(Bundle.getMessage("DeleteLoad"));
049    JButton deleteAllLoadsButton = new JButton(Bundle.getMessage("DeleteAll"));
050
051    JButton addShipLoadButton = new JButton(Bundle.getMessage("AddLoad"));
052    JButton deleteShipLoadButton = new JButton(Bundle.getMessage("DeleteLoad"));
053    JButton deleteAllShipLoadsButton = new JButton(Bundle.getMessage("DeleteAll"));
054
055    // check boxes
056    JCheckBox loadAndTypeCheckBox = new JCheckBox(Bundle.getMessage("TypeAndLoad"));
057    JCheckBox shipLoadAndTypeCheckBox = new JCheckBox(Bundle.getMessage("TypeAndLoad"));
058    JCheckBox holdCars = new JCheckBox(Bundle.getMessage("HoldCarsWithCustomLoads"));
059    JCheckBox disableLoadChange = new JCheckBox(Bundle.getMessage("DisableLoadChange"));
060    JCheckBox quickLoadService = new JCheckBox(Bundle.getMessage("QuickLoadService"));
061
062    // radio buttons
063    JRadioButton loadNameAll = new JRadioButton(Bundle.getMessage("AcceptAll"));
064    JRadioButton loadNameInclude = new JRadioButton(Bundle.getMessage("AcceptOnly"));
065    JRadioButton loadNameExclude = new JRadioButton(Bundle.getMessage("Exclude"));
066
067    JRadioButton shipLoadNameAll = new JRadioButton(Bundle.getMessage("ShipsAllLoads"));
068    JRadioButton shipLoadNameInclude = new JRadioButton(Bundle.getMessage("ShipOnly"));
069    JRadioButton shipLoadNameExclude = new JRadioButton(Bundle.getMessage("Exclude"));
070
071    // combo box
072    JComboBox<String> comboBoxLoads = InstanceManager.getDefault(CarLoads.class).getComboBox(null);
073    JComboBox<String> comboBoxShipLoads = InstanceManager.getDefault(CarLoads.class).getComboBox(null);
074    JComboBox<String> comboBoxTypes = InstanceManager.getDefault(CarTypes.class).getComboBox();
075    JComboBox<String> comboBoxShipTypes = InstanceManager.getDefault(CarTypes.class).getComboBox();
076
077    JTextField factorTextField = new JTextField(5);
078
079    // labels
080    JLabel trackName = new JLabel();
081    JLabel factor = new JLabel(Bundle.getMessage("ScheduleFactor"));
082
083    public static final String DISPOSE = "dispose"; // NOI18N
084    public static final int MAX_NAME_LENGTH = Control.max_len_string_track_name;
085
086    public TrackLoadEditFrame() {
087        super(Bundle.getMessage("TitleEditTrackLoads"));
088    }
089
090    public void initComponents(Location location, Track track) {
091        _location = location;
092        _track = track;
093
094        // property changes
095        _location.addPropertyChangeListener(this);
096        // listen for car load name and type changes
097        InstanceManager.getDefault(CarLoads.class).addPropertyChangeListener(this);
098        InstanceManager.getDefault(CarTypes.class).addPropertyChangeListener(this);
099
100        // the following code sets the frame's initial state
101        getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
102
103        // Set up the panels
104        // Layout the panel by rows
105        // row 1
106        JPanel p1 = new JPanel();
107        p1.setLayout(new BoxLayout(p1, BoxLayout.X_AXIS));
108        p1.setMaximumSize(new Dimension(2000, 250));
109
110        // row 1a
111        JPanel pTrackName = new JPanel();
112        pTrackName.setLayout(new GridBagLayout());
113        pTrackName.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Track")));
114        addItem(pTrackName, trackName, 0, 0);
115
116        // row 1b
117        JPanel pLocationName = new JPanel();
118        pLocationName.setLayout(new GridBagLayout());
119        pLocationName.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Location")));
120        addItem(pLocationName, new JLabel(_location.getName()), 0, 0);
121
122        p1.add(pTrackName);
123        p1.add(pLocationName);
124
125        // row 3
126        JPanel p3 = new JPanel();
127        p3.setLayout(new BoxLayout(p3, BoxLayout.Y_AXIS));
128        JScrollPane pane3 = new JScrollPane(p3);
129        pane3.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("LoadsTrack")));
130        pane3.setMaximumSize(new Dimension(2000, 400));
131
132        JPanel pLoadRadioButtons = new JPanel();
133        pLoadRadioButtons.setLayout(new FlowLayout());
134
135        pLoadRadioButtons.add(loadNameAll);
136        pLoadRadioButtons.add(loadNameInclude);
137        pLoadRadioButtons.add(loadNameExclude);
138        pLoadRadioButtons.add(loadAndTypeCheckBox);
139
140        pLoadControls.setLayout(new FlowLayout());
141
142        pLoadControls.add(comboBoxTypes);
143        pLoadControls.add(comboBoxLoads);
144        pLoadControls.add(addLoadButton);
145        pLoadControls.add(deleteLoadButton);
146        pLoadControls.add(deleteAllLoadsButton);
147
148        pLoadControls.setVisible(false);
149
150        p3.add(pLoadRadioButtons);
151        p3.add(pLoadControls);
152
153        // row 4
154        panelLoads.setLayout(new GridBagLayout());
155        paneLoads.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Loads")));
156
157        ButtonGroup loadGroup = new ButtonGroup();
158        loadGroup.add(loadNameAll);
159        loadGroup.add(loadNameInclude);
160        loadGroup.add(loadNameExclude);
161
162        // row 6
163        JPanel p6 = new JPanel();
164        p6.setLayout(new BoxLayout(p6, BoxLayout.Y_AXIS));
165        paneShipLoadControls = new JScrollPane(p6);
166        paneShipLoadControls.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("ShipLoadsTrack")));
167        paneShipLoadControls.setMaximumSize(new Dimension(2000, 400));
168
169        JPanel pShipLoadRadioButtons = new JPanel();
170        pShipLoadRadioButtons.setLayout(new FlowLayout());
171
172        pShipLoadRadioButtons.add(shipLoadNameAll);
173        pShipLoadRadioButtons.add(shipLoadNameInclude);
174        pShipLoadRadioButtons.add(shipLoadNameExclude);
175        pShipLoadRadioButtons.add(shipLoadAndTypeCheckBox);
176
177        pShipLoadControls.setLayout(new FlowLayout());
178
179        pShipLoadControls.add(comboBoxShipTypes);
180        pShipLoadControls.add(comboBoxShipLoads);
181        pShipLoadControls.add(addShipLoadButton);
182        pShipLoadControls.add(deleteShipLoadButton);
183        pShipLoadControls.add(deleteAllShipLoadsButton);
184
185        pShipLoadControls.setVisible(false);
186
187        p6.add(pShipLoadRadioButtons);
188        p6.add(pShipLoadControls);
189
190        // row 7
191        panelShipLoads.setLayout(new GridBagLayout());
192        paneShipLoads.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Loads")));
193
194        ButtonGroup shipLoadGroup = new ButtonGroup();
195        shipLoadGroup.add(shipLoadNameAll);
196        shipLoadGroup.add(shipLoadNameInclude);
197        shipLoadGroup.add(shipLoadNameExclude);
198        
199        JPanel pOptions = new JPanel();
200        pOptions.setLayout(new GridBagLayout());
201        pOptions.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Options")));
202        pOptions.setMaximumSize(new Dimension(2000, 400));
203        addItemLeft(pOptions, disableLoadChange, 0, 0);
204        addItemLeft(pOptions, quickLoadService, 0, 1);
205        addItemLeft(pOptions, holdCars, 0, 2);
206        disableLoadChange.setToolTipText(Bundle.getMessage("DisableLoadChangeTip"));
207        quickLoadService.setToolTipText(Bundle.getMessage("QuickLoadServiceTip"));
208        holdCars.setToolTipText(Bundle.getMessage("HoldCarsWithCustomLoadsTip"));
209        
210        addItemLeft(pOptions, factor, 0, 3);
211        addItemLeft(pOptions, factorTextField, 1, 3);
212        factorTextField.setToolTipText(Bundle.getMessage("TipScheduleFactor"));
213
214        // row 12
215        JPanel panelButtons = new JPanel();
216        panelButtons.setLayout(new GridBagLayout());
217        panelButtons.setBorder(BorderFactory.createTitledBorder(""));
218        panelButtons.setMaximumSize(new Dimension(2000, 200));
219
220        // row 13
221        addItem(panelButtons, saveButton, 0, 0);
222
223        getContentPane().add(p1);
224        getContentPane().add(pane3);
225        getContentPane().add(paneLoads);
226        getContentPane().add(paneShipLoadControls);
227        getContentPane().add(paneShipLoads);
228        getContentPane().add(pOptions);
229        getContentPane().add(panelButtons);
230
231        // setup buttons
232        addButtonAction(saveButton);
233
234        addButtonAction(deleteLoadButton);
235        addButtonAction(deleteAllLoadsButton);
236        addButtonAction(addLoadButton);
237
238        addButtonAction(deleteShipLoadButton);
239        addButtonAction(deleteAllShipLoadsButton);
240        addButtonAction(addShipLoadButton);
241
242        addRadioButtonAction(loadNameAll);
243        addRadioButtonAction(loadNameInclude);
244        addRadioButtonAction(loadNameExclude);
245
246        addRadioButtonAction(shipLoadNameAll);
247        addRadioButtonAction(shipLoadNameInclude);
248        addRadioButtonAction(shipLoadNameExclude);
249
250        addComboBoxAction(comboBoxTypes);
251        addComboBoxAction(comboBoxShipTypes);
252
253        paneShipLoadControls.setVisible(false);
254        paneShipLoads.setVisible(false);
255        pOptions.setVisible(false);
256
257        // load fields and enable buttons
258        if (_track != null) {
259            _track.addPropertyChangeListener(this);
260            trackName.setText(_track.getName());
261            // only show ship loads for staging tracks
262            paneShipLoadControls.setVisible(_track.isStaging());
263            paneShipLoads.setVisible(_track.isStaging());
264            pOptions.setVisible(_track.isSpur());
265            holdCars.setEnabled(_track.getSchedule() != null && _track.getAlternateTrack() != null);
266            holdCars.setSelected(_track.isHoldCarsWithCustomLoadsEnabled());
267            disableLoadChange.setSelected(_track.isDisableLoadChangeEnabled());
268            quickLoadService.setSelected(_track.isQuickServiceEnabled());
269            factor.setEnabled(_track.getSchedule() != null);
270            factorTextField.setEnabled(_track.getSchedule() != null);
271            factorTextField.setText(Integer.toString(_track.getReservationFactor()));
272            updateButtons(true);
273        } else {
274            updateButtons(false);
275        }
276
277        updateTypeComboBoxes();
278        updateLoadComboBoxes();
279        updateLoadNames();
280        updateShipLoadNames();
281
282        loadAndTypeCheckBox.setSelected(loadAndType);
283        shipLoadAndTypeCheckBox.setSelected(shipLoadAndType);
284        
285        // add help menu to window
286        addHelpMenu("package.jmri.jmrit.operations.Operations_LoadOptions", true); // NOI18N
287
288        initMinimumSize(new Dimension(Control.panelWidth600, Control.panelHeight400));
289    }
290
291    // Save, Delete, Add
292    @Override
293    public void buttonActionPerformed(java.awt.event.ActionEvent ae) {
294        if (_track == null) {
295            return;
296        }
297        if (ae.getSource() == saveButton) {
298            log.debug("track save button activated");
299            save();
300        }
301        if (ae.getSource() == addLoadButton) {
302            String loadName = (String) comboBoxLoads.getSelectedItem();
303            if (loadAndTypeCheckBox.isSelected()) {
304                loadName = comboBoxTypes.getSelectedItem() + CarLoad.SPLIT_CHAR + loadName;
305            }
306            _track.addLoadName(loadName);
307            selectNextItemComboBox(comboBoxLoads);
308        }
309        if (ae.getSource() == deleteLoadButton) {
310            String loadName = (String) comboBoxLoads.getSelectedItem();
311            if (loadAndTypeCheckBox.isSelected()) {
312                loadName = comboBoxTypes.getSelectedItem() + CarLoad.SPLIT_CHAR + loadName;
313            }
314            _track.deleteLoadName(loadName);
315            selectNextItemComboBox(comboBoxLoads);
316        }
317        if (ae.getSource() == deleteAllLoadsButton) {
318            deleteAllLoads();
319        }
320        if (ae.getSource() == addShipLoadButton) {
321            String loadName = (String) comboBoxShipLoads.getSelectedItem();
322            if (shipLoadAndTypeCheckBox.isSelected()) {
323                loadName = comboBoxShipTypes.getSelectedItem() + CarLoad.SPLIT_CHAR + loadName;
324            }
325            _track.addShipLoadName(loadName);
326            selectNextItemComboBox(comboBoxShipLoads);
327        }
328        if (ae.getSource() == deleteShipLoadButton) {
329            String loadName = (String) comboBoxShipLoads.getSelectedItem();
330            if (shipLoadAndTypeCheckBox.isSelected()) {
331                loadName = comboBoxShipTypes.getSelectedItem() + CarLoad.SPLIT_CHAR + loadName;
332            }
333            _track.deleteShipLoadName(loadName);
334            selectNextItemComboBox(comboBoxShipLoads);
335        }
336        if (ae.getSource() == deleteAllShipLoadsButton) {
337            deleteAllShipLoads();
338        }
339    }
340
341    @SuppressFBWarnings(value = "ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD", justification = "GUI ease of use")
342    protected void save() {
343        if (!checkForErrors()) {
344            _track.setHoldCarsWithCustomLoadsEnabled(holdCars.isSelected());
345            _track.setDisableLoadChangeEnabled(disableLoadChange.isSelected());
346            _track.setQuickServiceEnabled(quickLoadService.isSelected());
347            saveReservationFactor();
348            // save the last state of the "Use car type and load" checkbox
349            loadAndType = loadAndTypeCheckBox.isSelected();
350            shipLoadAndType = shipLoadAndTypeCheckBox.isSelected();
351            // save location file
352            OperationsXml.save();
353            if (Setup.isCloseWindowOnSaveEnabled()) {
354                dispose();
355            }
356        }
357    }
358
359    /*
360     * percentage from staging
361     */
362    private void saveReservationFactor() {
363        boolean okay = false;
364        try {
365            int factor = Integer.parseInt(factorTextField.getText());
366            if (0 <= factor && factor <= 1000) {
367                okay = true;
368            }
369        } catch (NumberFormatException e) {
370            // do nothing
371        }
372        if (okay) {
373            _track.setReservationFactor(Integer.parseInt(factorTextField.getText()));
374        } else {
375            JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("FactorMustBeNumber"),
376                    Bundle.getMessage("ErrorTitle"), JmriJOptionPane.ERROR_MESSAGE);
377        }
378    }
379
380    protected void updateButtons(boolean enabled) {
381        saveButton.setEnabled(enabled);
382
383        loadNameAll.setEnabled(enabled);
384        loadNameInclude.setEnabled(enabled);
385        loadNameExclude.setEnabled(enabled);
386        loadAndTypeCheckBox.setEnabled(enabled);
387
388        // enable ship options if any of the three generate loads from staging is selected
389        // or if there are any ship load restrictions for this track
390        boolean en = enabled
391                && (_track.isAddCustomLoadsAnyStagingTrackEnabled() || _track.isAddCustomLoadsAnySpurEnabled() || _track
392                .isAddCustomLoadsEnabled() || !_track.getShipLoadOption().equals(Track.ALL_LOADS));
393
394        shipLoadNameAll.setEnabled(en);
395        shipLoadNameInclude.setEnabled(en);
396        shipLoadNameExclude.setEnabled(en);
397        shipLoadAndTypeCheckBox.setEnabled(en);
398
399        addShipLoadButton.setEnabled(en);
400        deleteShipLoadButton.setEnabled(en);
401        deleteAllShipLoadsButton.setEnabled(en);
402
403        comboBoxShipLoads.setEnabled(en);
404        comboBoxShipTypes.setEnabled(en);
405    }
406
407    @Override
408    public void radioButtonActionPerformed(java.awt.event.ActionEvent ae) {
409        log.debug("radio button activated");
410        if (ae.getSource() == loadNameAll) {
411            _track.setLoadOption(Track.ALL_LOADS);
412        }
413        if (ae.getSource() == loadNameInclude) {
414            _track.setLoadOption(Track.INCLUDE_LOADS);
415        }
416        if (ae.getSource() == loadNameExclude) {
417            _track.setLoadOption(Track.EXCLUDE_LOADS);
418        }
419        if (ae.getSource() == shipLoadNameAll) {
420            _track.setShipLoadOption(Track.ALL_LOADS);
421        }
422        if (ae.getSource() == shipLoadNameInclude) {
423            _track.setShipLoadOption(Track.INCLUDE_LOADS);
424        }
425        if (ae.getSource() == shipLoadNameExclude) {
426            _track.setShipLoadOption(Track.EXCLUDE_LOADS);
427        }
428    }
429
430    // Car type combo box has been changed, show loads associated with this car type
431    @Override
432    public void comboBoxActionPerformed(java.awt.event.ActionEvent ae) {
433        updateLoadComboBoxes();
434    }
435
436    private void updateLoadComboBoxes() {
437        String carType = (String) comboBoxTypes.getSelectedItem();
438        InstanceManager.getDefault(CarLoads.class).updateComboBox(carType, comboBoxLoads);
439        carType = (String) comboBoxShipTypes.getSelectedItem();
440        InstanceManager.getDefault(CarLoads.class).updateComboBox(carType, comboBoxShipLoads);
441    }
442
443    private void updateLoadNames() {
444        log.debug("Update load names");
445        panelLoads.removeAll();
446        if (_track != null) {
447            // set radio button
448            loadNameAll.setSelected(_track.getLoadOption().equals(Track.ALL_LOADS));
449            loadNameInclude.setSelected(_track.getLoadOption().equals(Track.INCLUDE_LOADS));
450            loadNameExclude.setSelected(_track.getLoadOption().equals(Track.EXCLUDE_LOADS));
451
452            pLoadControls.setVisible(!loadNameAll.isSelected());
453
454            if (!loadNameAll.isSelected()) {
455                int x = 0;
456                int y = 0; // vertical position in panel
457
458                int numberOfLoads = getNumberOfCheckboxesPerLine() / 2 + 1;
459                for (String loadName : _track.getLoadNames()) {
460                    JLabel load = new JLabel();
461                    load.setText(loadName);
462                    addItemTop(panelLoads, load, x++, y);
463                    // limit the number of loads per line
464                    if (x > numberOfLoads) {
465                        y++;
466                        x = 0;
467                    }
468                }
469                revalidate();
470            }
471        } else {
472            loadNameAll.setSelected(true);
473        }
474        panelLoads.repaint();
475        panelLoads.revalidate();
476    }
477
478    private void updateShipLoadNames() {
479        log.debug("Update ship load names");
480        panelShipLoads.removeAll();
481        if (_track != null) {
482            // set radio button
483            shipLoadNameAll.setSelected(_track.getShipLoadOption().equals(Track.ALL_LOADS));
484            shipLoadNameInclude.setSelected(_track.getShipLoadOption().equals(Track.INCLUDE_LOADS));
485            shipLoadNameExclude.setSelected(_track.getShipLoadOption().equals(Track.EXCLUDE_LOADS));
486
487            pShipLoadControls.setVisible(!shipLoadNameAll.isSelected());
488
489            if (!shipLoadNameAll.isSelected()) {
490                int x = 0;
491                int y = 0; // vertical position in panel
492
493                int numberOfLoads = getNumberOfCheckboxesPerLine() / 2 + 1;
494                for (String loadName : _track.getShipLoadNames()) {
495                    JLabel load = new JLabel();
496                    load.setText(loadName);
497                    addItemTop(panelShipLoads, load, x++, y);
498                    // limit the number of loads per line
499                    if (x > numberOfLoads) {
500                        y++;
501                        x = 0;
502                    }
503                }
504                revalidate();
505            }
506        } else {
507            shipLoadNameAll.setSelected(true);
508        }
509        panelShipLoads.repaint();
510        panelShipLoads.revalidate();
511    }
512
513    private void deleteAllLoads() {
514        if (_track != null) {
515            for (String loadName : _track.getLoadNames()) {
516                _track.deleteLoadName(loadName);
517            }
518        }
519    }
520
521    private void deleteAllShipLoads() {
522        if (_track != null) {
523            for (String loadName : _track.getShipLoadNames()) {
524                _track.deleteShipLoadName(loadName);
525            }
526        }
527    }
528
529    private void updateTypeComboBoxes() {
530        InstanceManager.getDefault(CarTypes.class).updateComboBox(comboBoxTypes);
531        // remove car types not serviced by this location and track
532        for (int i = comboBoxTypes.getItemCount() - 1; i >= 0; i--) {
533            String type = comboBoxTypes.getItemAt(i);
534            if (_track != null && !_track.isTypeNameAccepted(type)) {
535                comboBoxTypes.removeItem(type);
536            }
537        }
538        InstanceManager.getDefault(CarTypes.class).updateComboBox(comboBoxShipTypes);
539        // remove car types not serviced by this location and track
540        for (int i = comboBoxShipTypes.getItemCount() - 1; i >= 0; i--) {
541            String type = comboBoxShipTypes.getItemAt(i);
542            if (_track != null && !_track.isTypeNameAccepted(type)) {
543                comboBoxShipTypes.removeItem(type);
544            }
545        }
546    }
547
548    private boolean checkForErrors() {
549        if (_track.getLoadOption().equals(Track.INCLUDE_LOADS) && _track.getLoadNames().length == 0
550                || _track.getShipLoadOption().equals(Track.INCLUDE_LOADS) && _track.getShipLoadNames().length == 0) {
551            JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("ErrorNeedLoads"), Bundle.getMessage("ErrorNoLoads"),
552                    JmriJOptionPane.ERROR_MESSAGE);
553            return true;
554        }
555        return false;
556    }
557
558    @Override
559    public void dispose() {
560        if (_track != null) {
561            _track.removePropertyChangeListener(this);
562        }
563        _location.removePropertyChangeListener(this);
564        InstanceManager.getDefault(CarLoads.class).removePropertyChangeListener(this);
565        InstanceManager.getDefault(CarTypes.class).removePropertyChangeListener(this);
566        super.dispose();
567    }
568
569    @Override
570    public void propertyChange(java.beans.PropertyChangeEvent e) {
571        if (Control.SHOW_PROPERTY) {
572            log.debug("Property change ({}) old: ({}) new: ({})", e.getPropertyName(), e.getOldValue(), e.getNewValue()); // NOI18N
573        }
574        if (e.getPropertyName().equals(Location.TYPES_CHANGED_PROPERTY)
575                || e.getPropertyName().equals(CarTypes.CARTYPES_CHANGED_PROPERTY)
576                || e.getPropertyName().equals(Track.TYPES_CHANGED_PROPERTY)) {
577            updateTypeComboBoxes();
578        }
579        if (e.getPropertyName().equals(CarLoads.LOAD_NAME_CHANGED_PROPERTY)
580                || e.getPropertyName().equals(CarLoads.LOAD_CHANGED_PROPERTY)) {
581            updateLoadComboBoxes();
582            updateLoadNames();
583            updateShipLoadNames();
584        }
585        if (e.getPropertyName().equals(Track.LOADS_CHANGED_PROPERTY)) {
586            updateLoadNames();
587            updateShipLoadNames();
588        }
589        if (_track != null) {
590            if (e.getPropertyName().equals(Track.LOAD_OPTIONS_CHANGED_PROPERTY)) {
591                updateButtons(true);
592                disableLoadChange.setSelected(_track.isDisableLoadChangeEnabled());
593                quickLoadService.setSelected(_track.isQuickServiceEnabled());
594            }
595            if (e.getPropertyName().equals(Track.HOLD_CARS_CHANGED_PROPERTY)) {
596                holdCars.setSelected(_track.isHoldCarsWithCustomLoadsEnabled());
597            }
598            if (e.getPropertyName().equals(Track.ALTERNATE_TRACK_CHANGED_PROPERTY) ||
599                    e.getPropertyName().equals(Track.SCHEDULE_ID_CHANGED_PROPERTY)) {
600                holdCars.setEnabled(_track.getSchedule() != null && _track.getAlternateTrack() != null);
601            }
602            if (e.getPropertyName().equals(Track.TRACK_FACTOR_CHANGED_PROPERTY)) {
603                factorTextField.setText(Integer.toString(_track.getReservationFactor()));
604            }
605        }
606    }
607
608    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(TrackLoadEditFrame.class);
609}