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