001package jmri.jmrit.operations.rollingstock.cars; 002 003import java.util.List; 004 005import javax.swing.*; 006import javax.swing.event.TableModelEvent; 007import javax.swing.event.TableModelListener; 008import javax.swing.table.TableColumnModel; 009 010import jmri.InstanceManager; 011import jmri.jmrit.operations.OperationsFrame; 012import jmri.jmrit.operations.OperationsXml; 013import jmri.jmrit.operations.locations.schedules.ScheduleManager; 014import jmri.jmrit.operations.locations.tools.ModifyLocationsAction; 015import jmri.jmrit.operations.rollingstock.cars.tools.*; 016import jmri.jmrit.operations.setup.Control; 017import jmri.jmrit.operations.setup.Setup; 018import jmri.jmrit.operations.trains.tools.TrainsByCarTypeAction; 019import jmri.swing.JTablePersistenceManager; 020import jmri.util.swing.JmriJOptionPane; 021 022/** 023 * Frame for adding and editing the car roster for operations. 024 * 025 * @author Bob Jacobsen Copyright (C) 2001 026 * @author Daniel Boudreau Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013, 027 * 2014 028 */ 029public class CarsTableFrame extends OperationsFrame implements TableModelListener { 030 031 public CarsTableModel carsTableModel; 032 public JTable carsTable; 033 boolean showAllCars; 034 String locationName; 035 String trackName; 036 CarManager carManager = InstanceManager.getDefault(CarManager.class); 037 038 // labels 039 JLabel numCars = new JLabel(); 040 JLabel textCars = new JLabel(Bundle.getMessage("cars")); 041 JLabel textSep1 = new JLabel(" "); 042 043 // radio buttons 044 JRadioButton sortByNumber = new JRadioButton(Bundle.getMessage("Number")); 045 JRadioButton sortByRoad = new JRadioButton(Bundle.getMessage("Road")); 046 JRadioButton sortByType = new JRadioButton(Bundle.getMessage("Type")); 047 JRadioButton sortByColor = new JRadioButton(Bundle.getMessage("Color")); 048 JRadioButton sortByLoad = new JRadioButton(Bundle.getMessage("Load")); 049 JRadioButton sortByKernel = new JRadioButton(Bundle.getMessage("Kernel")); 050 JRadioButton sortByLocation = new JRadioButton(Bundle.getMessage("Location")); 051 JRadioButton sortByDestination = new JRadioButton(Bundle.getMessage("Destination")); 052 JRadioButton sortByFinalDestination = new JRadioButton(Bundle.getMessage("FD")); 053 JRadioButton sortByRwe = new JRadioButton(Bundle.getMessage("RWE")); 054 JRadioButton sortByRwl = new JRadioButton(Bundle.getMessage("RWL")); 055 JRadioButton sortByRoute = new JRadioButton(Bundle.getMessage("Route")); 056 JRadioButton sortByDivision = new JRadioButton(Bundle.getMessage("Division")); 057 JRadioButton sortByTrain = new JRadioButton(Bundle.getMessage("Train")); 058 JRadioButton sortByMoves = new JRadioButton(Bundle.getMessage("Moves")); 059 JRadioButton sortByBuilt = new JRadioButton(Bundle.getMessage("Built")); 060 JRadioButton sortByOwner = new JRadioButton(Bundle.getMessage("Owner")); 061 JRadioButton sortByValue = new JRadioButton(Setup.getValueLabel()); 062 JRadioButton sortByRfid = new JRadioButton(Setup.getRfidLabel()); 063 JRadioButton sortByWait = new JRadioButton(Bundle.getMessage("Wait")); 064 JRadioButton sortByPickup = new JRadioButton(Bundle.getMessage("Pickup")); 065 JRadioButton sortByLast = new JRadioButton(Bundle.getMessage("Last")); 066 JRadioButton sortByComment = new JRadioButton(Bundle.getMessage("Comment")); 067 ButtonGroup group = new ButtonGroup(); 068 069 // major buttons 070 JButton addButton = new JButton(Bundle.getMessage("TitleCarAdd")); 071 JButton findButton = new JButton(Bundle.getMessage("Find")); 072 JButton saveButton = new JButton(Bundle.getMessage("ButtonSave")); 073 074 JTextField findCarTextBox = new JTextField(6); 075 076 public CarsTableFrame(boolean showAllCars, String locationName, String trackName) { 077 super(Bundle.getMessage("TitleCarsTable")); 078 this.showAllCars = showAllCars; 079 this.locationName = locationName; 080 this.trackName = trackName; 081 // general GUI configuration 082 getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS)); 083 084 // Set up the table in a Scroll Pane.. 085 carsTableModel = new CarsTableModel(showAllCars, locationName, trackName); 086 carsTable = new JTable(carsTableModel); 087 JScrollPane carsPane = new JScrollPane(carsTable); 088 carsPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); 089 carsTableModel.initTable(carsTable, this); 090 091 // load the number of cars and listen for changes 092 updateNumCars(); 093 carsTableModel.addTableModelListener(this); 094 095 // Set up the control panel 096 // row 1 097 JPanel cp1 = new JPanel(); 098 cp1.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("SortBy"))); 099 cp1.add(sortByNumber); 100 cp1.add(sortByRoad); 101 cp1.add(sortByType); 102 103 JPanel clp = new JPanel(); 104 clp.setBorder(BorderFactory.createTitledBorder("")); 105 clp.add(sortByLoad); 106 clp.add(sortByColor); 107 cp1.add(clp); 108 cp1.add(sortByKernel); 109 cp1.add(sortByLocation); 110 111 JPanel destp = new JPanel(); 112 destp.setBorder(BorderFactory.createTitledBorder("")); 113 destp.add(sortByDestination); 114 destp.add(sortByFinalDestination); 115 destp.add(sortByRwe); 116 destp.add(sortByRwl); 117 destp.add(sortByRoute); 118 cp1.add(destp); 119 cp1.add(sortByDivision); 120 cp1.add(sortByTrain); 121 122 JPanel movep = new JPanel(); 123 movep.setBorder(BorderFactory.createTitledBorder("")); 124 movep.add(sortByMoves); 125 movep.add(sortByBuilt); 126 movep.add(sortByOwner); 127 if (Setup.isValueEnabled()) { 128 movep.add(sortByValue); 129 } 130 if (Setup.isRfidEnabled()) { 131 movep.add(sortByRfid); 132 } 133 if (InstanceManager.getDefault(ScheduleManager.class).numEntries() > 0) { 134 movep.add(sortByWait); 135 movep.add(sortByPickup); 136 } 137 movep.add(sortByLast); 138 movep.add(sortByComment); 139 cp1.add(movep); 140 141 // row 2 142 JPanel cp2 = new JPanel(); 143 cp2.setLayout(new BoxLayout(cp2, BoxLayout.X_AXIS)); 144 145 JPanel cp2Add = new JPanel(); 146 cp2Add.setBorder(BorderFactory.createTitledBorder("")); 147 addButton.setToolTipText(Bundle.getMessage("TipAddButton")); 148 cp2Add.add(numCars); 149 cp2Add.add(textCars); 150 cp2Add.add(textSep1); 151 cp2Add.add(addButton); 152 cp2.add(cp2Add); 153 154 JPanel cp2Find = new JPanel(); 155 cp2Find.setBorder(BorderFactory.createTitledBorder("")); 156 findButton.setToolTipText(Bundle.getMessage("findCar")); 157 findCarTextBox.setToolTipText(Bundle.getMessage("findCar")); 158 cp2Find.add(findButton); 159 cp2Find.add(findCarTextBox); 160 cp2.add(cp2Find); 161 162 JPanel cp2Save = new JPanel(); 163 cp2Save.setBorder(BorderFactory.createTitledBorder("")); 164 cp2Save.add(saveButton); 165 cp2.add(cp2Save); 166 167 // place controls in scroll pane 168 JPanel controlPanel = new JPanel(); 169 controlPanel.setLayout(new BoxLayout(controlPanel, BoxLayout.Y_AXIS)); 170 controlPanel.add(cp1); 171 controlPanel.add(cp2); 172 173 // some tool tips 174 sortByFinalDestination.setToolTipText(Bundle.getMessage("FinalDestination")); 175 sortByRwe.setToolTipText(Bundle.getMessage("ReturnWhenEmpty")); 176 sortByRwl.setToolTipText(Bundle.getMessage("ReturnWhenLoaded")); 177 sortByPickup.setToolTipText(Bundle.getMessage("TipPickup")); 178 sortByLast.setToolTipText(Bundle.getMessage("TipLastMoved")); 179 180 JScrollPane controlPane = new JScrollPane(controlPanel); 181 182 getContentPane().add(carsPane); 183 getContentPane().add(controlPane); 184 185 // setup buttons 186 addButtonAction(addButton); 187 addButtonAction(findButton); 188 addButtonAction(saveButton); 189 190 sortByNumber.setSelected(true); 191 addRadioButtonAction(sortByNumber); 192 addRadioButtonAction(sortByRoad); 193 addRadioButtonAction(sortByType); 194 addRadioButtonAction(sortByColor); 195 addRadioButtonAction(sortByLoad); 196 addRadioButtonAction(sortByKernel); 197 addRadioButtonAction(sortByLocation); 198 addRadioButtonAction(sortByDestination); 199 addRadioButtonAction(sortByFinalDestination); 200 addRadioButtonAction(sortByRwe); 201 addRadioButtonAction(sortByRwl); 202 addRadioButtonAction(sortByRoute); 203 addRadioButtonAction(sortByDivision); 204 addRadioButtonAction(sortByTrain); 205 addRadioButtonAction(sortByMoves); 206 addRadioButtonAction(sortByBuilt); 207 addRadioButtonAction(sortByOwner); 208 addRadioButtonAction(sortByValue); 209 addRadioButtonAction(sortByRfid); 210 addRadioButtonAction(sortByWait); 211 addRadioButtonAction(sortByPickup); 212 addRadioButtonAction(sortByLast); 213 addRadioButtonAction(sortByComment); 214 215 group.add(sortByNumber); 216 group.add(sortByRoad); 217 group.add(sortByType); 218 group.add(sortByColor); 219 group.add(sortByLoad); 220 group.add(sortByKernel); 221 group.add(sortByLocation); 222 group.add(sortByDestination); 223 group.add(sortByFinalDestination); 224 group.add(sortByRwe); 225 group.add(sortByRwl); 226 group.add(sortByRoute); 227 group.add(sortByDivision); 228 group.add(sortByTrain); 229 group.add(sortByMoves); 230 group.add(sortByBuilt); 231 group.add(sortByOwner); 232 group.add(sortByValue); 233 group.add(sortByRfid); 234 group.add(sortByWait); 235 group.add(sortByPickup); 236 group.add(sortByLast); 237 group.add(sortByComment); 238 239 // sort by location 240 if (!showAllCars) { 241 sortByLocation.doClick(); 242 if (locationName != null) { 243 String title = Bundle.getMessage("TitleCarsTable") + " " + locationName; 244 if (trackName != null) { 245 title = title + " " + trackName; 246 } 247 setTitle(title); 248 } 249 } 250 251 // build menu 252 JMenuBar menuBar = new JMenuBar(); 253 JMenu toolMenu = new JMenu(Bundle.getMessage("MenuTools")); 254 toolMenu.add(new CarRosterMenu(Bundle.getMessage("TitleCarRoster"), CarRosterMenu.MAINMENU, this)); 255 toolMenu.addSeparator(); 256 toolMenu.add(new ShowCheckboxesCarsTableAction(carsTableModel)); 257 toolMenu.add(new ResetCheckboxesCarsTableAction(carsTableModel)); 258 toolMenu.addSeparator(); 259 toolMenu.add(new ModifyLocationsAction()); 260 toolMenu.add(new TrainsByCarTypeAction()); 261 toolMenu.addSeparator(); 262 toolMenu.add(new PrintCarLoadsAction(false)); 263 toolMenu.add(new PrintCarLoadsAction(true)); 264 toolMenu.addSeparator(); 265 toolMenu.add(new CarsSetFrameAction(carsTable)); 266 menuBar.add(toolMenu); 267 menuBar.add(new jmri.jmrit.operations.OperationsMenu()); 268 setJMenuBar(menuBar); 269 addHelpMenu("package.jmri.jmrit.operations.Operations_Cars", true); // NOI18N 270 271 initMinimumSize(); 272 273 addHorizontalScrollBarKludgeFix(controlPane, controlPanel); 274 275 // create ShutDownTasks 276 createShutDownTask(); 277 } 278 279 @Override 280 public void radioButtonActionPerformed(java.awt.event.ActionEvent ae) { 281 log.debug("radio button activated"); 282 // clear any sorts by column 283 clearTableSort(carsTable); 284 if (ae.getSource() == sortByNumber) { 285 carsTableModel.setSort(carsTableModel.SORTBY_NUMBER); 286 } 287 if (ae.getSource() == sortByRoad) { 288 carsTableModel.setSort(carsTableModel.SORTBY_ROAD); 289 } 290 if (ae.getSource() == sortByType) { 291 carsTableModel.setSort(carsTableModel.SORTBY_TYPE); 292 } 293 if (ae.getSource() == sortByColor) { 294 carsTableModel.setSort(carsTableModel.SORTBY_COLOR); 295 } 296 if (ae.getSource() == sortByLoad) { 297 carsTableModel.setSort(carsTableModel.SORTBY_LOAD); 298 } 299 if (ae.getSource() == sortByKernel) { 300 carsTableModel.setSort(carsTableModel.SORTBY_KERNEL); 301 } 302 if (ae.getSource() == sortByLocation) { 303 carsTableModel.setSort(carsTableModel.SORTBY_LOCATION); 304 } 305 if (ae.getSource() == sortByDestination) { 306 carsTableModel.setSort(carsTableModel.SORTBY_DESTINATION); 307 } 308 if (ae.getSource() == sortByFinalDestination) { 309 carsTableModel.setSort(carsTableModel.SORTBY_FINALDESTINATION); 310 } 311 if (ae.getSource() == sortByRwe) { 312 carsTableModel.setSort(carsTableModel.SORTBY_RWE); 313 } 314 if (ae.getSource() == sortByRwl) { 315 carsTableModel.setSort(carsTableModel.SORTBY_RWL); 316 } 317 if (ae.getSource() == sortByRoute) { 318 carsTableModel.setSort(carsTableModel.SORTBY_ROUTE); 319 } 320 if (ae.getSource() == sortByDivision) { 321 carsTableModel.setSort(carsTableModel.SORTBY_DIVISION); 322 } 323 if (ae.getSource() == sortByTrain) { 324 carsTableModel.setSort(carsTableModel.SORTBY_TRAIN); 325 } 326 if (ae.getSource() == sortByMoves) { 327 carsTableModel.setSort(carsTableModel.SORTBY_MOVES); 328 } 329 if (ae.getSource() == sortByBuilt) { 330 carsTableModel.setSort(carsTableModel.SORTBY_BUILT); 331 } 332 if (ae.getSource() == sortByOwner) { 333 carsTableModel.setSort(carsTableModel.SORTBY_OWNER); 334 } 335 if (ae.getSource() == sortByValue) { 336 carsTableModel.setSort(carsTableModel.SORTBY_VALUE); 337 } 338 if (ae.getSource() == sortByRfid) { 339 carsTableModel.setSort(carsTableModel.SORTBY_RFID); 340 } 341 if (ae.getSource() == sortByWait) { 342 carsTableModel.setSort(carsTableModel.SORTBY_WAIT); 343 } 344 if (ae.getSource() == sortByPickup) { 345 carsTableModel.setSort(carsTableModel.SORTBY_PICKUP); 346 } 347 if (ae.getSource() == sortByLast) { 348 carsTableModel.setSort(carsTableModel.SORTBY_LAST); 349 } 350 if (ae.getSource() == sortByComment) { 351 carsTableModel.setSort(carsTableModel.SORTBY_COMMENT); 352 } 353 } 354 355 public List<Car> getSortByList() { 356 return carsTableModel.carList; 357 } 358 359 CarEditFrame f = null; 360 361 // add, find or save button 362 @Override 363 public void buttonActionPerformed(java.awt.event.ActionEvent ae) { 364 // log.debug("car button activated"); 365 if (ae.getSource() == findButton) { 366 int rowindex = carsTableModel.findCarByRoadNumber(findCarTextBox.getText()); 367 if (rowindex < 0) { 368 JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("carWithRoadNumNotFound", 369 findCarTextBox.getText()), Bundle.getMessage("carCouldNotFind"), 370 JmriJOptionPane.INFORMATION_MESSAGE); 371 return; 372 } 373 // clear any sorts by column 374 clearTableSort(carsTable); 375 carsTable.changeSelection(rowindex, 0, false, false); 376 return; 377 } 378 if (ae.getSource() == addButton) { 379 if (f != null) { 380 f.dispose(); 381 } 382 f = new CarEditFrame(); 383 f.initComponents(); // default is add car 384 } 385 if (ae.getSource() == saveButton) { 386 if (carsTable.isEditing()) { 387 log.debug("cars table edit true"); 388 carsTable.getCellEditor().stopCellEditing(); 389 } 390 OperationsXml.save(); 391 if (Setup.isCloseWindowOnSaveEnabled()) { 392 dispose(); 393 } 394 } 395 } 396 397 protected int[] getCurrentTableColumnWidths() { 398 TableColumnModel tcm = carsTable.getColumnModel(); 399 int[] widths = new int[tcm.getColumnCount()]; 400 for (int i = 0; i < tcm.getColumnCount(); i++) { 401 widths[i] = tcm.getColumn(i).getWidth(); 402 } 403 return widths; 404 } 405 406 @Override 407 public void dispose() { 408 carsTableModel.removeTableModelListener(this); 409 carsTableModel.dispose(); 410 if (f != null) { 411 f.dispose(); 412 } 413 InstanceManager.getOptionalDefault(JTablePersistenceManager.class).ifPresent(tpm -> { 414 tpm.stopPersisting(carsTable); 415 }); 416 super.dispose(); 417 } 418 419 @Override 420 public void tableChanged(TableModelEvent e) { 421 if (Control.SHOW_PROPERTY) { 422 log.debug("Table changed"); 423 } 424 updateNumCars(); 425 } 426 427 private void updateNumCars() { 428 String totalNumber = Integer.toString(InstanceManager.getDefault(CarManager.class).getNumEntries()); 429 if (showAllCars) { 430 numCars.setText(totalNumber); 431 return; 432 } 433 String showNumber = Integer.toString(getSortByList().size()); 434 numCars.setText(showNumber + "/" + totalNumber); 435 } 436 437 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(CarsTableFrame.class); 438 439}