public void propertyChange(PropertyChangeEvent pce) {
   Object source = pce.getSource();
   if (source == posSlider_x) {
     double posX = ((Double) pce.getNewValue()).doubleValue();
     posDisk.x = posX;
     Disk.setNode3D(ShapeNodeDisk);
     Disk.setPosition(posDisk);
     PlaceBNVectors();
   } else if (source == posSlider_y) {
     double posY = ((Double) pce.getNewValue()).doubleValue();
     posDisk.y = posY;
     Disk.setNode3D(ShapeNodeDisk);
     Disk.setPosition(posDisk);
     PlaceBNVectors();
   } else if (source == angDisk) {
     angleDisk = ((Double) pce.getNewValue()).doubleValue();
     double angDisk_rad = angleDisk * Math.PI / 180.;
     double compx = Math.cos(angDisk_rad);
     double compy = Math.sin(angDisk_rad);
     Disk.setNode3D(ShapeNodeDisk);
     Disk.setDirection(new Vector3d(compx, compy, 0.));
     flux_plot.setNormalDisk(new Vector3d(compx, compy, 0.));
     PlaceBNVectors();
   } else if (source == radDisk) {
     radiusDisk = ((Double) pce.getNewValue()).doubleValue();
     ShapeNodeDisk.setGeometry(Cylinder.makeGeometry(32, radiusDisk, heightDisk));
     Disk.setNode3D(ShapeNodeDisk);
     arrowScale = arrowScaleInitial * radiusDisk / radiusDiskInitial;
     flux_plot.setRadiusDisk(radiusDisk);
     PlaceBNVectors();
   } else {
     super.propertyChange(pce);
   }
 }
  /** Method to place the magnetic field vectors and normals on the disk. */
  public void PlaceBNVectors() {
    // first place the vectors on the top of the cylinder
    Vector3d normalTop = null;
    Vector3d centerTop = new Vector3d(0, 0, 0);
    double compx = Math.cos(angleDisk * Math.PI / 180.);
    double compy = Math.sin(angleDisk * Math.PI / 180.);
    normalTop = new Vector3d(compx, compy, 0.);
    normalTop.scale(heightDisk / 2.);
    centerTop.add(normalTop);
    centerTop.add(posDisk);

    for (int j = 0; j < numRadDisk; j++) {
      double rad = (j + 1) * radiusDisk / (numRadDisk + 1);
      for (int i = 0; i < numAziTopDisk; i++) {
        double aziangle = i * 2. * Math.PI / (numAziTopDisk * 1.);
        Vector3d azipos = new Vector3d(0., Math.cos(aziangle), Math.sin(aziangle));
        Vector3d aziposTrans = new Vector3d(0, 0, 0);
        Vector3d azidirTrans = new Vector3d(1, 0, 0);
        Vector3d azidir = new Vector3d(1., 0., 0.);
        azipos.scale(rad);
        aziposTrans.x = azipos.x * compx - azipos.y * compy;
        aziposTrans.y = azipos.x * compy + azipos.y * compx;
        aziposTrans.z = azipos.z;
        azidirTrans.x = azidir.x * compx - azidir.y * compy;
        azidirTrans.y = azidir.x * compy + azidir.y * compx;
        azidirTrans.z = azidir.z;
        aziposTrans.add(centerTop);
        theFieldDiskTop[i][j].setPosition(aziposTrans);
        theFieldDiskTop[i][j].setScale(arrowScale);
        theNormalDiskTop[i][j].setPosition(aziposTrans);
        theNormalDiskTop[i][j].setValue(azidirTrans);
        theNormalDiskTop[i][j].setDrawn(true);
        theNormalDiskTop[i][j].setScale(arrowScale);
        // here we make the field vector tip be at the location of the arrow if the arrow points
        // inward at the local normal

        if (theEngine != null) theEngine.requestSpatial();
      }
    }
  }