Пример #1
0
 public void dispose() {
   if (_track != null) {
     _track.removePropertyChangeListener(this);
   }
   _location.removePropertyChangeListener(this);
   CarLoads.instance().removePropertyChangeListener(this);
   CarTypes.instance().removePropertyChangeListener(this);
   super.dispose();
 }
Пример #2
0
 private void updateTypeComboBoxes() {
   CarTypes.instance().updateComboBox(comboBoxTypes);
   // remove car types not serviced by this location and track
   for (int i = comboBoxTypes.getItemCount() - 1; i >= 0; i--) {
     String type = comboBoxTypes.getItemAt(i);
     if (_track != null && !_track.acceptsTypeName(type)) {
       comboBoxTypes.removeItem(type);
     }
   }
   CarTypes.instance().updateComboBox(comboBoxShipTypes);
   // remove car types not serviced by this location and track
   for (int i = comboBoxShipTypes.getItemCount() - 1; i >= 0; i--) {
     String type = comboBoxShipTypes.getItemAt(i);
     if (_track != null && !_track.acceptsTypeName(type)) {
       comboBoxShipTypes.removeItem(type);
     }
   }
 }
Пример #3
0
  // test Track typename support
  public void testTrackTypeNameSupport() {
    Location l = new Location("Location Test Name id", "Location Test Name");
    Track t = new Track("Test id", "Test Name", "Test Type", l);
    Assert.assertEquals("Location Track id", "Test id", t.getId());
    Assert.assertEquals("Location Track Name", "Test Name", t.getName());
    Assert.assertEquals("Location Track Type", "Test Type", t.getTrackType());
    Assert.assertEquals("Location", l, t.getLocation());

    /* Test Type Name */
    Assert.assertEquals(
        "Location Track Accepts Type Name undefined", false, t.acceptsTypeName("TestTypeName"));

    t.addTypeName("TestTypeName");
    Assert.assertEquals(
        "Location Track Accepts Type Name defined", false, t.acceptsTypeName("TestTypeName"));

    // now add to car types
    CarTypes ct = CarTypes.instance();
    ct.addName("TestTypeName");
    t.addTypeName("TestTypeName");
    Assert.assertEquals(
        "Location Track Accepts Type Name defined after ct",
        false,
        t.acceptsTypeName("TestTypeName"));

    // location must also accept the same type
    l.addTypeName("TestTypeName");
    Assert.assertEquals(
        "Location Track Accepts Type Name defined after location",
        true,
        t.acceptsTypeName("TestTypeName"));

    t.deleteTypeName("TestTypeName");
    Assert.assertEquals(
        "Location Track Accepts Type Name deleted", false, t.acceptsTypeName("TestTypeName"));

    /* Needed so later tests will behave correctly */
    ct.deleteName("TestTypeName");

    ct.addName("Baggager");
    t.addTypeName("Baggager");
    l.addTypeName("Baggager");

    Assert.assertEquals(
        "Location Track Accepts Type Name Baggager", true, t.acceptsTypeName("Baggager"));

    /* Test Road Name */
    t.setRoadOption(Track.INCLUDE_ROADS);
    Assert.assertEquals(
        "Location Track set Road Option INCLUDEROADS", "Include", t.getRoadOption());

    Assert.assertEquals(
        "Location Track Accepts Road Name undefined", false, t.acceptsRoadName("TestRoadName"));

    t.addRoadName("TestRoadName");
    Assert.assertEquals(
        "Location Track Accepts Road Name defined", true, t.acceptsRoadName("TestRoadName"));

    t.addRoadName("TestOtherRoadName");
    Assert.assertEquals(
        "Location Track Accepts Road Name other defined", true, t.acceptsRoadName("TestRoadName"));

    t.deleteRoadName("TestRoadName");
    Assert.assertEquals(
        "Location Track Accepts Road Name deleted", false, t.acceptsRoadName("TestRoadName"));

    t.setRoadOption(Track.ALL_ROADS);
    Assert.assertEquals("Location Track set Road Option AllROADS", "All", t.getRoadOption());
    Assert.assertEquals(
        "Location Track Accepts All Road Names", true, t.acceptsRoadName("TestRoadName"));

    t.setRoadOption(Track.EXCLUDE_ROADS);
    Assert.assertEquals(
        "Location Track set Road Option EXCLUDEROADS", "Exclude", t.getRoadOption());
    Assert.assertEquals(
        "Location Track Excludes Road Names", true, t.acceptsRoadName("TestRoadName"));

    t.addRoadName("TestRoadName");
    Assert.assertEquals(
        "Location Track Excludes Road Names 2", false, t.acceptsRoadName("TestRoadName"));

    /* Test Drop IDs */
    Assert.assertEquals(
        "Location Track Accepts Drop ID undefined", false, t.containsDropId("TestDropId"));

    t.addDropId("TestDropId");
    Assert.assertEquals(
        "Location Track Accepts Drop ID defined", true, t.containsDropId("TestDropId"));

    t.addDropId("TestOtherDropId");
    Assert.assertEquals(
        "Location Track Accepts Drop ID other defined", true, t.containsDropId("TestDropId"));

    t.deleteDropId("TestDropId");
    Assert.assertEquals(
        "Location Track Accepts Drop ID deleted", false, t.containsDropId("TestDropId"));

    /* Test Pickup IDs */
    Assert.assertEquals(
        "Location Track Accepts Pickup ID undefined", false, t.containsPickupId("TestPickupId"));

    t.addPickupId("TestPickupId");
    Assert.assertEquals(
        "Location Track Accepts Pickup ID defined", true, t.containsPickupId("TestPickupId"));

    t.addPickupId("TestOtherPickupId");
    Assert.assertEquals(
        "Location Track Accepts Pickup ID other defined", true, t.containsPickupId("TestPickupId"));

    t.deletePickupId("TestPickupId");
    Assert.assertEquals(
        "Location Track Accepts Pickup ID deleted", false, t.containsPickupId("TestPickupId"));
  }
Пример #4
0
  /**
   * 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();
  }
 @edu.umd.cs.findbugs.annotations.SuppressFBWarnings(
     value = "BC_UNCONFIRMED_CAST_OF_RETURN_VALUE",
     justification = "CarManager only provides Car Objects")
 private void runUpdate() {
   log.debug("run update");
   removePropertyChangeListerners();
   trainCommon.clearUtilityCarTypes(); // reset the utility car counts
   carCheckBoxes.clear();
   pTrack.removeAll();
   boolean pickup = false;
   boolean setout = false;
   if (_track != null) {
     pTrackPane.setBorder(BorderFactory.createTitledBorder(_track.getName()));
     textTrackCommentPane.setText(_track.getComment());
     textTrackCommentPane.setVisible(!_track.getComment().equals(Track.NONE));
     textTrackCommentWorkPane.setText("");
     for (Train train : trainManager.getTrainsArrivingThisLocationList(_track.getLocation())) {
       JPanel pTrain = new JPanel();
       pTrain.setLayout(new BoxLayout(pTrain, BoxLayout.Y_AXIS));
       pTrain.setBorder(
           BorderFactory.createTitledBorder(
               MessageFormat.format(
                   TrainSwitchListText.getStringScheduledWork(),
                   new Object[] {train.getName(), train.getDescription()})));
       // List locos first
       List<Engine> engList = engManager.getByTrainBlockingList(train);
       if (Setup.isPrintHeadersEnabled()) {
         for (Engine engine : engList) {
           if (engine.getTrack() == _track) {
             JLabel header = new JLabel(Tab + trainCommon.getPickupEngineHeader());
             setLabelFont(header);
             pTrain.add(header);
             break;
           }
         }
       }
       for (Engine engine : engList) {
         if (engine.getTrack() == _track) {
           engine.addPropertyChangeListener(this);
           rollingStock.add(engine);
           JCheckBox checkBox = new JCheckBox(trainCommon.pickupEngine(engine));
           setCheckBoxFont(checkBox);
           pTrain.add(checkBox);
           carCheckBoxes.put(engine.getId(), checkBox);
           pTrack.add(pTrain);
         }
       }
       if (Setup.isPrintHeadersEnabled()) {
         for (Engine engine : engList) {
           if (engine.getDestinationTrack() == _track) {
             JLabel header = new JLabel(Tab + trainCommon.getDropEngineHeader());
             setLabelFont(header);
             pTrain.add(header);
             break;
           }
         }
       }
       for (Engine engine : engList) {
         if (engine.getDestinationTrack() == _track) {
           engine.addPropertyChangeListener(this);
           rollingStock.add(engine);
           JCheckBox checkBox = new JCheckBox(trainCommon.dropEngine(engine));
           setCheckBoxFont(checkBox);
           pTrain.add(checkBox);
           carCheckBoxes.put(engine.getId(), checkBox);
           pTrack.add(pTrain);
         }
       }
       List<Car> carList = carManager.getByTrainDestinationList(train);
       if (Setup.isPrintHeadersEnabled()) {
         for (Car car : carList) {
           if (car.getTrack() == _track && car.getRouteDestination() != car.getRouteLocation()) {
             JLabel header =
                 new JLabel(
                     Tab
                         + trainCommon.getPickupCarHeader(
                             !IS_MANIFEST, !TrainCommon.IS_TWO_COLUMN_TRACK));
             setLabelFont(header);
             pTrain.add(header);
             break;
           }
         }
       }
       // sort car pick ups by their destination
       List<RouteLocation> routeList = train.getRoute().getLocationsBySequenceList();
       for (RouteLocation rl : routeList) {
         for (Car car : carList) {
           if (car.getTrack() == _track
               && car.getRouteDestination() != car.getRouteLocation()
               && car.getRouteDestination() == rl) {
             car.addPropertyChangeListener(this);
             rollingStock.add(car);
             String text;
             if (car.isUtility()) {
               text =
                   trainCommon.pickupUtilityCars(
                       carList, car, !IS_MANIFEST, !TrainCommon.IS_TWO_COLUMN_TRACK);
               if (text == null) {
                 continue; // this car type has already been processed
               }
             } else {
               text = trainCommon.pickupCar(car, !IS_MANIFEST, !TrainCommon.IS_TWO_COLUMN_TRACK);
             }
             pickup = true;
             JCheckBox checkBox = new JCheckBox(text);
             setCheckBoxFont(checkBox);
             pTrain.add(checkBox);
             carCheckBoxes.put(car.getId(), checkBox);
             pTrack.add(pTrain);
           }
         }
       }
       // now do car set outs
       if (Setup.isPrintHeadersEnabled()) {
         for (Car car : carList) {
           if (car.getDestinationTrack() == _track
               && car.getRouteDestination() != car.getRouteLocation()) {
             JLabel header =
                 new JLabel(
                     Tab
                         + trainCommon.getDropCarHeader(
                             !IS_MANIFEST, !TrainCommon.IS_TWO_COLUMN_TRACK));
             setLabelFont(header);
             pTrain.add(header);
             break;
           }
         }
       }
       for (Car car : carList) {
         if (car.getDestinationTrack() == _track
             && car.getRouteLocation() != car.getRouteDestination()) {
           car.addPropertyChangeListener(this);
           rollingStock.add(car);
           String text;
           if (car.isUtility()) {
             text = trainCommon.setoutUtilityCars(carList, car, !TrainCommon.LOCAL, !IS_MANIFEST);
             if (text == null) {
               continue; // this car type has already been processed
             }
           } else {
             text = trainCommon.dropCar(car, !IS_MANIFEST, !TrainCommon.IS_TWO_COLUMN_TRACK);
           }
           setout = true;
           JCheckBox checkBox = new JCheckBox(text);
           setCheckBoxFont(checkBox);
           pTrain.add(checkBox);
           carCheckBoxes.put(car.getId(), checkBox);
           pTrack.add(pTrain);
         }
       }
       // now do local car moves
       if (Setup.isPrintHeadersEnabled()) {
         for (Car car : carList) {
           if ((car.getTrack() == _track || car.getDestinationTrack() == _track)
               && car.getRouteDestination() == car.getRouteLocation()) {
             JLabel header = new JLabel(Tab + trainCommon.getLocalMoveHeader(!IS_MANIFEST));
             setLabelFont(header);
             pTrain.add(header);
             break;
           }
         }
       }
       for (Car car : carList) {
         if ((car.getTrack() == _track || car.getDestinationTrack() == _track)
             && car.getRouteLocation() != null
             && car.getRouteLocation() == car.getRouteDestination()) {
           car.addPropertyChangeListener(this);
           rollingStock.add(car);
           String text;
           if (car.isUtility()) {
             text = trainCommon.setoutUtilityCars(carList, car, TrainCommon.LOCAL, !IS_MANIFEST);
             if (text == null) {
               continue; // this car type has already been processed
             }
           } else {
             text = trainCommon.localMoveCar(car, !IS_MANIFEST);
           }
           setout = true;
           JCheckBox checkBox = new JCheckBox(text);
           setCheckBoxFont(checkBox);
           pTrain.add(checkBox);
           carCheckBoxes.put(car.getId(), checkBox);
           pTrack.add(pTrain);
         }
       }
     }
     // now do car holds
     // we only need the cars on this track
     List<RollingStock> rsList = carManager.getByTrainList();
     List<Car> carList = new ArrayList<Car>();
     for (RollingStock rs : rsList) {
       if (rs.getTrack() != _track || rs.getRouteLocation() != null) continue;
       carList.add((Car) rs);
     }
     JPanel pHoldCars = new JPanel();
     pHoldCars.setLayout(new BoxLayout(pHoldCars, BoxLayout.Y_AXIS));
     pHoldCars.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("HoldCars")));
     for (Car car : carList) {
       String text;
       if (car.isUtility()) {
         String s =
             trainCommon.pickupUtilityCars(
                 carList, car, !IS_MANIFEST, !TrainCommon.IS_TWO_COLUMN_TRACK);
         if (s == null) continue;
         text = TrainSwitchListText.getStringHoldCar().split("\\{")[0] + s.trim();
       } else {
         text =
             MessageFormat.format(
                 TrainSwitchListText.getStringHoldCar(),
                 new Object[] {
                   TrainCommon.padAndTruncateString(
                       car.getRoadName(), CarRoads.instance().getMaxNameLength()),
                   TrainCommon.padAndTruncateString(
                       car.getNumber(), Control.max_len_string_print_road_number),
                   TrainCommon.padAndTruncateString(
                       car.getTypeName().split("-")[0], CarTypes.instance().getMaxNameLength()),
                   TrainCommon.padAndTruncateString(
                       car.getLength() + TrainCommon.LENGTHABV,
                       Control.max_len_string_length_name),
                   TrainCommon.padAndTruncateString(
                       car.getLoadName(), CarLoads.instance().getMaxNameLength()),
                   TrainCommon.padAndTruncateString(
                       _track.getName(), LocationManager.instance().getMaxTrackNameLength()),
                   TrainCommon.padAndTruncateString(
                       car.getColor(), CarColors.instance().getMaxNameLength())
                 });
       }
       JCheckBox checkBox = new JCheckBox(text);
       setCheckBoxFont(checkBox);
       pHoldCars.add(checkBox);
       carCheckBoxes.put(car.getId(), checkBox);
       pTrack.add(pHoldCars);
     }
     pTrackPane.validate();
     if (pickup && !setout) {
       textTrackCommentWorkPane.setText(_track.getCommentPickup());
     } else if (!pickup && setout) {
       textTrackCommentWorkPane.setText(_track.getCommentSetout());
     } else if (pickup && setout) {
       textTrackCommentWorkPane.setText(_track.getCommentBoth());
     }
     textTrackCommentWorkPane.setVisible(!textTrackCommentWorkPane.getText().equals(""));
   } else {
     pTrackPane.setBorder(BorderFactory.createTitledBorder(""));
     textTrackCommentPane.setVisible(false);
     textTrackCommentWorkPane.setVisible(false);
   }
 }
Пример #6
0
  public void initComponents(Location location, Track track) {
    _location = location;
    _track = track;

    // property changes
    _location.addPropertyChangeListener(this);
    // listen for car load name and type changes
    CarLoads.instance().addPropertyChangeListener(this);
    CarTypes.instance().addPropertyChangeListener(this);

    // the following code sets the frame's initial state
    getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));

    // Set up the panels
    // Layout the panel by rows
    // row 1
    JPanel p1 = new JPanel();
    p1.setLayout(new BoxLayout(p1, BoxLayout.X_AXIS));
    p1.setMaximumSize(new Dimension(2000, 250));

    // row 1a
    JPanel pTrackName = new JPanel();
    pTrackName.setLayout(new GridBagLayout());
    pTrackName.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Track")));
    addItem(pTrackName, trackName, 0, 0);

    // row 1b
    JPanel pLocationName = new JPanel();
    pLocationName.setLayout(new GridBagLayout());
    pLocationName.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Location")));
    addItem(pLocationName, new JLabel(_location.getName()), 0, 0);

    p1.add(pTrackName);
    p1.add(pLocationName);

    // row 3
    JPanel p3 = new JPanel();
    p3.setLayout(new BoxLayout(p3, BoxLayout.Y_AXIS));
    JScrollPane pane3 = new JScrollPane(p3);
    pane3.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("LoadsTrack")));
    pane3.setMaximumSize(new Dimension(2000, 400));

    JPanel pLoadRadioButtons = new JPanel();
    pLoadRadioButtons.setLayout(new FlowLayout());

    pLoadRadioButtons.add(loadNameAll);
    pLoadRadioButtons.add(loadNameInclude);
    pLoadRadioButtons.add(loadNameExclude);
    pLoadRadioButtons.add(loadAndTypeCheckBox);

    pLoadControls.setLayout(new FlowLayout());

    pLoadControls.add(comboBoxTypes);
    pLoadControls.add(comboBoxLoads);
    pLoadControls.add(addLoadButton);
    pLoadControls.add(deleteLoadButton);
    pLoadControls.add(deleteAllLoadsButton);

    pLoadControls.setVisible(false);

    p3.add(pLoadRadioButtons);
    p3.add(pLoadControls);

    // row 4
    panelLoads.setLayout(new GridBagLayout());
    paneLoads.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Loads")));

    ButtonGroup loadGroup = new ButtonGroup();
    loadGroup.add(loadNameAll);
    loadGroup.add(loadNameInclude);
    loadGroup.add(loadNameExclude);

    // row 6
    JPanel p6 = new JPanel();
    p6.setLayout(new BoxLayout(p6, BoxLayout.Y_AXIS));
    paneShipLoadControls = new JScrollPane(p6);
    paneShipLoadControls.setBorder(
        BorderFactory.createTitledBorder(Bundle.getMessage("ShipLoadsTrack")));
    paneShipLoadControls.setMaximumSize(new Dimension(2000, 400));

    JPanel pShipLoadRadioButtons = new JPanel();
    pShipLoadRadioButtons.setLayout(new FlowLayout());

    pShipLoadRadioButtons.add(shipLoadNameAll);
    pShipLoadRadioButtons.add(shipLoadNameInclude);
    pShipLoadRadioButtons.add(shipLoadNameExclude);
    pShipLoadRadioButtons.add(shipLoadAndTypeCheckBox);

    pShipLoadControls.setLayout(new FlowLayout());

    pShipLoadControls.add(comboBoxShipTypes);
    pShipLoadControls.add(comboBoxShipLoads);
    pShipLoadControls.add(addShipLoadButton);
    pShipLoadControls.add(deleteShipLoadButton);
    pShipLoadControls.add(deleteAllShipLoadsButton);

    pShipLoadControls.setVisible(false);

    p6.add(pShipLoadRadioButtons);
    p6.add(pShipLoadControls);

    // row 7
    panelShipLoads.setLayout(new GridBagLayout());
    paneShipLoads.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Loads")));

    ButtonGroup shipLoadGroup = new ButtonGroup();
    shipLoadGroup.add(shipLoadNameAll);
    shipLoadGroup.add(shipLoadNameInclude);
    shipLoadGroup.add(shipLoadNameExclude);

    JPanel pOptions = new JPanel();
    pOptions.setLayout(new GridBagLayout());
    pOptions.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Options")));
    pOptions.setMaximumSize(new Dimension(2000, 400));
    addItem(pOptions, holdCars, 0, 0);
    holdCars.setText(Bundle.getMessage("HoldCarsWithCustomLoads"));
    holdCars.setToolTipText(Bundle.getMessage("HoldCarsWithCustomLoadsTip"));

    // row 12
    JPanel panelButtons = new JPanel();
    panelButtons.setLayout(new GridBagLayout());
    panelButtons.setBorder(BorderFactory.createTitledBorder(""));
    panelButtons.setMaximumSize(new Dimension(2000, 200));

    // row 13
    addItem(panelButtons, saveTrackButton, 0, 0);

    getContentPane().add(p1);
    getContentPane().add(pane3);
    getContentPane().add(paneLoads);
    getContentPane().add(paneShipLoadControls);
    getContentPane().add(paneShipLoads);
    getContentPane().add(pOptions);
    getContentPane().add(panelButtons);

    // setup buttons
    addButtonAction(saveTrackButton);

    addButtonAction(deleteLoadButton);
    addButtonAction(deleteAllLoadsButton);
    addButtonAction(addLoadButton);

    addButtonAction(deleteShipLoadButton);
    addButtonAction(deleteAllShipLoadsButton);
    addButtonAction(addShipLoadButton);

    addRadioButtonAction(loadNameAll);
    addRadioButtonAction(loadNameInclude);
    addRadioButtonAction(loadNameExclude);

    addRadioButtonAction(shipLoadNameAll);
    addRadioButtonAction(shipLoadNameInclude);
    addRadioButtonAction(shipLoadNameExclude);

    addComboBoxAction(comboBoxTypes);
    addComboBoxAction(comboBoxShipTypes);

    paneShipLoadControls.setVisible(false);
    paneShipLoads.setVisible(false);
    pOptions.setVisible(false);

    // load fields and enable buttons
    if (_track != null) {
      _track.addPropertyChangeListener(this);
      trackName.setText(_track.getName());
      // only show ship loads for staging tracks
      paneShipLoadControls.setVisible(_track.getTrackType().equals(Track.STAGING));
      paneShipLoads.setVisible(_track.getTrackType().equals(Track.STAGING));
      pOptions.setVisible(_track.getTrackType().equals(Track.SPUR));
      holdCars.setSelected(_track.isHoldCarsWithCustomLoadsEnabled());
      updateButtons(true);
    } else {
      updateButtons(false);
    }

    // build menu
    // JMenuBar menuBar = new JMenuBar();
    // _toolMenu = new JMenu(Bundle.getMessage("Tools"));
    // menuBar.add(_toolMenu);
    // setJMenuBar(menuBar);
    // load
    updateTypeComboBoxes();
    updateLoadComboBoxes();
    updateLoadNames();
    updateShipLoadNames();

    loadAndTypeCheckBox.setSelected(loadAndType);
    shipLoadAndTypeCheckBox.setSelected(shipLoadAndType);

    initMinimumSize(new Dimension(Control.panelWidth600, Control.panelHeight400));
  }
Пример #7
0
/**
 * Frame for user edit of track loads
 *
 * @author Dan Boudreau Copyright (C) 2013, 2014, 2015
 * @version $Revision: 22371 $
 */
public class TrackLoadEditFrame extends OperationsFrame
    implements java.beans.PropertyChangeListener {

  /** */
  private static final long serialVersionUID = -5231003531264725867L;

  private static boolean loadAndType = false;
  private static boolean shipLoadAndType = false;

  Location _location = null;
  Track _track = null;
  String _type = "";
  JMenu _toolMenu = null;

  // panels
  JPanel pLoadControls = new JPanel();
  JPanel panelLoads = new JPanel();
  JScrollPane paneLoads = new JScrollPane(panelLoads);

  JPanel pShipLoadControls = new JPanel();
  JPanel panelShipLoads = new JPanel();
  JScrollPane paneShipLoadControls;
  JScrollPane paneShipLoads = new JScrollPane(panelShipLoads);

  // major buttons
  JButton saveTrackButton = new JButton(Bundle.getMessage("SaveTrack"));

  JButton addLoadButton = new JButton(Bundle.getMessage("AddLoad"));
  JButton deleteLoadButton = new JButton(Bundle.getMessage("DeleteLoad"));
  JButton deleteAllLoadsButton = new JButton(Bundle.getMessage("DeleteAll"));

  JButton addShipLoadButton = new JButton(Bundle.getMessage("AddLoad"));
  JButton deleteShipLoadButton = new JButton(Bundle.getMessage("DeleteLoad"));
  JButton deleteAllShipLoadsButton = new JButton(Bundle.getMessage("DeleteAll"));

  // check boxes
  JCheckBox loadAndTypeCheckBox = new JCheckBox(Bundle.getMessage("TypeAndLoad"));
  JCheckBox shipLoadAndTypeCheckBox = new JCheckBox(Bundle.getMessage("TypeAndLoad"));
  JCheckBox holdCars = new JCheckBox();

  // radio buttons
  JRadioButton loadNameAll = new JRadioButton(Bundle.getMessage("AcceptAll"));
  JRadioButton loadNameInclude = new JRadioButton(Bundle.getMessage("AcceptOnly"));
  JRadioButton loadNameExclude = new JRadioButton(Bundle.getMessage("Exclude"));

  JRadioButton shipLoadNameAll = new JRadioButton(Bundle.getMessage("ShipAll"));
  JRadioButton shipLoadNameInclude = new JRadioButton(Bundle.getMessage("ShipOnly"));
  JRadioButton shipLoadNameExclude = new JRadioButton(Bundle.getMessage("Exclude"));

  // combo box
  JComboBox<String> comboBoxLoads = CarLoads.instance().getComboBox(null);
  JComboBox<String> comboBoxShipLoads = CarLoads.instance().getComboBox(null);
  JComboBox<String> comboBoxTypes = CarTypes.instance().getComboBox();
  JComboBox<String> comboBoxShipTypes = CarTypes.instance().getComboBox();

  // labels
  JLabel trackName = new JLabel();

  public static final String DISPOSE = "dispose"; // NOI18N
  public static final int MAX_NAME_LENGTH = Control.max_len_string_track_name;

  public TrackLoadEditFrame() {
    super(Bundle.getMessage("TitleEditTrackLoads"));
  }

  public void initComponents(Location location, Track track) {
    _location = location;
    _track = track;

    // property changes
    _location.addPropertyChangeListener(this);
    // listen for car load name and type changes
    CarLoads.instance().addPropertyChangeListener(this);
    CarTypes.instance().addPropertyChangeListener(this);

    // the following code sets the frame's initial state
    getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));

    // Set up the panels
    // Layout the panel by rows
    // row 1
    JPanel p1 = new JPanel();
    p1.setLayout(new BoxLayout(p1, BoxLayout.X_AXIS));
    p1.setMaximumSize(new Dimension(2000, 250));

    // row 1a
    JPanel pTrackName = new JPanel();
    pTrackName.setLayout(new GridBagLayout());
    pTrackName.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Track")));
    addItem(pTrackName, trackName, 0, 0);

    // row 1b
    JPanel pLocationName = new JPanel();
    pLocationName.setLayout(new GridBagLayout());
    pLocationName.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Location")));
    addItem(pLocationName, new JLabel(_location.getName()), 0, 0);

    p1.add(pTrackName);
    p1.add(pLocationName);

    // row 3
    JPanel p3 = new JPanel();
    p3.setLayout(new BoxLayout(p3, BoxLayout.Y_AXIS));
    JScrollPane pane3 = new JScrollPane(p3);
    pane3.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("LoadsTrack")));
    pane3.setMaximumSize(new Dimension(2000, 400));

    JPanel pLoadRadioButtons = new JPanel();
    pLoadRadioButtons.setLayout(new FlowLayout());

    pLoadRadioButtons.add(loadNameAll);
    pLoadRadioButtons.add(loadNameInclude);
    pLoadRadioButtons.add(loadNameExclude);
    pLoadRadioButtons.add(loadAndTypeCheckBox);

    pLoadControls.setLayout(new FlowLayout());

    pLoadControls.add(comboBoxTypes);
    pLoadControls.add(comboBoxLoads);
    pLoadControls.add(addLoadButton);
    pLoadControls.add(deleteLoadButton);
    pLoadControls.add(deleteAllLoadsButton);

    pLoadControls.setVisible(false);

    p3.add(pLoadRadioButtons);
    p3.add(pLoadControls);

    // row 4
    panelLoads.setLayout(new GridBagLayout());
    paneLoads.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Loads")));

    ButtonGroup loadGroup = new ButtonGroup();
    loadGroup.add(loadNameAll);
    loadGroup.add(loadNameInclude);
    loadGroup.add(loadNameExclude);

    // row 6
    JPanel p6 = new JPanel();
    p6.setLayout(new BoxLayout(p6, BoxLayout.Y_AXIS));
    paneShipLoadControls = new JScrollPane(p6);
    paneShipLoadControls.setBorder(
        BorderFactory.createTitledBorder(Bundle.getMessage("ShipLoadsTrack")));
    paneShipLoadControls.setMaximumSize(new Dimension(2000, 400));

    JPanel pShipLoadRadioButtons = new JPanel();
    pShipLoadRadioButtons.setLayout(new FlowLayout());

    pShipLoadRadioButtons.add(shipLoadNameAll);
    pShipLoadRadioButtons.add(shipLoadNameInclude);
    pShipLoadRadioButtons.add(shipLoadNameExclude);
    pShipLoadRadioButtons.add(shipLoadAndTypeCheckBox);

    pShipLoadControls.setLayout(new FlowLayout());

    pShipLoadControls.add(comboBoxShipTypes);
    pShipLoadControls.add(comboBoxShipLoads);
    pShipLoadControls.add(addShipLoadButton);
    pShipLoadControls.add(deleteShipLoadButton);
    pShipLoadControls.add(deleteAllShipLoadsButton);

    pShipLoadControls.setVisible(false);

    p6.add(pShipLoadRadioButtons);
    p6.add(pShipLoadControls);

    // row 7
    panelShipLoads.setLayout(new GridBagLayout());
    paneShipLoads.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Loads")));

    ButtonGroup shipLoadGroup = new ButtonGroup();
    shipLoadGroup.add(shipLoadNameAll);
    shipLoadGroup.add(shipLoadNameInclude);
    shipLoadGroup.add(shipLoadNameExclude);

    JPanel pOptions = new JPanel();
    pOptions.setLayout(new GridBagLayout());
    pOptions.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Options")));
    pOptions.setMaximumSize(new Dimension(2000, 400));
    addItem(pOptions, holdCars, 0, 0);
    holdCars.setText(Bundle.getMessage("HoldCarsWithCustomLoads"));
    holdCars.setToolTipText(Bundle.getMessage("HoldCarsWithCustomLoadsTip"));

    // row 12
    JPanel panelButtons = new JPanel();
    panelButtons.setLayout(new GridBagLayout());
    panelButtons.setBorder(BorderFactory.createTitledBorder(""));
    panelButtons.setMaximumSize(new Dimension(2000, 200));

    // row 13
    addItem(panelButtons, saveTrackButton, 0, 0);

    getContentPane().add(p1);
    getContentPane().add(pane3);
    getContentPane().add(paneLoads);
    getContentPane().add(paneShipLoadControls);
    getContentPane().add(paneShipLoads);
    getContentPane().add(pOptions);
    getContentPane().add(panelButtons);

    // setup buttons
    addButtonAction(saveTrackButton);

    addButtonAction(deleteLoadButton);
    addButtonAction(deleteAllLoadsButton);
    addButtonAction(addLoadButton);

    addButtonAction(deleteShipLoadButton);
    addButtonAction(deleteAllShipLoadsButton);
    addButtonAction(addShipLoadButton);

    addRadioButtonAction(loadNameAll);
    addRadioButtonAction(loadNameInclude);
    addRadioButtonAction(loadNameExclude);

    addRadioButtonAction(shipLoadNameAll);
    addRadioButtonAction(shipLoadNameInclude);
    addRadioButtonAction(shipLoadNameExclude);

    addComboBoxAction(comboBoxTypes);
    addComboBoxAction(comboBoxShipTypes);

    paneShipLoadControls.setVisible(false);
    paneShipLoads.setVisible(false);
    pOptions.setVisible(false);

    // load fields and enable buttons
    if (_track != null) {
      _track.addPropertyChangeListener(this);
      trackName.setText(_track.getName());
      // only show ship loads for staging tracks
      paneShipLoadControls.setVisible(_track.getTrackType().equals(Track.STAGING));
      paneShipLoads.setVisible(_track.getTrackType().equals(Track.STAGING));
      pOptions.setVisible(_track.getTrackType().equals(Track.SPUR));
      holdCars.setSelected(_track.isHoldCarsWithCustomLoadsEnabled());
      updateButtons(true);
    } else {
      updateButtons(false);
    }

    // build menu
    // JMenuBar menuBar = new JMenuBar();
    // _toolMenu = new JMenu(Bundle.getMessage("Tools"));
    // menuBar.add(_toolMenu);
    // setJMenuBar(menuBar);
    // load
    updateTypeComboBoxes();
    updateLoadComboBoxes();
    updateLoadNames();
    updateShipLoadNames();

    loadAndTypeCheckBox.setSelected(loadAndType);
    shipLoadAndTypeCheckBox.setSelected(shipLoadAndType);

    initMinimumSize(new Dimension(Control.panelWidth600, Control.panelHeight400));
  }

  // Save, Delete, Add
  public void buttonActionPerformed(java.awt.event.ActionEvent ae) {
    if (_track == null) {
      return;
    }
    if (ae.getSource() == saveTrackButton) {
      log.debug("track save button activated");
      save();
      if (Setup.isCloseWindowOnSaveEnabled()) {
        dispose();
      }
    }
    if (ae.getSource() == addLoadButton) {
      String loadName = (String) comboBoxLoads.getSelectedItem();
      if (loadAndTypeCheckBox.isSelected()) {
        loadName = comboBoxTypes.getSelectedItem() + CarLoad.SPLIT_CHAR + loadName;
      }
      _track.addLoadName(loadName);
      selectNextItemComboBox(comboBoxLoads);
    }
    if (ae.getSource() == deleteLoadButton) {
      String loadName = (String) comboBoxLoads.getSelectedItem();
      if (loadAndTypeCheckBox.isSelected()) {
        loadName = comboBoxTypes.getSelectedItem() + CarLoad.SPLIT_CHAR + loadName;
      }
      _track.deleteLoadName(loadName);
      selectNextItemComboBox(comboBoxLoads);
    }
    if (ae.getSource() == deleteAllLoadsButton) {
      deleteAllLoads();
    }
    if (ae.getSource() == addShipLoadButton) {
      String loadName = (String) comboBoxShipLoads.getSelectedItem();
      if (shipLoadAndTypeCheckBox.isSelected()) {
        loadName = comboBoxShipTypes.getSelectedItem() + CarLoad.SPLIT_CHAR + loadName;
      }
      _track.addShipLoadName(loadName);
      selectNextItemComboBox(comboBoxShipLoads);
    }
    if (ae.getSource() == deleteShipLoadButton) {
      String loadName = (String) comboBoxShipLoads.getSelectedItem();
      if (shipLoadAndTypeCheckBox.isSelected()) {
        loadName = comboBoxShipTypes.getSelectedItem() + CarLoad.SPLIT_CHAR + loadName;
      }
      _track.deleteShipLoadName(loadName);
      selectNextItemComboBox(comboBoxShipLoads);
    }
    if (ae.getSource() == deleteAllShipLoadsButton) {
      deleteAllShipLoads();
    }
  }

  @edu.umd.cs.findbugs.annotations.SuppressFBWarnings(
      value = "ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD")
  protected void save() {
    checkForErrors();
    _track.setHoldCarsWithCustomLoadsEnabled(holdCars.isSelected());
    // save the last state of the "Use car type and load" checkbox
    loadAndType = loadAndTypeCheckBox.isSelected();
    shipLoadAndType = shipLoadAndTypeCheckBox.isSelected();
    // save location file
    OperationsXml.save();
  }

  protected void updateButtons(boolean enabled) {
    saveTrackButton.setEnabled(enabled);

    loadNameAll.setEnabled(enabled);
    loadNameInclude.setEnabled(enabled);
    loadNameExclude.setEnabled(enabled);
    loadAndTypeCheckBox.setEnabled(enabled);

    boolean en =
        enabled
            && (_track.isAddCustomLoadsAnyStagingTrackEnabled()
                || _track.isAddCustomLoadsAnySpurEnabled()
                || _track.isAddCustomLoadsEnabled());

    shipLoadNameAll.setEnabled(en);
    shipLoadNameInclude.setEnabled(en);
    shipLoadNameExclude.setEnabled(en);
    shipLoadAndTypeCheckBox.setEnabled(en);

    addShipLoadButton.setEnabled(en);
    deleteShipLoadButton.setEnabled(en);
    deleteAllShipLoadsButton.setEnabled(en);

    comboBoxShipLoads.setEnabled(en);
    comboBoxShipTypes.setEnabled(en);
  }

  public void radioButtonActionPerformed(java.awt.event.ActionEvent ae) {
    log.debug("radio button activated");
    if (ae.getSource() == loadNameAll) {
      _track.setLoadOption(Track.ALL_LOADS);
    }
    if (ae.getSource() == loadNameInclude) {
      _track.setLoadOption(Track.INCLUDE_LOADS);
    }
    if (ae.getSource() == loadNameExclude) {
      _track.setLoadOption(Track.EXCLUDE_LOADS);
    }
    if (ae.getSource() == shipLoadNameAll) {
      _track.setShipLoadOption(Track.ALL_LOADS);
    }
    if (ae.getSource() == shipLoadNameInclude) {
      _track.setShipLoadOption(Track.INCLUDE_LOADS);
    }
    if (ae.getSource() == shipLoadNameExclude) {
      _track.setShipLoadOption(Track.EXCLUDE_LOADS);
    }
  }

  // Car type combo box has been changed, show loads associated with this car type
  public void comboBoxActionPerformed(java.awt.event.ActionEvent ae) {
    updateLoadComboBoxes();
  }

  private void updateLoadComboBoxes() {
    String carType = (String) comboBoxTypes.getSelectedItem();
    CarLoads.instance().updateComboBox(carType, comboBoxLoads);
    carType = (String) comboBoxShipTypes.getSelectedItem();
    CarLoads.instance().updateComboBox(carType, comboBoxShipLoads);
  }

  private void updateLoadNames() {
    log.debug("Update load names");
    panelLoads.removeAll();
    if (_track != null) {
      // set radio button
      loadNameAll.setSelected(_track.getLoadOption().equals(Track.ALL_LOADS));
      loadNameInclude.setSelected(_track.getLoadOption().equals(Track.INCLUDE_LOADS));
      loadNameExclude.setSelected(_track.getLoadOption().equals(Track.EXCLUDE_LOADS));

      pLoadControls.setVisible(!loadNameAll.isSelected());

      if (!loadNameAll.isSelected()) {
        int x = 0;
        int y = 0; // vertical position in panel

        int numberOfLoads = getNumberOfCheckboxesPerLine() / 2 + 1;
        for (String loadName : _track.getLoadNames()) {
          JLabel load = new JLabel();
          load.setText(loadName);
          addItemTop(panelLoads, load, x++, y);
          // limit the number of loads per line
          if (x > numberOfLoads) {
            y++;
            x = 0;
          }
        }
        revalidate();
      }
    } else {
      loadNameAll.setSelected(true);
    }
    panelLoads.repaint();
    panelLoads.revalidate();
  }

  private void updateShipLoadNames() {
    log.debug("Update ship load names");
    panelShipLoads.removeAll();
    if (_track != null) {
      // set radio button
      shipLoadNameAll.setSelected(_track.getShipLoadOption().equals(Track.ALL_LOADS));
      shipLoadNameInclude.setSelected(_track.getShipLoadOption().equals(Track.INCLUDE_LOADS));
      shipLoadNameExclude.setSelected(_track.getShipLoadOption().equals(Track.EXCLUDE_LOADS));

      pShipLoadControls.setVisible(!shipLoadNameAll.isSelected());

      if (!shipLoadNameAll.isSelected()) {
        int x = 0;
        int y = 0; // vertical position in panel

        int numberOfLoads = getNumberOfCheckboxesPerLine() / 2 + 1;
        for (String loadName : _track.getShipLoadNames()) {
          JLabel load = new JLabel();
          load.setText(loadName);
          addItemTop(panelShipLoads, load, x++, y);
          // limit the number of loads per line
          if (x > numberOfLoads) {
            y++;
            x = 0;
          }
        }
        revalidate();
      }
    } else {
      shipLoadNameAll.setSelected(true);
    }
    panelShipLoads.repaint();
    panelShipLoads.revalidate();
  }

  private void deleteAllLoads() {
    if (_track != null) {
      for (String loadName : _track.getLoadNames()) {
        _track.deleteLoadName(loadName);
      }
    }
  }

  private void deleteAllShipLoads() {
    if (_track != null) {
      for (String loadName : _track.getShipLoadNames()) {
        _track.deleteShipLoadName(loadName);
      }
    }
  }

  private void updateTypeComboBoxes() {
    CarTypes.instance().updateComboBox(comboBoxTypes);
    // remove car types not serviced by this location and track
    for (int i = comboBoxTypes.getItemCount() - 1; i >= 0; i--) {
      String type = comboBoxTypes.getItemAt(i);
      if (_track != null && !_track.acceptsTypeName(type)) {
        comboBoxTypes.removeItem(type);
      }
    }
    CarTypes.instance().updateComboBox(comboBoxShipTypes);
    // remove car types not serviced by this location and track
    for (int i = comboBoxShipTypes.getItemCount() - 1; i >= 0; i--) {
      String type = comboBoxShipTypes.getItemAt(i);
      if (_track != null && !_track.acceptsTypeName(type)) {
        comboBoxShipTypes.removeItem(type);
      }
    }
  }

  private void checkForErrors() {
    if (_track.getLoadOption().equals(Track.INCLUDE_LOADS) && _track.getLoadNames().length == 0
        || _track.getShipLoadOption().equals(Track.INCLUDE_LOADS)
            && _track.getShipLoadNames().length == 0) {
      JOptionPane.showMessageDialog(
          this,
          Bundle.getMessage("ErrorNeedLoads"),
          Bundle.getMessage("ErrorNoLoads"),
          JOptionPane.ERROR_MESSAGE);
    }
  }

  public void dispose() {
    if (_track != null) {
      _track.removePropertyChangeListener(this);
    }
    _location.removePropertyChangeListener(this);
    CarLoads.instance().removePropertyChangeListener(this);
    CarTypes.instance().removePropertyChangeListener(this);
    super.dispose();
  }

  public void propertyChange(java.beans.PropertyChangeEvent e) {
    if (Control.showProperty) {
      log.debug(
          "Property change ({}) old: ({}) new: ({})",
          e.getPropertyName(),
          e.getOldValue(),
          e.getNewValue()); // NOI18N
    }
    if (e.getPropertyName().equals(Location.TYPES_CHANGED_PROPERTY)
        || e.getPropertyName().equals(CarTypes.CARTYPES_CHANGED_PROPERTY)
        || e.getPropertyName().equals(Track.TYPES_CHANGED_PROPERTY)) {
      updateTypeComboBoxes();
    }
    if (e.getPropertyName().equals(CarLoads.LOAD_NAME_CHANGED_PROPERTY)
        || e.getPropertyName().equals(CarLoads.LOAD_CHANGED_PROPERTY)) {
      updateLoadComboBoxes();
      updateLoadNames();
      updateShipLoadNames();
    }
    if (e.getPropertyName().equals(Track.LOADS_CHANGED_PROPERTY)) {
      updateLoadNames();
      updateShipLoadNames();
    }
    if (e.getPropertyName().equals(Track.LOAD_OPTIONS_CHANGED_PROPERTY)) {
      if (_track != null) {
        updateButtons(true);
      }
    }
  }

  static Logger log = LoggerFactory.getLogger(TrackLoadEditFrame.class.getName());
}