001package jmri.jmrit.operations.rollingstock.engines;
002
003import java.beans.PropertyChangeEvent;
004import java.beans.PropertyChangeListener;
005import java.util.List;
006
007import javax.swing.*;
008import javax.swing.table.TableColumnModel;
009
010import jmri.InstanceManager;
011import jmri.jmrit.operations.OperationsFrame;
012import jmri.jmrit.operations.OperationsXml;
013import jmri.jmrit.operations.rollingstock.engines.tools.EnginesSetFrameAction;
014import jmri.jmrit.operations.rollingstock.engines.tools.NceConsistEngineAction;
015import jmri.jmrit.operations.setup.Control;
016import jmri.jmrit.operations.setup.Setup;
017import jmri.swing.JTablePersistenceManager;
018import jmri.util.swing.JmriJOptionPane;
019
020/**
021 * Frame for adding and editing the engine roster for operations.
022 *
023 * @author Bob Jacobsen Copyright (C) 2001
024 * @author Daniel Boudreau Copyright (C) 2008, 2011, 2012, 2013
025 */
026public class EnginesTableFrame extends OperationsFrame implements PropertyChangeListener {
027
028    public EnginesTableModel enginesModel;
029    javax.swing.JTable enginesTable;
030    JScrollPane enginesPane;
031    EngineManager engineManager = InstanceManager.getDefault(EngineManager.class);
032
033    // labels
034    JLabel numEngines = new JLabel();
035    JLabel textEngines = new JLabel();
036    JLabel textSep1 = new JLabel("          ");
037
038    // radio buttons
039    JRadioButton sortByNumber = new JRadioButton(Bundle.getMessage("Number"));
040    JRadioButton sortByRoad = new JRadioButton(Bundle.getMessage("Road"));
041    JRadioButton sortByModel = new JRadioButton(Bundle.getMessage("Model"));
042    public JRadioButton sortByConsist = new JRadioButton(Bundle.getMessage("Consist"));
043    JRadioButton sortByLocation = new JRadioButton(Bundle.getMessage("Location"));
044    JRadioButton sortByDestination = new JRadioButton(Bundle.getMessage("Destination"));
045    JRadioButton sortByTrain = new JRadioButton(Bundle.getMessage("Train"));
046    JRadioButton sortByMoves = new JRadioButton(Bundle.getMessage("Moves"));
047    JRadioButton sortByBuilt = new JRadioButton(Bundle.getMessage("Built"));
048    JRadioButton sortByOwner = new JRadioButton(Bundle.getMessage("Owner"));
049    public JRadioButton sortByValue = new JRadioButton(Setup.getValueLabel());
050    public JRadioButton sortByRfid = new JRadioButton(Setup.getRfidLabel());
051    JRadioButton sortByDcc = new JRadioButton(Bundle.getMessage("DccAddress"));
052    JRadioButton sortByLast = new JRadioButton(Bundle.getMessage("Last"));
053    JRadioButton sortByComment = new JRadioButton(Bundle.getMessage("Comment"));
054    ButtonGroup group = new ButtonGroup();
055
056    // major buttons
057    JButton addButton = new JButton(Bundle.getMessage("TitleEngineAdd"));
058    JButton findButton = new JButton(Bundle.getMessage("Find"));
059    JButton saveButton = new JButton(Bundle.getMessage("ButtonSave"));
060
061    JTextField findEngineTextBox = new JTextField(6);
062
063    public EnginesTableFrame() {
064        super(Bundle.getMessage("TitleEnginesTable"));
065        // general GUI config
066
067        getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
068
069        // Set up the jtable in a Scroll Pane..
070        enginesModel = new EnginesTableModel();
071        enginesTable = new JTable(enginesModel);
072        enginesPane = new JScrollPane(enginesTable);
073        enginesPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
074        enginesModel.initTable(enginesTable, this);
075
076        // load the number of engines and listen for changes
077        numEngines.setText(Integer.toString(engineManager.getNumEntries()));
078        engineManager.addPropertyChangeListener(this);
079        textEngines.setText(Bundle.getMessage("engines"));
080
081        // Set up the control panel
082        // row 1
083        JPanel cp1 = new JPanel();
084        cp1.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("SortBy")));
085
086        cp1.add(sortByNumber);
087        cp1.add(sortByRoad);
088        cp1.add(sortByModel);
089        cp1.add(sortByConsist);
090        cp1.add(sortByLocation);
091        cp1.add(sortByDestination);
092        cp1.add(sortByTrain);
093        JPanel movep = new JPanel();
094        movep.setBorder(BorderFactory.createTitledBorder(""));
095        movep.add(sortByMoves);
096        movep.add(sortByBuilt);
097        movep.add(sortByOwner);
098        if (Setup.isValueEnabled()) {
099            movep.add(sortByValue);
100        }
101        if (Setup.isRfidEnabled()) {
102            movep.add(sortByRfid);
103        }
104        movep.add(sortByDcc);
105        movep.add(sortByLast);
106        movep.add(sortByComment);
107        cp1.add(movep);
108
109        // row 2
110        JPanel cp2 = new JPanel();
111        cp2.setLayout(new BoxLayout(cp2, BoxLayout.X_AXIS));
112
113        JPanel cp2Add = new JPanel();
114        cp2Add.setBorder(BorderFactory.createTitledBorder(""));
115        addButton.setToolTipText(Bundle.getMessage("TipAddButton"));
116        cp2Add.add(numEngines);
117        cp2Add.add(textEngines);
118        cp2Add.add(textSep1);
119        cp2Add.add(addButton);
120        cp2.add(cp2Add);
121
122        JPanel cp2Find = new JPanel();
123        cp2Find.setBorder(BorderFactory.createTitledBorder(""));
124        findButton.setToolTipText(Bundle.getMessage("findEngine"));
125        findEngineTextBox.setToolTipText(Bundle.getMessage("findEngine"));
126        cp2Find.add(findButton);
127        cp2Find.add(findEngineTextBox);
128        cp2.add(cp2Find);
129
130        JPanel cp2Save = new JPanel();
131        cp2Save.setBorder(BorderFactory.createTitledBorder(""));
132        cp2Save.add(saveButton);
133        cp2.add(cp2Save);
134
135        // place controls in scroll pane
136        JPanel controlPanel = new JPanel();
137        controlPanel.setLayout(new BoxLayout(controlPanel, BoxLayout.Y_AXIS));
138        controlPanel.add(cp1);
139        controlPanel.add(cp2);
140
141        // some tool tips
142        sortByLast.setToolTipText(Bundle.getMessage("TipLastMoved"));
143
144        JScrollPane controlPane = new JScrollPane(controlPanel);
145
146        getContentPane().add(enginesPane);
147        getContentPane().add(controlPane);
148
149        // setup buttons
150        addButtonAction(addButton);
151        addButtonAction(findButton);
152        addButtonAction(saveButton);
153
154        sortByNumber.setSelected(true);
155        addRadioButtonAction(sortByNumber);
156        addRadioButtonAction(sortByRoad);
157        addRadioButtonAction(sortByModel);
158        addRadioButtonAction(sortByConsist);
159        addRadioButtonAction(sortByLocation);
160        addRadioButtonAction(sortByDestination);
161        addRadioButtonAction(sortByTrain);
162        addRadioButtonAction(sortByMoves);
163        addRadioButtonAction(sortByBuilt);
164        addRadioButtonAction(sortByOwner);
165        addRadioButtonAction(sortByValue);
166        addRadioButtonAction(sortByRfid);
167        addRadioButtonAction(sortByDcc);
168        addRadioButtonAction(sortByLast);
169        addRadioButtonAction(sortByComment);
170
171        group.add(sortByNumber);
172        group.add(sortByRoad);
173        group.add(sortByModel);
174        group.add(sortByConsist);
175        group.add(sortByLocation);
176        group.add(sortByDestination);
177        group.add(sortByTrain);
178        group.add(sortByMoves);
179        group.add(sortByBuilt);
180        group.add(sortByOwner);
181        group.add(sortByValue);
182        group.add(sortByRfid);
183        group.add(sortByDcc);
184        group.add(sortByLast);
185        group.add(sortByComment);
186        
187        sortByDcc.setToolTipText(Bundle.getMessage("TipDccAddressFromRoster"));
188
189        // build menu
190        JMenuBar menuBar = new JMenuBar();
191        JMenu toolMenu = new JMenu(Bundle.getMessage("MenuTools"));
192        toolMenu.add(new EngineRosterMenu(Bundle.getMessage("TitleEngineRoster"), EngineRosterMenu.MAINMENU, this));
193        toolMenu.add(new EnginesSetFrameAction(enginesTable));
194        toolMenu.add(new NceConsistEngineAction());
195        menuBar.add(toolMenu);
196        menuBar.add(new jmri.jmrit.operations.OperationsMenu());
197        setJMenuBar(menuBar);
198        addHelpMenu("package.jmri.jmrit.operations.Operations_Locomotives", true); // NOI18N
199
200        initMinimumSize();
201
202        addHorizontalScrollBarKludgeFix(controlPane, controlPanel);
203
204        // create ShutDownTasks
205        createShutDownTask();
206    }
207
208    @Override
209    public void radioButtonActionPerformed(java.awt.event.ActionEvent ae) {
210        log.debug("radio button activated");
211        // clear any sorts by column
212        clearTableSort(enginesTable);
213        if (ae.getSource() == sortByNumber) {
214            enginesModel.setSort(enginesModel.SORTBY_NUMBER);
215        }
216        if (ae.getSource() == sortByRoad) {
217            enginesModel.setSort(enginesModel.SORTBY_ROAD);
218        }
219        if (ae.getSource() == sortByModel) {
220            enginesModel.setSort(enginesModel.SORTBY_MODEL);
221        }
222        if (ae.getSource() == sortByConsist) {
223            enginesModel.setSort(enginesModel.SORTBY_CONSIST);
224        }
225        if (ae.getSource() == sortByLocation) {
226            enginesModel.setSort(enginesModel.SORTBY_LOCATION);
227        }
228        if (ae.getSource() == sortByDestination) {
229            enginesModel.setSort(enginesModel.SORTBY_DESTINATION);
230        }
231        if (ae.getSource() == sortByTrain) {
232            enginesModel.setSort(enginesModel.SORTBY_TRAIN);
233        }
234        if (ae.getSource() == sortByMoves) {
235            enginesModel.setSort(enginesModel.SORTBY_MOVES);
236        }
237        if (ae.getSource() == sortByBuilt) {
238            enginesModel.setSort(enginesModel.SORTBY_BUILT);
239        }
240        if (ae.getSource() == sortByOwner) {
241            enginesModel.setSort(enginesModel.SORTBY_OWNER);
242        }
243        if (ae.getSource() == sortByValue) {
244            enginesModel.setSort(enginesModel.SORTBY_VALUE);
245        }
246        if (ae.getSource() == sortByRfid) {
247            enginesModel.setSort(enginesModel.SORTBY_RFID);
248        }
249        if (ae.getSource() == sortByLast) {
250            enginesModel.setSort(enginesModel.SORTBY_LAST);
251        }
252        if (ae.getSource() == sortByDcc) {
253            enginesModel.setSort(enginesModel.SORTBY_DCC_ADDRESS);
254        }
255        if (ae.getSource() == sortByComment) {
256            enginesModel.setSort(enginesModel.SORTBY_COMMENT);
257        }
258    }
259
260    public List<Engine> getSortByList() {
261        return enginesModel.getSelectedEngineList();
262    }
263
264    EngineEditFrame engineEditFrame = null;
265
266    // add, save or find button
267    @Override
268    public void buttonActionPerformed(java.awt.event.ActionEvent ae) {
269        // log.debug("engine button activated");
270        if (ae.getSource() == findButton) {
271            int rowindex = enginesModel.findEngineByRoadNumber(findEngineTextBox.getText());
272            if (rowindex < 0) {
273                JmriJOptionPane.showMessageDialog(this, 
274                        Bundle.getMessage("engineWithRoadNumNotFound", findEngineTextBox.getText()),
275                        Bundle.getMessage("engineCouldNotFind"), JmriJOptionPane.INFORMATION_MESSAGE);
276                return;
277
278            }
279            // clear any sorts by column
280            clearTableSort(enginesTable);
281            enginesTable.changeSelection(rowindex, 0, false, false);
282            return;
283        }
284        if (ae.getSource() == addButton) {
285            if (engineEditFrame != null) {
286                engineEditFrame.dispose();
287            }
288            engineEditFrame = new EngineEditFrame();
289            engineEditFrame.initComponents();
290        }
291        if (ae.getSource() == saveButton) {
292            if (enginesTable.isEditing()) {
293                log.debug("locomotives table edit true");
294                enginesTable.getCellEditor().stopCellEditing();
295            }
296            OperationsXml.save();
297            if (Setup.isCloseWindowOnSaveEnabled()) {
298                dispose();
299            }
300        }
301    }
302
303    protected int[] getCurrentTableColumnWidths() {
304        TableColumnModel tcm = enginesTable.getColumnModel();
305        int[] widths = new int[tcm.getColumnCount()];
306        for (int i = 0; i < tcm.getColumnCount(); i++) {
307            widths[i] = tcm.getColumn(i).getWidth();
308        }
309        return widths;
310    }
311
312    @Override
313    public void dispose() {
314        engineManager.removePropertyChangeListener(this);
315        enginesModel.dispose();
316        if (engineEditFrame != null) {
317            engineEditFrame.dispose();
318        }
319        InstanceManager.getOptionalDefault(JTablePersistenceManager.class).ifPresent(tpm -> {
320            tpm.stopPersisting(enginesTable);
321        });
322        super.dispose();
323    }
324
325    @Override
326    public void propertyChange(PropertyChangeEvent e) {
327        if (Control.SHOW_PROPERTY) {
328            log.debug("Property change: ({}) old: ({}) new: ({})", e.getPropertyName(), e.getOldValue(), e
329                    .getNewValue());
330        }
331        if (e.getPropertyName().equals(EngineManager.LISTLENGTH_CHANGED_PROPERTY)) {
332            numEngines.setText(Integer.toString(engineManager.getNumEntries()));
333        }
334    }
335
336    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(EnginesTableFrame.class);
337}