/** * Block cars by track (optional), then pick up and set out for each location in a train's route. * This shows each car with a check box or with a set button. The set button is displayed when the * checkbox isn't selected and the display is in "set" mode. If the car is a utility. Show the * number of cars that have the same attributes, and not the car's road and number. Each car is * displayed only once in one of three panes. The three panes are pick up, set out, or local move. * To keep track of each car and which pane to use, they are placed in the list "rollingStock" * with the prefix "p", "s" or "m" and the car's unique id. */ protected void blockCars(RouteLocation rl, boolean isManifest) { if (Setup.isPrintHeadersEnabled()) { JLabel header = new JLabel( Tab + trainCommon.getPickupCarHeader(isManifest, !TrainCommon.IS_TWO_COLUMN_TRACK)); setLabelFont(header); pPickups.add(header); header = new JLabel( Tab + trainCommon.getDropCarHeader(isManifest, !TrainCommon.IS_TWO_COLUMN_TRACK)); setLabelFont(header); pSetouts.add(header); header = new JLabel(Tab + trainCommon.getLocalMoveHeader(isManifest)); setLabelFont(header); pMoves.add(header); } List<Track> tracks = rl.getLocation().getTrackByNameList(null); List<RouteLocation> routeList = _train.getRoute().getLocationsBySequenceList(); List<Car> carList = carManager.getByTrainDestinationList(_train); for (Track track : tracks) { for (RouteLocation rld : routeList) { for (Car car : carList) { // determine if car is a pick up from the right track // caboose or FRED is placed at end of the train // passenger trains are already blocked in the car list if (car.getTrack() != null && car.getRouteLocation() == rl && car.getRouteDestination() != rl && (!Setup.isSortByTrackEnabled() || car.getTrackName().equals(track.getName())) && ((car.getRouteDestination() == rld && !car.isCaboose() && !car.hasFred()) || (rld == routeList.get(routeList.size() - 1) && (car.isCaboose() || car.hasFred())) || car.isPassenger())) { // yes we have a pick up pWorkPanes.setVisible(true); pickupPane.setVisible(true); if (!rollingStock.contains(car)) { rollingStock.add(car); car.addPropertyChangeListener(this); } // did we already process this car? if (checkBoxes.containsKey("p" + car.getId())) { if (isSetMode && !checkBoxes.get("p" + car.getId()).isSelected()) { // change to set button so user can remove car from train pPickups.add(addSet(car)); } else { pPickups.add(checkBoxes.get("p" + car.getId())); } // figure out the checkbox text, either single car or utility } else { String text; if (car.isUtility()) { text = trainCommon.pickupUtilityCars( carList, car, isManifest, !TrainCommon.IS_TWO_COLUMN_TRACK); if (text == null) { continue; // this car type has already been processed } } else { text = trainCommon.pickupCar(car, isManifest, !TrainCommon.IS_TWO_COLUMN_TRACK); } JCheckBox checkBox = new JCheckBox(text); setCheckBoxFont(checkBox); addCheckBoxAction(checkBox); pPickups.add(checkBox); checkBoxes.put("p" + car.getId(), checkBox); } } } } // set outs and local moves for (Car car : carList) { if (car.getRouteDestination() != rl || car.getDestinationTrack() == null) { continue; } // car in train if track null, second check is for yard master window if (car.getTrack() == null || car.getTrack() != null && (car.getRouteLocation() != rl)) { if (Setup.isSortByTrackEnabled() && !car.getDestinationTrack().getName().equals(track.getName())) { continue; } // we have set outs pWorkPanes.setVisible(true); setoutPane.setVisible(true); if (!rollingStock.contains(car)) { rollingStock.add(car); car.addPropertyChangeListener(this); } if (checkBoxes.containsKey("s" + car.getId())) { if (isSetMode && !checkBoxes.get("s" + car.getId()).isSelected()) { // change to set button so user can remove car from train pSetouts.add(addSet(car)); } else { pSetouts.add(checkBoxes.get("s" + car.getId())); } } else { String text; if (car.isUtility()) { text = trainCommon.setoutUtilityCars(carList, car, !TrainCommon.LOCAL, isManifest); if (text == null) { continue; // this car type has already been processed } } else { text = trainCommon.dropCar(car, isManifest, !TrainCommon.IS_TWO_COLUMN_TRACK); } JCheckBox checkBox = new JCheckBox(text); setCheckBoxFont(checkBox); addCheckBoxAction(checkBox); pSetouts.add(checkBox); checkBoxes.put("s" + car.getId(), checkBox); } // local move? } else if (car.getTrack() != null && car.getRouteLocation() == rl && (!Setup.isSortByTrackEnabled() || car.getTrack().getName().equals(track.getName()))) { movePane.setVisible(true); if (!rollingStock.contains(car)) { rollingStock.add(car); car.addPropertyChangeListener(this); } if (checkBoxes.containsKey("m" + car.getId())) { if (isSetMode && !checkBoxes.get("m" + car.getId()).isSelected()) { // change to set button so user can remove car from train pMoves.add(addSet(car)); } else { pMoves.add(checkBoxes.get("m" + car.getId())); } } else { String text; if (car.isUtility()) { text = trainCommon.setoutUtilityCars(carList, car, TrainCommon.LOCAL, isManifest); if (text == null) { continue; // this car type has already been processed } } else { text = trainCommon.localMoveCar(car, isManifest); } JCheckBox checkBox = new JCheckBox(text); setCheckBoxFont(checkBox); addCheckBoxAction(checkBox); pMoves.add(checkBox); checkBoxes.put("m" + car.getId(), checkBox); } } } // if not sorting by track, we're done if (!Setup.isSortByTrackEnabled()) { break; } } // pad the panels in case the horizontal scroll bar appears pPickups.add(new JLabel(Space)); pSetouts.add(new JLabel(Space)); pMoves.add(new JLabel(Space)); }
@Override @edu.umd.cs.findbugs.annotations.SuppressFBWarnings( value = "ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD", justification = "GUI ease of use") protected void buttonActionPerformed(java.awt.event.ActionEvent ae) { if (ae.getSource() == copyButton) { log.debug("copy location button activated"); if (!checkName()) { return; } if (locationBox.getSelectedItem() == null) { JOptionPane.showMessageDialog( this, Bundle.getMessage("SelectLocationToCopy"), MessageFormat.format( Bundle.getMessage("CanNotLocation"), new Object[] {Bundle.getMessage("Copy")}), JOptionPane.ERROR_MESSAGE); return; } Location location = (Location) locationBox.getSelectedItem(); // check to see if there are cars scheduled for pickup or set out if (moveRollingStockCheckBox.isSelected()) { for (Track track : location.getTrackList()) { if (track.getPickupRS() > 0) { JOptionPane.showMessageDialog( this, MessageFormat.format( Bundle.getMessage("FoundRollingStockPickUp"), new Object[] {track.getPickupRS()}), MessageFormat.format( Bundle.getMessage("TrainsServicingTrack"), new Object[] {track.getName()}), JOptionPane.WARNING_MESSAGE); return; // can't move rolling stock, some are scheduled for a pick up } if (track.getDropRS() > 0) { JOptionPane.showMessageDialog( this, MessageFormat.format( Bundle.getMessage("FoundRollingStockDrop"), new Object[] {track.getDropRS()}), MessageFormat.format( Bundle.getMessage("TrainsServicingTrack"), new Object[] {track.getName()}), JOptionPane.WARNING_MESSAGE); return; // can't move rolling stock, some are scheduled for drops } } } // now copy all of the tracks Location newLocation = locationManager.newLocation(loctionNameTextField.getText()); location.copyLocation(newLocation); // does the user want the cars to also move to the new tracks? if (moveRollingStockCheckBox.isSelected()) { for (Track track : location.getTrackList()) { moveRollingStock(track, newLocation.getTrackByName(track.getName(), null)); if (deleteTrackCheckBox.isSelected()) { location.deleteTrack(track); } } } } if (ae.getSource() == saveButton) { log.debug("save track button activated"); // save checkbox states moveRollingStock = moveRollingStockCheckBox.isSelected(); deleteTrack = deleteTrackCheckBox.isSelected(); // save location file OperationsXml.save(); } }
public String getFinalDestinationTrackName() { if (_finalDestTrack != null) { return _finalDestTrack.getName(); } return NONE; }
/** * Builds a switch list for a location showing the work by train arrival time. If not running in * real time, new train work is appended to the end of the file. User has the ability to modify * the text of the messages which can cause an IllegalArgumentException. Some messages have more * arguments than the default message allowing the user to customize the message to their liking. * * <p>There also an option to list all of the car work by track name. This option is only * available in real time and is shown after the switch list by train. * * @param location The Location needing a switch list */ @edu.umd.cs.findbugs.annotations.SuppressFBWarnings( value = "BC_UNCONFIRMED_CAST_OF_RETURN_VALUE", justification = "CarManager only provides Car Objects") // NOI18N public void buildSwitchList(Location location) { // Append switch list data if not operating in real time boolean newTrainsOnly = !Setup.isSwitchListRealTime(); boolean append = false; // add text to end of file when true boolean checkFormFeed = true; // used to determine if FF needed between trains if (newTrainsOnly) { if (!location.getStatus().equals(Location.MODIFIED) && !Setup.isSwitchListAllTrainsEnabled()) { return; // nothing to add } append = location.getSwitchListState() == Location.SW_APPEND; if (location.getSwitchListState() != Location.SW_APPEND) { location.setSwitchListState(Location.SW_APPEND); } location.setStatus(Location.UPDATED); } log.debug("Append: {} for location ({})", append, location.getName()); // create switch list file File file = TrainManagerXml.instance().createSwitchListFile(location.getName()); PrintWriter fileOut = null; try { fileOut = new PrintWriter( new BufferedWriter( new OutputStreamWriter(new FileOutputStream(file, append), "UTF-8")), true); // NOI18N } catch (IOException e) { log.error("Can not open switchlist file: {}", file.getName()); return; } try { // build header if (!append) { newLine(fileOut, Setup.getRailroadName()); newLine(fileOut); newLine( fileOut, MessageFormat.format( messageFormatText = TrainSwitchListText.getStringSwitchListFor(), new Object[] {splitString(location.getName())})); if (!location.getSwitchListComment().equals(Location.NONE)) { newLine(fileOut, location.getSwitchListComment()); } } String valid = MessageFormat.format( messageFormatText = TrainManifestText.getStringValid(), new Object[] {getDate(true)}); if (Setup.isPrintTimetableNameEnabled()) { TrainSchedule sch = TrainScheduleManager.instance() .getScheduleById(trainManager.getTrainScheduleActiveId()); if (sch != null) { valid = valid + " (" + sch.getName() + ")"; } } // get a list of trains sorted by arrival time List<Train> trains = trainManager.getTrainsArrivingThisLocationList(location); for (Train train : trains) { if (!train.isBuilt()) { continue; // train wasn't built so skip } if (newTrainsOnly && train.getSwitchListStatus().equals(Train.PRINTED)) { continue; // already printed this train } Route route = train.getRoute(); if (route == null) { continue; // no route for this train } // determine if train works this location boolean works = isThereWorkAtLocation(train, location); if (!works && !Setup.isSwitchListAllTrainsEnabled()) { log.debug("No work for train ({}) at location ({})", train.getName(), location.getName()); continue; } // we're now going to add to the switch list if (checkFormFeed) { if (append && !Setup.getSwitchListPageFormat().equals(Setup.PAGE_NORMAL)) { fileOut.write(FORM_FEED); } if (Setup.isPrintValidEnabled()) { newLine(fileOut, valid); } } else if (!Setup.getSwitchListPageFormat().equals(Setup.PAGE_NORMAL)) { fileOut.write(FORM_FEED); } checkFormFeed = false; // done with FF for this train // some cars booleans and the number of times this location get's serviced pickupCars = false; // when true there was a car pick up dropCars = false; // when true there was a car set out int stops = 1; boolean trainDone = false; // get engine and car lists List<Engine> engineList = engineManager.getByTrainBlockingList(train); List<Car> carList = carManager.getByTrainDestinationList(train); List<RouteLocation> routeList = route.getLocationsBySequenceList(); RouteLocation rlPrevious = null; // does the train stop once or more at this location? for (RouteLocation rl : routeList) { if (!splitString(rl.getName()).equals(splitString(location.getName()))) { rlPrevious = rl; continue; } String expectedArrivalTime = train.getExpectedArrivalTime(rl); if (expectedArrivalTime.equals(Train.ALREADY_SERVICED)) { trainDone = true; } // first time at this location? if (stops == 1) { newLine(fileOut); newLine( fileOut, MessageFormat.format( messageFormatText = TrainSwitchListText.getStringScheduledWork(), new Object[] {train.getName(), train.getDescription()})); if (train.isTrainEnRoute()) { if (!trainDone) { newLine( fileOut, MessageFormat.format( messageFormatText = TrainSwitchListText.getStringDepartedExpected(), new Object[] { splitString(train.getTrainDepartsName()), expectedArrivalTime, rl.getTrainDirectionString() })); } } else if (!train.isLocalSwitcher()) { if (rl == train.getRoute().getDepartsRouteLocation()) { newLine( fileOut, MessageFormat.format( messageFormatText = TrainSwitchListText.getStringDepartsAt(), new Object[] { splitString(train.getTrainDepartsName()), rl.getTrainDirectionString(), train.getFormatedDepartureTime() })); } else { newLine( fileOut, MessageFormat.format( messageFormatText = TrainSwitchListText.getStringDepartsAtExpectedArrival(), new Object[] { splitString(train.getTrainDepartsName()), train.getFormatedDepartureTime(), expectedArrivalTime, rl.getTrainDirectionString() })); } } } else { // multiple visits to this location // Print visit number only if previous location wasn't the same if (rlPrevious == null || !splitString(rl.getName()).equals(splitString(rlPrevious.getName()))) { if (Setup.getSwitchListPageFormat().equals(Setup.PAGE_PER_VISIT)) { fileOut.write(FORM_FEED); } newLine(fileOut); if (train.isTrainEnRoute()) { if (expectedArrivalTime.equals(Train.ALREADY_SERVICED)) { newLine( fileOut, MessageFormat.format( messageFormatText = TrainSwitchListText.getStringVisitNumberDone(), new Object[] {stops, train.getName(), train.getDescription()})); } else if (rl != train.getRoute().getTerminatesRouteLocation()) { newLine( fileOut, MessageFormat.format( messageFormatText = TrainSwitchListText.getStringVisitNumberDeparted(), new Object[] { stops, train.getName(), expectedArrivalTime, rl.getTrainDirectionString(), train.getDescription() })); } else { // message: Visit number {0} for train ({1}) expect to arrive in {2}, terminates // {3} newLine( fileOut, MessageFormat.format( messageFormatText = TrainSwitchListText.getStringVisitNumberTerminatesDeparted(), new Object[] { stops, train.getName(), expectedArrivalTime, splitString(rl.getName()), train.getDescription() })); } } else { // train hasn't departed if (rl != train.getRoute().getTerminatesRouteLocation()) { newLine( fileOut, MessageFormat.format( messageFormatText = TrainSwitchListText.getStringVisitNumber(), new Object[] { stops, train.getName(), expectedArrivalTime, rl.getTrainDirectionString(), train.getDescription() })); } else { newLine( fileOut, MessageFormat.format( messageFormatText = TrainSwitchListText.getStringVisitNumberTerminates(), new Object[] { stops, train.getName(), expectedArrivalTime, splitString(rl.getName()), train.getDescription() })); } } } else { stops--; // don't bump stop count, same location // Does the train reverse direction? if (rl.getTrainDirection() != rlPrevious.getTrainDirection() && !TrainSwitchListText.getStringTrainDirectionChange().equals("")) { newLine( fileOut, MessageFormat.format( messageFormatText = TrainSwitchListText.getStringTrainDirectionChange(), new Object[] { train.getName(), rl.getTrainDirectionString(), train.getDescription(), train.getTrainTerminatesName() })); } } } rlPrevious = rl; // save current location in case there's back to back location with the same name // add route comment if (Setup.isSwitchListRouteLocationCommentEnabled() && !rl.getComment().trim().equals("")) { newLine(fileOut, rl.getComment()); } // now print out the work for this location if (Setup.getManifestFormat().equals(Setup.STANDARD_FORMAT)) { pickupEngines(fileOut, engineList, rl, !IS_MANIFEST); // if switcher show loco drop at end of list if (train.isLocalSwitcher()) { blockCarsByTrack( fileOut, train, carList, routeList, rl, IS_PRINT_HEADER, !IS_MANIFEST); dropEngines(fileOut, engineList, rl, !IS_MANIFEST); } else { dropEngines(fileOut, engineList, rl, !IS_MANIFEST); blockCarsByTrack( fileOut, train, carList, routeList, rl, IS_PRINT_HEADER, !IS_MANIFEST); } } else if (Setup.getManifestFormat().equals(Setup.TWO_COLUMN_FORMAT)) { blockLocosTwoColumn(fileOut, engineList, rl, !IS_MANIFEST); blockCarsByTrackTwoColumn( fileOut, train, carList, routeList, rl, IS_PRINT_HEADER, !IS_MANIFEST); } else { blockLocosTwoColumn(fileOut, engineList, rl, !IS_MANIFEST); blockCarsByTrackNameTwoColumn( fileOut, train, carList, routeList, rl, IS_PRINT_HEADER, !IS_MANIFEST); } if (Setup.isPrintHeadersEnabled() || !Setup.getManifestFormat().equals(Setup.STANDARD_FORMAT)) { printHorizontalLine(fileOut, !IS_MANIFEST); } stops++; // done with work, now print summary for this location if we're done if (rl != train.getRoute().getTerminatesRouteLocation()) { RouteLocation nextRl = train.getRoute().getNextRouteLocation(rl); if (splitString(rl.getName()).equals(splitString(nextRl.getName()))) { continue; // the current location name is the "same" as the next } // print departure text if not a switcher if (!train.isLocalSwitcher()) { String trainDeparts = ""; if (Setup.isPrintLoadsAndEmptiesEnabled()) { int emptyCars = train.getNumberEmptyCarsInTrain(rl); // Message format: Train departs Boston Westbound with 4 loads, 8 empties, 450 feet, // 3000 tons trainDeparts = MessageFormat.format( TrainSwitchListText.getStringTrainDepartsLoads(), new Object[] { TrainCommon.splitString(rl.getName()), rl.getTrainDirectionString(), train.getNumberCarsInTrain(rl) - emptyCars, emptyCars, train.getTrainLength(rl), Setup.getLengthUnit().toLowerCase(), train.getTrainWeight(rl), train.getTrainTerminatesName(), train.getName() }); } else { // Message format: Train departs Boston Westbound with 12 cars, 450 feet, 3000 tons trainDeparts = MessageFormat.format( TrainSwitchListText.getStringTrainDepartsCars(), new Object[] { TrainCommon.splitString(rl.getName()), rl.getTrainDirectionString(), train.getNumberCarsInTrain(rl), train.getTrainLength(rl), Setup.getLengthUnit().toLowerCase(), train.getTrainWeight(rl), train.getTrainTerminatesName(), train.getName() }); } newLine(fileOut, trainDeparts); } } } if (trainDone && !pickupCars && !dropCars) { // Default message: Train ({0}) has serviced this location newLine( fileOut, MessageFormat.format( messageFormatText = TrainSwitchListText.getStringTrainDone(), new Object[] { train.getName(), train.getDescription(), splitString(location.getName()) })); } else { if (stops > 1 && !pickupCars) { // Default message: No car pick ups for train ({0}) at this location newLine( fileOut, MessageFormat.format( messageFormatText = TrainSwitchListText.getStringNoCarPickUps(), new Object[] { train.getName(), train.getDescription(), splitString(location.getName()) })); } if (stops > 1 && !dropCars) { // Default message: No car set outs for train ({0}) at this location newLine( fileOut, MessageFormat.format( messageFormatText = TrainSwitchListText.getStringNoCarDrops(), new Object[] { train.getName(), train.getDescription(), splitString(location.getName()) })); } } } // now report car movement by tracks at location if (Setup.isTrackSummaryEnabled() && Setup.isSwitchListRealTime()) { clearUtilityCarTypes(); // list utility cars by quantity if (Setup.getSwitchListPageFormat().equals(Setup.PAGE_NORMAL)) { newLine(fileOut); newLine(fileOut); } else { fileOut.write(FORM_FEED); } newLine( fileOut, MessageFormat.format( messageFormatText = TrainSwitchListText.getStringSwitchListByTrack(), new Object[] {splitString(location.getName())})); // we only need the cars delivered to or at this location List<RollingStock> rsList = carManager.getByTrainList(); List<Car> carList = new ArrayList<Car>(); for (RollingStock rs : rsList) { if ((rs.getLocation() != null && splitString(rs.getLocation().getName()) .equals(splitString(location.getName()))) || (rs.getDestination() != null && splitString(rs.getDestination().getName()) .equals(splitString(location.getName())))) carList.add((Car) rs); } List<String> trackNames = new ArrayList< String>(); // locations and tracks can have "similar" names, only list track names // once for (Location loc : locationManager.getLocationsByNameList()) { if (!splitString(loc.getName()).equals(splitString(location.getName()))) continue; for (Track track : loc.getTrackByNameList(null)) { String trackName = splitString(track.getName()); if (trackNames.contains(trackName)) continue; trackNames.add(trackName); String trainName = ""; // for printing train message once newLine(fileOut); newLine(fileOut, trackName); // print out just the track name // now show the cars pickup and holds for this track for (Car car : carList) { if (!splitString(car.getTrackName()).equals(trackName)) { continue; } // is the car scheduled for pickup? if (car.getRouteLocation() != null) { if (splitString(car.getRouteLocation().getLocation().getName()) .equals(splitString(location.getName()))) { // cars are sorted by train name, print train message once if (!trainName.equals(car.getTrainName())) { trainName = car.getTrainName(); newLine( fileOut, MessageFormat.format( messageFormatText = TrainSwitchListText.getStringScheduledWork(), new Object[] {car.getTrainName(), car.getTrain().getDescription()})); printPickupCarHeader(fileOut, !IS_MANIFEST, !IS_TWO_COLUMN_TRACK); } if (car.isUtility()) { pickupUtilityCars(fileOut, carList, car, !IS_MANIFEST); } else { pickUpCar(fileOut, car, !IS_MANIFEST); } } // car holds } else if (car.isUtility()) { String s = pickupUtilityCars(carList, car, !IS_MANIFEST, !IS_TWO_COLUMN_TRACK); if (s != null) { newLine( fileOut, TrainSwitchListText.getStringHoldCar().split("\\{")[0] + s.trim()); // NOI18N } } else { newLine( fileOut, MessageFormat.format( messageFormatText = TrainSwitchListText.getStringHoldCar(), new Object[] { padAndTruncateString( car.getRoadName(), CarRoads.instance().getMaxNameLength()), padAndTruncateString( TrainCommon.splitString(car.getNumber()), Control.max_len_string_print_road_number), padAndTruncateString( car.getTypeName().split("-")[0], CarTypes.instance().getMaxNameLength()), padAndTruncateString( car.getLength() + LENGTHABV, Control.max_len_string_length_name), padAndTruncateString( car.getLoadName(), CarLoads.instance().getMaxNameLength()), padAndTruncateString(trackName, locationManager.getMaxTrackNameLength()), padAndTruncateString( car.getColor(), CarColors.instance().getMaxNameLength()) })); } } // now do set outs at this location for (Car car : carList) { if (!splitString(car.getDestinationTrackName()).equals(trackName)) { continue; } if (car.getRouteDestination() != null && splitString(car.getRouteDestination().getLocation().getName()) .equals(splitString(location.getName()))) { // cars are sorted by train name, print train message once if (!trainName.equals(car.getTrainName())) { trainName = car.getTrainName(); newLine( fileOut, MessageFormat.format( messageFormatText = TrainSwitchListText.getStringScheduledWork(), new Object[] {car.getTrainName(), car.getTrain().getDescription()})); printDropCarHeader(fileOut, !IS_MANIFEST, !IS_TWO_COLUMN_TRACK); } if (car.isUtility()) { setoutUtilityCars(fileOut, carList, car, !IS_MANIFEST); } else { dropCar(fileOut, car, !IS_MANIFEST); } } } } } } } catch (IllegalArgumentException e) { newLine( fileOut, MessageFormat.format( Bundle.getMessage("ErrorIllegalArgument"), new Object[] {Bundle.getMessage("TitleSwitchListText"), e.getLocalizedMessage()})); newLine(fileOut, messageFormatText); e.printStackTrace(); } // Are there any cars that need to be found? addCarsLocationUnknown(fileOut, !IS_MANIFEST); fileOut.flush(); fileOut.close(); }