/**
   * Constructs from nothing.
   *
   * @throws VisADException if a VisAD failure occurs.
   * @throws RemoteException if a Java RMI failure occurs.
   */
  public GriddedSoundingControl() throws VisADException, RemoteException {

    super(false);
    gridLocs = new LineDrawing("GriddedSoundingControl gridLocs");
    probe = new LineProbe();
    probe.setVisible(true);
    setSounding(0);
  }
  /**
   * Sets the horizontal position of the probe. This method is used by the persistance mechanism.
   *
   * @param p The horizontal position of the probe.
   * @throws VisADException if <code>p.getType()</code> isn't {@link
   *     visad.RealTupleType#SpatialCartesian2DTuple} or if another VisAD failure occurs.
   * @throws RemoteException if a Java RMI failure occurs.
   */
  public void setPosition(RealTuple p) throws VisADException, RemoteException {

    /*
     * The following fires a PropertyChangeEvent for the probe
     * position.
     */
    probe.setPosition(p);
  }
 /** Reset the position of the probe to the center. */
 private void resetProbePosition() {
   try {
     if (probe != null) {
       probe.setPosition(0.0, 0.0);
     }
   } catch (Exception exc) {
     logException("Resetting probe position", exc);
   }
 }
  /**
   * Constructs the vertical profile display and control buttons
   *
   * @param dataChoice The data for this instance.
   * @return <code>true</code> if and only if this instance was correctly initialized.
   * @throws VisADException couldn't create a VisAD object needed
   * @throws RemoteException couldn't create a remote object needed
   */
  public boolean init(DataChoice dataChoice) throws VisADException, RemoteException {

    /*
     * Initialize the superclass.
     */
    if (!super.init()) {
      return false;
    }
    setSpatialLoci(gridLocs);

    if (!setData(dataChoice)) {
      return false;
    }

    /*
     * Add the listener here (as opposed to in the contructor) so we
     * don't get spurious events before we are fully initialized
     */
    probe.addPropertyChangeListener(
        SelectorDisplayable.PROPERTY_POSITION,
        new PropertyChangeListener() {

          public void propertyChange(PropertyChangeEvent evt) {
            if (getActive() && getHaveInitialized()) {
              lineProbeWasMoved();
            }
          }
        });
    probe.setPointSize(getDisplayScale());
    probe.setAutoSize(true);
    addDisplayable(probe, FLAG_COLOR);
    addDisplayable(gridLocs, FLAG_COLOR);

    dataNode = SoundingDataNode.getInstance(new Listener());

    dataNode.setData(getData(getDataInstance()));

    return true;
  }
  /**
   * Receive shared-data updates.
   *
   * @param from The {@link ucar.unidata.collab.Sharable} object from which this event originates.
   * @param dataId The shared data identifier.
   * @param data The shared data.
   */
  public void receiveShareData(Sharable from, Object dataId, Object[] data) {

    if (!(dataId.equals(SHARE_POSITION))) {
      super.receiveShareData(from, dataId, data); // pass it up
    } else {
      if (probe == null) {
        return;
      }

      try {

        /*
         * The following fires a PropertyChangeEvent for the
         * probe position.
         */
        probe.setPosition((RealTuple) data[0]);
      } catch (Exception ex) {
        logException("receiveShareData:" + dataId, ex);
      }
    }
  }
  /**
   * Returns the horizontal position of the probe or <code>null</code> if the probe's position is
   * indeterminate.
   *
   * @return The horizontal probe position or <code>null </code>. The {@link visad.MathType} of a
   *     non-<code>null</code> returned object is {@link
   *     visad.RealTupleType#SpatialCartesian2DTuple}.
   * @throws VisADException if a VisAD failure occurs.
   * @throws RemoteException if a Java RMI failure occurs.
   */
  public RealTuple getPosition() throws VisADException, RemoteException {

    return ((probe != null) ? probe.getPosition() : null);
  }