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}