001package jmri.jmrit.operations.rollingstock.engines; 002 003import java.beans.PropertyChangeEvent; 004import java.beans.PropertyChangeListener; 005import java.text.MessageFormat; 006import java.util.List; 007 008import javax.swing.*; 009import javax.swing.table.TableColumnModel; 010 011import jmri.InstanceManager; 012import jmri.jmrit.operations.OperationsFrame; 013import jmri.jmrit.operations.OperationsXml; 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 NceConsistEngineAction()); 194 menuBar.add(toolMenu); 195 menuBar.add(new jmri.jmrit.operations.OperationsMenu()); 196 setJMenuBar(menuBar); 197 addHelpMenu("package.jmri.jmrit.operations.Operations_Locomotives", true); // NOI18N 198 199 initMinimumSize(); 200 201 addHorizontalScrollBarKludgeFix(controlPane, controlPanel); 202 203 // create ShutDownTasks 204 createShutDownTask(); 205 } 206 207 @Override 208 public void radioButtonActionPerformed(java.awt.event.ActionEvent ae) { 209 log.debug("radio button activated"); 210 // clear any sorts by column 211 clearTableSort(enginesTable); 212 if (ae.getSource() == sortByNumber) { 213 enginesModel.setSort(enginesModel.SORTBY_NUMBER); 214 } 215 if (ae.getSource() == sortByRoad) { 216 enginesModel.setSort(enginesModel.SORTBY_ROAD); 217 } 218 if (ae.getSource() == sortByModel) { 219 enginesModel.setSort(enginesModel.SORTBY_MODEL); 220 } 221 if (ae.getSource() == sortByConsist) { 222 enginesModel.setSort(enginesModel.SORTBY_CONSIST); 223 } 224 if (ae.getSource() == sortByLocation) { 225 enginesModel.setSort(enginesModel.SORTBY_LOCATION); 226 } 227 if (ae.getSource() == sortByDestination) { 228 enginesModel.setSort(enginesModel.SORTBY_DESTINATION); 229 } 230 if (ae.getSource() == sortByTrain) { 231 enginesModel.setSort(enginesModel.SORTBY_TRAIN); 232 } 233 if (ae.getSource() == sortByMoves) { 234 enginesModel.setSort(enginesModel.SORTBY_MOVES); 235 } 236 if (ae.getSource() == sortByBuilt) { 237 enginesModel.setSort(enginesModel.SORTBY_BUILT); 238 } 239 if (ae.getSource() == sortByOwner) { 240 enginesModel.setSort(enginesModel.SORTBY_OWNER); 241 } 242 if (ae.getSource() == sortByValue) { 243 enginesModel.setSort(enginesModel.SORTBY_VALUE); 244 } 245 if (ae.getSource() == sortByRfid) { 246 enginesModel.setSort(enginesModel.SORTBY_RFID); 247 } 248 if (ae.getSource() == sortByLast) { 249 enginesModel.setSort(enginesModel.SORTBY_LAST); 250 } 251 if (ae.getSource() == sortByDcc) { 252 enginesModel.setSort(enginesModel.SORTBY_DCC_ADDRESS); 253 } 254 if (ae.getSource() == sortByComment) { 255 enginesModel.setSort(enginesModel.SORTBY_COMMENT); 256 } 257 } 258 259 public List<Engine> getSortByList() { 260 return enginesModel.getSelectedEngineList(); 261 } 262 263 EngineEditFrame engineEditFrame = null; 264 265 // add, save or find button 266 @Override 267 public void buttonActionPerformed(java.awt.event.ActionEvent ae) { 268 // log.debug("engine button activated"); 269 if (ae.getSource() == findButton) { 270 int rowindex = enginesModel.findEngineByRoadNumber(findEngineTextBox.getText()); 271 if (rowindex < 0) { 272 JmriJOptionPane.showMessageDialog(this, MessageFormat.format( 273 Bundle.getMessage("engineWithRoadNumNotFound"), new Object[]{findEngineTextBox.getText()}), 274 Bundle.getMessage("engineCouldNotFind"), JmriJOptionPane.INFORMATION_MESSAGE); 275 return; 276 277 } 278 // clear any sorts by column 279 clearTableSort(enginesTable); 280 enginesTable.changeSelection(rowindex, 0, false, false); 281 return; 282 } 283 if (ae.getSource() == addButton) { 284 if (engineEditFrame != null) { 285 engineEditFrame.dispose(); 286 } 287 engineEditFrame = new EngineEditFrame(); 288 engineEditFrame.initComponents(); 289 } 290 if (ae.getSource() == saveButton) { 291 if (enginesTable.isEditing()) { 292 log.debug("locomotives table edit true"); 293 enginesTable.getCellEditor().stopCellEditing(); 294 } 295 OperationsXml.save(); 296 if (Setup.isCloseWindowOnSaveEnabled()) { 297 dispose(); 298 } 299 } 300 } 301 302 protected int[] getCurrentTableColumnWidths() { 303 TableColumnModel tcm = enginesTable.getColumnModel(); 304 int[] widths = new int[tcm.getColumnCount()]; 305 for (int i = 0; i < tcm.getColumnCount(); i++) { 306 widths[i] = tcm.getColumn(i).getWidth(); 307 } 308 return widths; 309 } 310 311 @Override 312 public void dispose() { 313 engineManager.removePropertyChangeListener(this); 314 enginesModel.dispose(); 315 if (engineEditFrame != null) { 316 engineEditFrame.dispose(); 317 } 318 InstanceManager.getOptionalDefault(JTablePersistenceManager.class).ifPresent(tpm -> { 319 tpm.stopPersisting(enginesTable); 320 }); 321 super.dispose(); 322 } 323 324 @Override 325 public void propertyChange(PropertyChangeEvent e) { 326 if (Control.SHOW_PROPERTY) { 327 log.debug("Property change: ({}) old: ({}) new: ({})", e.getPropertyName(), e.getOldValue(), e 328 .getNewValue()); 329 } 330 if (e.getPropertyName().equals(EngineManager.LISTLENGTH_CHANGED_PROPERTY)) { 331 numEngines.setText(Integer.toString(engineManager.getNumEntries())); 332 } 333 } 334 335 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(EnginesTableFrame.class); 336}