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.add(new ShowCheckboxesCarsTableAction(carsTableModel)); 256 toolMenu.add(new ResetCheckboxesCarsTableAction(carsTableModel)); 257 toolMenu.add(new ModifyLocationsAction()); 258 toolMenu.add(new TrainsByCarTypeAction()); 259 toolMenu.add(new PrintCarLoadsAction(false)); 260 toolMenu.add(new PrintCarLoadsAction(true)); 261 toolMenu.add(new CarsSetFrameAction(carsTable)); 262 menuBar.add(toolMenu); 263 menuBar.add(new jmri.jmrit.operations.OperationsMenu()); 264 setJMenuBar(menuBar); 265 addHelpMenu("package.jmri.jmrit.operations.Operations_Cars", true); // NOI18N 266 267 initMinimumSize(); 268 269 addHorizontalScrollBarKludgeFix(controlPane, controlPanel); 270 271 // create ShutDownTasks 272 createShutDownTask(); 273 } 274 275 @Override 276 public void radioButtonActionPerformed(java.awt.event.ActionEvent ae) { 277 log.debug("radio button activated"); 278 // clear any sorts by column 279 clearTableSort(carsTable); 280 if (ae.getSource() == sortByNumber) { 281 carsTableModel.setSort(carsTableModel.SORTBY_NUMBER); 282 } 283 if (ae.getSource() == sortByRoad) { 284 carsTableModel.setSort(carsTableModel.SORTBY_ROAD); 285 } 286 if (ae.getSource() == sortByType) { 287 carsTableModel.setSort(carsTableModel.SORTBY_TYPE); 288 } 289 if (ae.getSource() == sortByColor) { 290 carsTableModel.setSort(carsTableModel.SORTBY_COLOR); 291 } 292 if (ae.getSource() == sortByLoad) { 293 carsTableModel.setSort(carsTableModel.SORTBY_LOAD); 294 } 295 if (ae.getSource() == sortByKernel) { 296 carsTableModel.setSort(carsTableModel.SORTBY_KERNEL); 297 } 298 if (ae.getSource() == sortByLocation) { 299 carsTableModel.setSort(carsTableModel.SORTBY_LOCATION); 300 } 301 if (ae.getSource() == sortByDestination) { 302 carsTableModel.setSort(carsTableModel.SORTBY_DESTINATION); 303 } 304 if (ae.getSource() == sortByFinalDestination) { 305 carsTableModel.setSort(carsTableModel.SORTBY_FINALDESTINATION); 306 } 307 if (ae.getSource() == sortByRwe) { 308 carsTableModel.setSort(carsTableModel.SORTBY_RWE); 309 } 310 if (ae.getSource() == sortByRwl) { 311 carsTableModel.setSort(carsTableModel.SORTBY_RWL); 312 } 313 if (ae.getSource() == sortByRoute) { 314 carsTableModel.setSort(carsTableModel.SORTBY_ROUTE); 315 } 316 if (ae.getSource() == sortByDivision) { 317 carsTableModel.setSort(carsTableModel.SORTBY_DIVISION); 318 } 319 if (ae.getSource() == sortByTrain) { 320 carsTableModel.setSort(carsTableModel.SORTBY_TRAIN); 321 } 322 if (ae.getSource() == sortByMoves) { 323 carsTableModel.setSort(carsTableModel.SORTBY_MOVES); 324 } 325 if (ae.getSource() == sortByBuilt) { 326 carsTableModel.setSort(carsTableModel.SORTBY_BUILT); 327 } 328 if (ae.getSource() == sortByOwner) { 329 carsTableModel.setSort(carsTableModel.SORTBY_OWNER); 330 } 331 if (ae.getSource() == sortByValue) { 332 carsTableModel.setSort(carsTableModel.SORTBY_VALUE); 333 } 334 if (ae.getSource() == sortByRfid) { 335 carsTableModel.setSort(carsTableModel.SORTBY_RFID); 336 } 337 if (ae.getSource() == sortByWait) { 338 carsTableModel.setSort(carsTableModel.SORTBY_WAIT); 339 } 340 if (ae.getSource() == sortByPickup) { 341 carsTableModel.setSort(carsTableModel.SORTBY_PICKUP); 342 } 343 if (ae.getSource() == sortByLast) { 344 carsTableModel.setSort(carsTableModel.SORTBY_LAST); 345 } 346 if (ae.getSource() == sortByComment) { 347 carsTableModel.setSort(carsTableModel.SORTBY_COMMENT); 348 } 349 } 350 351 public List<Car> getSortByList() { 352 return carsTableModel.carList; 353 } 354 355 CarEditFrame f = null; 356 357 // add, find or save button 358 @Override 359 public void buttonActionPerformed(java.awt.event.ActionEvent ae) { 360 // log.debug("car button activated"); 361 if (ae.getSource() == findButton) { 362 int rowindex = carsTableModel.findCarByRoadNumber(findCarTextBox.getText()); 363 if (rowindex < 0) { 364 JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("carWithRoadNumNotFound", 365 findCarTextBox.getText()), Bundle.getMessage("carCouldNotFind"), 366 JmriJOptionPane.INFORMATION_MESSAGE); 367 return; 368 } 369 // clear any sorts by column 370 clearTableSort(carsTable); 371 carsTable.changeSelection(rowindex, 0, false, false); 372 return; 373 } 374 if (ae.getSource() == addButton) { 375 if (f != null) { 376 f.dispose(); 377 } 378 f = new CarEditFrame(); 379 f.initComponents(); // default is add car 380 } 381 if (ae.getSource() == saveButton) { 382 if (carsTable.isEditing()) { 383 log.debug("cars table edit true"); 384 carsTable.getCellEditor().stopCellEditing(); 385 } 386 OperationsXml.save(); 387 if (Setup.isCloseWindowOnSaveEnabled()) { 388 dispose(); 389 } 390 } 391 } 392 393 protected int[] getCurrentTableColumnWidths() { 394 TableColumnModel tcm = carsTable.getColumnModel(); 395 int[] widths = new int[tcm.getColumnCount()]; 396 for (int i = 0; i < tcm.getColumnCount(); i++) { 397 widths[i] = tcm.getColumn(i).getWidth(); 398 } 399 return widths; 400 } 401 402 @Override 403 public void dispose() { 404 carsTableModel.removeTableModelListener(this); 405 carsTableModel.dispose(); 406 if (f != null) { 407 f.dispose(); 408 } 409 InstanceManager.getOptionalDefault(JTablePersistenceManager.class).ifPresent(tpm -> { 410 tpm.stopPersisting(carsTable); 411 }); 412 super.dispose(); 413 } 414 415 @Override 416 public void tableChanged(TableModelEvent e) { 417 if (Control.SHOW_PROPERTY) { 418 log.debug("Table changed"); 419 } 420 updateNumCars(); 421 } 422 423 private void updateNumCars() { 424 String totalNumber = Integer.toString(InstanceManager.getDefault(CarManager.class).getNumEntries()); 425 if (showAllCars) { 426 numCars.setText(totalNumber); 427 return; 428 } 429 String showNumber = Integer.toString(getSortByList().size()); 430 numCars.setText(showNumber + "/" + totalNumber); 431 } 432 433 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(CarsTableFrame.class); 434 435}