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