/**
   * Update the GUI (both the dynamic and static windows) so that it displays the data of the newly
   * selected train.
   */
  public static void setSelectedId(int selId) {
    selectedId = selId;
    dynamicWindow.setTitle(
        "Train Model (Chris Paskie)   -   UI   (Train ID:   "
            + trainList.get(selectedId - 1).stringId
            + ")");
    staticWindow.setTitle(
        "Train Model (Chris Paskie)   -   Static Values   (Train ID:   "
            + trainList.get(selectedId - 1).stringId
            + ")");
    int hrs = (int) soloTime / (60 * 60);
    int min = ((int) soloTime / 60) % 60;
    int sec = (int) soloTime - (hrs * 60 * 60 + min * 60);
    jlTime.setText(
        ((hrs < 10) ? "0" : "")
            + hrs
            + ":"
            + ((min < 10) ? "0" : "")
            + min
            + ":"
            + ((sec < 10) ? "0" : "")
            + sec);

    jlCurVel.setText("" + trainList.get(selectedId - 1).curVelocity);
    jlCurAccel.setText("" + trainList.get(selectedId - 1).curAccel);
    jlRecPowerTNC.setText("" + trainList.get(selectedId - 1).receivedPower);
    jlManRecPower.setText("" + trainList.get(selectedId - 1).manualPower);
    jlToggleManRecPower.setText("" + trainList.get(selectedId - 1).issetManualPower);
    jlPostedSpdLmt.setText("" + trainList.get(selectedId - 1).postedSpeedLimit);
    jlManDesSpdLmt.setText("" + trainList.get(selectedId - 1).manualSpeedLimit);
    jlToggleManDesSpdLmt.setText("" + trainList.get(selectedId - 1).issetManualSpeedLimit);
    jlGrade.setText("" + trainList.get(selectedId - 1).getRelativeGrade());
    jlTotalMass.setText("" + trainList.get(selectedId - 1).totalMass);
    jlPassengerCount.setText("" + trainList.get(selectedId - 1).numPassengers);
    jlCrewCount.setText("" + trainList.get(selectedId - 1).numCrew);
    jlPosition.setText(
        ""
            + ((trainList.get(selectedId - 1).issetSignalPickupFailure)
                ? "???????"
                : ("[ "
                    + trainList.get(selectedId - 1).positionBlock.id
                    + " , "
                    + trainList.get(selectedId - 1).positionMeters
                    + " ]")));
    jlToggleSignalPickupFailure.setText(
        "" + trainList.get(selectedId - 1).issetSignalPickupFailure);
    jlToggleEngineFailure.setText("" + trainList.get(selectedId - 1).issetEngineFailure);
    jlToggleBrakeFailure.setText("" + trainList.get(selectedId - 1).issetBrakeFailure);
    jlToggleServiceBrake.setText("" + trainList.get(selectedId - 1).issetServiceBrake);
    jlToggleEmergencyBrake.setText("" + trainList.get(selectedId - 1).issetEmerBrake);
    jlLights.setText("" + ((trainList.get(selectedId - 1).issetLightsOn) ? "On" : "Off"));
    jlManLights.setText("" + ((trainList.get(selectedId - 1).issetLightsOnManual) ? "On" : "Off"));
    jlToggleManLights.setText("" + trainList.get(selectedId - 1).issetLightsOnUseManual);
    jlDoors.setText("" + ((trainList.get(selectedId - 1).issetDoorsOpen) ? "Open" : "Closed"));
    jlManDoors.setText(
        "" + ((trainList.get(selectedId - 1).issetDoorsOpenManual) ? "Open" : "Closed"));
    jlToggleManDoors.setText("" + trainList.get(selectedId - 1).issetDoorsOpenUseManual);
    jlCurTemperature.setText("" + trainList.get(selectedId - 1).curTemperature);
    jlTarTemperature.setText("" + trainList.get(selectedId - 1).targetTemperatureTNC);
    jlManTarTemperature.setText("" + trainList.get(selectedId - 1).targetTemperatureManual);
    jlToggleManTarTemperature.setText(
        "" + trainList.get(selectedId - 1).issetTargetTemperatureManual);
    jlAnnouncement.setText("" + trainList.get(selectedId - 1).announcement);

    jlLength.setText("" + trainList.get(selectedId - 1).length);
    jlWidth.setText("" + trainList.get(selectedId - 1).width);
    jlHeight.setText("" + trainList.get(selectedId - 1).height);
    jlNumCars.setText("" + trainList.get(selectedId - 1).numCars);
    jlMotorPower.setText("" + trainList.get(selectedId - 1).motorPower);
    jlMaxSpeed.setText("" + trainList.get(selectedId - 1).maxSpeed);
    jlServiceBrakeDecel.setText("" + trainList.get(selectedId - 1).serviceBrakeDecel);
    jlEmergencyBrakeDecel.setText("" + trainList.get(selectedId - 1).emerBrakeDecel);
    jlFrictionCoeff.setText("" + trainList.get(selectedId - 1).frictionCoeff);
    jlEmptyTrainMass.setText("" + trainList.get(selectedId - 1).emptyTrainMass);
    jlPersonMass.setText("" + trainList.get(selectedId - 1).personMass);
    jlMaxSeatedCount.setText("" + trainList.get(selectedId - 1).maxCapacitySeated);
    jlMaxStandingCount.setText("" + trainList.get(selectedId - 1).maxCapacityStanding);
    jlMaxCrewCount.setText("" + trainList.get(selectedId - 1).maxCapacityCrew);
  }
 /** Show/hide the main (dynamic) window. */
 public void setIsVisible(boolean isVisible) {
   this.isVisible = isVisible;
   dynamicWindow.setVisible(isVisible);
 }
 /** Show/hide the static window. */
 public void setIsVisibleStatic(boolean isVisibleStatic) {
   this.isVisibleStatic = isVisibleStatic;
   staticWindow.setVisible(isVisibleStatic);
 }
  /**
   * Create the train module GUI (the dynamic and static windows). Both windows are HIDE_ON_CLOSE so
   * that closing them does not cause the train module to close.
   */
  public TrainModelUI() {
    try {
      JPanel emptyJPanel = new JPanel();
      emptyJPanel.add(new JLabel("            "));
      isPaused = true;

      // Setup the dynamicWindow.

      btnShowStaticValues = buildJButton("Show Static Values");
      btnSelectTrain = buildJButton("Select Train");
      btnPauseResume = buildJButton("Pause");
      btnPauseResume.setEnabled(false);
      btnSetManRecPower = buildJButton("Set Manual Received Power");
      btnToggleManRecPower = buildJButton("Toggle Manual Received Power");
      btnSetManDesSpdLmt = buildJButton("Set Manual Desired Speed Limit");
      btnToggleManDesSpdLmt = buildJButton("Toggle Manual Desired Speed Limit");
      btnToggleSignalPickupFailure = buildJButton("Toggle Signal Pickup Failure");
      btnToggleEngineFailure = buildJButton("Toggle Engine Failure");
      btnToggleBrakeFailure = buildJButton("Toggle Brake Failure");
      btnToggleServiceBrake = buildJButton("Toggle Service Brake");
      btnToggleEmergencyBrake = buildJButton("Toggle Emergency Brake");
      btnSetManLights = buildJButton("Set Manual Lights Status");
      btnToggleManLights = buildJButton("Toggle Manual Lights Status");
      btnSetManDoors = buildJButton("Set Manual Doors Status");
      btnToggleManDoors = buildJButton("Toggle Manual Doors Status");
      btnSetManTarTemperature = buildJButton("Set Manual Target Temp.");
      btnToggleManTarTemperature = buildJButton("Toggle Manual Target Temp.");

      jlTime = new JLabel("XX:XX:XX", JLabel.CENTER);
      jlCurVel = new JLabel("", JLabel.CENTER);
      jlCurAccel = new JLabel("", JLabel.CENTER);
      jlRecPowerTNC = new JLabel("", JLabel.CENTER);
      jlManRecPower = new JLabel("", JLabel.CENTER);
      jlToggleManRecPower = new JLabel("", JLabel.CENTER);
      jlPostedSpdLmt = new JLabel("", JLabel.CENTER);
      jlManDesSpdLmt = new JLabel("", JLabel.CENTER);
      jlToggleManDesSpdLmt = new JLabel("", JLabel.CENTER);
      jlGrade = new JLabel("", JLabel.CENTER);
      jlTotalMass = new JLabel("", JLabel.CENTER);
      jlPassengerCount = new JLabel("", JLabel.CENTER);
      jlCrewCount = new JLabel("", JLabel.CENTER);
      jlPosition = new JLabel("", JLabel.CENTER);
      jlToggleSignalPickupFailure = new JLabel("", JLabel.CENTER);
      jlToggleEngineFailure = new JLabel("", JLabel.CENTER);
      jlToggleBrakeFailure = new JLabel("", JLabel.CENTER);
      jlToggleServiceBrake = new JLabel("", JLabel.CENTER);
      jlToggleEmergencyBrake = new JLabel("", JLabel.CENTER);
      jlLights = new JLabel("", JLabel.CENTER);
      jlManLights = new JLabel("", JLabel.CENTER);
      jlToggleManLights = new JLabel("", JLabel.CENTER);
      jlDoors = new JLabel("", JLabel.CENTER);
      jlManDoors = new JLabel("", JLabel.CENTER);
      jlToggleManDoors = new JLabel("", JLabel.CENTER);
      jlCurTemperature = new JLabel("", JLabel.CENTER);
      jlTarTemperature = new JLabel("", JLabel.CENTER);
      jlManTarTemperature = new JLabel("", JLabel.CENTER);
      jlToggleManTarTemperature = new JLabel("", JLabel.CENTER);
      jlAnnouncement = new JLabel("", JLabel.CENTER);

      JPanel dwPanel1 = new JPanel();
      dwPanel1.setLayout(new GridLayout(18, 2));
      dwPanel1.add(buildJPanel(new JLabel("Current Velocity (m/s)", JLabel.CENTER)));
      dwPanel1.add(buildJPanel(jlCurVel));
      dwPanel1.add(buildJPanel(new JLabel("Current Acceleration (m/s^2)", JLabel.CENTER)));
      dwPanel1.add(buildJPanel(jlCurAccel));
      dwPanel1.add(buildJPanel(new JLabel("Received Power from TNC (W)", JLabel.CENTER)));
      dwPanel1.add(buildJPanel(jlRecPowerTNC));
      dwPanel1.add(buildJPanel(btnSetManRecPower));
      dwPanel1.add(buildJPanel(jlManRecPower));
      dwPanel1.add(buildJPanel(btnToggleManRecPower));
      dwPanel1.add(buildJPanel(jlToggleManRecPower));
      dwPanel1.add(buildJPanel(new JLabel("Speed Limit Posted on Signs (m/s)", JLabel.CENTER)));
      dwPanel1.add(buildJPanel(jlPostedSpdLmt));
      dwPanel1.add(buildJPanel(btnSetManDesSpdLmt));
      dwPanel1.add(buildJPanel(jlManDesSpdLmt));
      dwPanel1.add(buildJPanel(btnToggleManDesSpdLmt));
      dwPanel1.add(buildJPanel(jlToggleManDesSpdLmt));
      dwPanel1.add(buildJPanel(new JLabel("Relative Grade from TKM (%)", JLabel.CENTER)));
      dwPanel1.add(buildJPanel(jlGrade));
      dwPanel1.add(
          buildJPanel(new JLabel("Total Mass (inc. passengers/crew) (kg)", JLabel.CENTER)));
      dwPanel1.add(buildJPanel(jlTotalMass));
      dwPanel1.add(buildJPanel(new JLabel("Passenger Count", JLabel.CENTER)));
      dwPanel1.add(buildJPanel(jlPassengerCount));
      dwPanel1.add(buildJPanel(new JLabel("Crew Count", JLabel.CENTER)));
      dwPanel1.add(buildJPanel(jlCrewCount));
      dwPanel1.add(
          buildJPanel(new JLabel("Position from Onboard GPS ([block], m)", JLabel.CENTER)));
      dwPanel1.add(buildJPanel(jlPosition));
      dwPanel1.add(buildJPanel(btnToggleSignalPickupFailure));
      dwPanel1.add(buildJPanel(jlToggleSignalPickupFailure));
      dwPanel1.add(buildJPanel(btnToggleEngineFailure));
      dwPanel1.add(buildJPanel(jlToggleEngineFailure));
      dwPanel1.add(buildJPanel(btnToggleBrakeFailure));
      dwPanel1.add(buildJPanel(jlToggleBrakeFailure));
      dwPanel1.add(buildJPanel(btnToggleServiceBrake));
      dwPanel1.add(buildJPanel(jlToggleServiceBrake));
      dwPanel1.add(buildJPanel(btnToggleEmergencyBrake));
      dwPanel1.add(buildJPanel(jlToggleEmergencyBrake));
      JPanel dwPanel2 = new JPanel();
      dwPanel2.setLayout(new GridLayout(18, 2));
      dwPanel2.add(buildJPanel(new JLabel("Lights Status", JLabel.CENTER)));
      dwPanel2.add(buildJPanel(jlLights));
      dwPanel2.add(buildJPanel(btnSetManLights));
      dwPanel2.add(buildJPanel(jlManLights));
      dwPanel2.add(buildJPanel(btnToggleManLights));
      dwPanel2.add(buildJPanel(jlToggleManLights));
      dwPanel2.add(buildJPanel(new JLabel("Doors Status", JLabel.CENTER)));
      dwPanel2.add(buildJPanel(jlDoors));
      dwPanel2.add(buildJPanel(btnSetManDoors));
      dwPanel2.add(buildJPanel(jlManDoors));
      dwPanel2.add(buildJPanel(btnToggleManDoors));
      dwPanel2.add(buildJPanel(jlToggleManDoors));
      dwPanel2.add(buildJPanel(new JLabel("Current Temp. (degrees F)", JLabel.CENTER)));
      dwPanel2.add(buildJPanel(jlCurTemperature));
      dwPanel2.add(buildJPanel(new JLabel("Target Temp. from TNC (degrees F)", JLabel.CENTER)));
      dwPanel2.add(buildJPanel(jlTarTemperature));
      dwPanel2.add(buildJPanel(btnSetManTarTemperature));
      dwPanel2.add(buildJPanel(jlManTarTemperature));
      dwPanel2.add(buildJPanel(btnToggleManTarTemperature));
      dwPanel2.add(buildJPanel(jlToggleManTarTemperature));
      dwPanel2.add(buildJPanel(new JLabel("Announcement", JLabel.CENTER)));
      dwPanel2.add(buildJPanel(jlAnnouncement));

      JPanel primaryButtons = new JPanel();
      primaryButtons.setLayout(new GridLayout(1, 4));
      primaryButtons.add(btnShowStaticValues);
      primaryButtons.add(btnSelectTrain);
      primaryButtons.add(btnPauseResume);
      primaryButtons.add(buildJPanel(jlTime));

      JPanel jp = new JPanel();
      jp.setLayout(new BoxLayout(jp, BoxLayout.Y_AXIS));
      jp.add(primaryButtons);
      jp.add(emptyJPanel);
      jp.add(new JSeparator(JSeparator.HORIZONTAL));
      jp.add(dwPanel1);
      jp.add(new JSeparator(JSeparator.HORIZONTAL));
      jp.add(dwPanel2);

      jp.setMaximumSize(new Dimension(400, 700));

      JScrollPane dScroll = new JScrollPane(jp);
      dScroll.setViewportView(jp);

      dynamicWindow = new JFrame();
      dynamicWindow.setTitle("Train Model (Chris Paskie)   -   UI   (Train ID:   --)");
      dynamicWindow.setSize(600, 400);
      dynamicWindow.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
      dynamicWindow.add(dScroll);
      isVisible = false;
      dynamicWindow.setVisible(isVisible);

      // Setup the staticWindow.

      jlLength = new JLabel("", JLabel.CENTER);
      jlWidth = new JLabel("", JLabel.CENTER);
      jlHeight = new JLabel("", JLabel.CENTER);
      jlNumCars = new JLabel("", JLabel.CENTER);
      jlMotorPower = new JLabel("", JLabel.CENTER);
      jlMaxSpeed = new JLabel("", JLabel.CENTER);
      jlServiceBrakeDecel = new JLabel("", JLabel.CENTER);
      jlEmergencyBrakeDecel = new JLabel("", JLabel.CENTER);
      jlFrictionCoeff = new JLabel("", JLabel.CENTER);
      jlEmptyTrainMass = new JLabel("", JLabel.CENTER);
      jlPersonMass = new JLabel("", JLabel.CENTER);
      jlMaxSeatedCount = new JLabel("", JLabel.CENTER);
      jlMaxStandingCount = new JLabel("", JLabel.CENTER);
      jlMaxCrewCount = new JLabel("", JLabel.CENTER);

      JPanel swPanel = new JPanel();
      swPanel.setLayout(new GridLayout(14, 2));
      swPanel.add(buildJPanel(new JLabel("Length (m)", JLabel.CENTER)));
      swPanel.add(buildJPanel(jlLength));
      swPanel.add(buildJPanel(new JLabel("Width (m)", JLabel.CENTER)));
      swPanel.add(buildJPanel(jlWidth));
      swPanel.add(buildJPanel(new JLabel("Height (m)", JLabel.CENTER)));
      swPanel.add(buildJPanel(jlHeight));
      swPanel.add(buildJPanel(new JLabel("Number of Cars", JLabel.CENTER)));
      swPanel.add(buildJPanel(jlNumCars));
      swPanel.add(buildJPanel(new JLabel("Motor Power (W)", JLabel.CENTER)));
      swPanel.add(buildJPanel(jlMotorPower));
      swPanel.add(buildJPanel(new JLabel("Maximum Speed (m/s)", JLabel.CENTER)));
      swPanel.add(buildJPanel(jlMaxSpeed));
      swPanel.add(buildJPanel(new JLabel("Service Brake Deceleration (m/s^2)", JLabel.CENTER)));
      swPanel.add(buildJPanel(jlServiceBrakeDecel));
      swPanel.add(buildJPanel(new JLabel("Emergency Brake Deceleration (m/s^2)", JLabel.CENTER)));
      swPanel.add(buildJPanel(jlEmergencyBrakeDecel));
      swPanel.add(buildJPanel(new JLabel("Coefficient of Friction", JLabel.CENTER)));
      swPanel.add(buildJPanel(jlFrictionCoeff));
      swPanel.add(
          buildJPanel(new JLabel("Train Mass (not inc. passengers/crew) (kg)", JLabel.CENTER)));
      swPanel.add(buildJPanel(jlEmptyTrainMass));
      swPanel.add(buildJPanel(new JLabel("Mass Per Passenger/Crew (kg)", JLabel.CENTER)));
      swPanel.add(buildJPanel(jlPersonMass));
      swPanel.add(buildJPanel(new JLabel("Maximum Seated Passenger Count", JLabel.CENTER)));
      swPanel.add(buildJPanel(jlMaxSeatedCount));
      swPanel.add(buildJPanel(new JLabel("Maximum Standing Passenger Count", JLabel.CENTER)));
      swPanel.add(buildJPanel(jlMaxStandingCount));
      swPanel.add(buildJPanel(new JLabel("Maximum Crew Count", JLabel.CENTER)));
      swPanel.add(buildJPanel(jlMaxCrewCount));

      staticWindow = new JFrame();
      staticWindow.setTitle("Train Model (Chris Paskie)   -   Static Values   (Train ID:   --)");
      staticWindow.setSize(700, 600);
      staticWindow.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
      staticWindow.add(swPanel);
      isVisibleStatic = false;
      staticWindow.setVisible(isVisibleStatic);

      // Set up the TNC UI.
      if (!isSolo) {
        tncUI = new TNC_UI();
      }

    } catch (Exception e) {
      e.printStackTrace(System.err);
      JOptionPane.showMessageDialog(null, e, "Error", JOptionPane.ERROR_MESSAGE);
    }
  }