/*
 * $Id: ContourLevels.java,v 1.20 2002/02/25 19:01:11 dwd Exp $
 *
 * This software is provided by NOAA for full, free and open release.  It is
 * understood by the recipient/user that NOAA assumes no liability for any
 * errors contained in the code.  Although this software is released without
 * conditions or restrictions in its use, it is expected that appropriate
 * credit be given to its author and to the National Oceanic and Atmospheric
 * Administration should the software be included by the recipient as an
 * element in other product development.
 */

package  sgtplot;


import java.util.Vector;
import java.util.Hashtable;
import java.util.Enumeration;
import java.awt.Color;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;

import sgtplot.util.Range2D;

/**
 * Contains levels and line styles for contour graphics.
 *
 * @author Donald Denbo
 * @version $Revision: 1.20 $, $Date: 2002/02/25 19:01:11 $
 * @since 2.0
 */
public class ContourLevels implements Cloneable {
  /**
   * @label defaultAttr
   * @link aggregationByValue
   * @supplierCardinality 1
   */
  private DefaultContourLineAttribute defaultAttr_ =
    new DefaultContourLineAttribute();
  private Vector levels_ = new Vector();
  private Hashtable lineAttrMap_ = new Hashtable();
  private boolean sorted_ = false;
  /**
   * @label solid
   * @link aggregationByValue
   */
  static private ContourLineAttribute solid_ =
    new ContourLineAttribute(ContourLineAttribute.SOLID);

  /**
   * @label heavy
   * @link aggregationByValue
   */
  static private ContourLineAttribute heavy_ =
    new ContourLineAttribute(ContourLineAttribute.HEAVY);

  /**
   * @label dashed
   * @link aggregationByValue
   */
  static private ContourLineAttribute dashed_ =
    new ContourLineAttribute(ContourLineAttribute.DASHED);

  private PropertyChangeSupport changes_ =
    new PropertyChangeSupport(this);

  /**
   * @directed
   * @label lineAttrMap
   * @link aggregation
   * @supplierCardinality 1..*
   */
  private ContourLineAttribute lnkLineAttribute;
  /**
   * Construct a default ContourLevels object from a double[].
   */
  static public ContourLevels getDefault(double[] array) {
    ContourLevels cl = new ContourLevels();
    double val = 0.0;
    for(int i=0; i < array.length; i++) {
      cl.addLevel(array[i]);
    }
    return cl;
  }
  /**
   * Construct a default ContourLevels object from a
   * Range2D.
   */
  static public ContourLevels getDefault(Range2D range) {
    ContourLevels cl = new ContourLevels();
    double val = range.start;
    while(val <= range.end) {
      cl.addLevel(val);
      val = val + range.delta;
    }
    return cl;
  }
  /**
   * Create a deep copy.
   */
  public ContourLevels copy() {
    ContourLevels newcls;
    try {
      newcls = (ContourLevels)clone();
      //      newcls.defaultAttr_ =
      //	(DefaultContourLineAttribute)this.defaultAttr_.copy();
      newcls.levels_ = (Vector)this.levels_.clone();
      newcls.lineAttrMap_ = (Hashtable)this.lineAttrMap_.clone();
    } catch (CloneNotSupportedException e) {
      newcls = null;
    }
    return newcls;
  }
  /**
   * Get the contour level elements.
   */
  public Enumeration levelElements() {
    if(!sorted_) sort();
    return levels_.elements();
  }
  /**
   * Set a the ContourLineAttribute for a value.
   */
  public void setContourLineAttribute(double val, ContourLineAttribute l)
    throws ContourLevelNotFoundException  {
    throw new MethodNotImplementedError();
  }
  /**
   * Set a the ContourLineAttribute for an index.
   */
  public void setContourLineAttribute(int indx, ContourLineAttribute l)
    throws ContourLevelNotFoundException  {
    throw new MethodNotImplementedError();
  }
  /**
   * Get the ContourLineAttribute for a value.
   */
  public ContourLineAttribute getContourLineAttribute(double val)
    throws ContourLevelNotFoundException  {
    ContourLineAttribute attr =
      (ContourLineAttribute)lineAttrMap_.get(new Double(val));
    if(attr == null) {
      throw new ContourLevelNotFoundException();
    }
    return attr;
  }
  /**
   * Get the ContourLineAttribute for an index.
   */
  public ContourLineAttribute getContourLineAttribute(int indx)
    throws ContourLevelNotFoundException  {
    if(!sorted_) sort();
    return getContourLineAttribute(getLevel(indx));
  }
  /**
   * Get the DefaultContourLineAtrribute
   */
  public DefaultContourLineAttribute getDefaultContourLineAttribute() {
    return defaultAttr_;
  }
  /**
   * Get the DefaultContourLineAttribute for index.
   */
  public DefaultContourLineAttribute getDefaultContourLineAttribute(int indx)
    throws ContourLevelNotFoundException {
    if(!sorted_) sort();
    return
      defaultAttr_.setContourLineAttribute(getContourLineAttribute(getLevel(indx)));
  }
  /**
   * Get the DefaultContourLineAttribute for value.
   */
  public DefaultContourLineAttribute getDefaultContourLineAttribute(double val)
    throws ContourLevelNotFoundException {
    if(!sorted_) sort();
    return
      defaultAttr_.setContourLineAttribute(getContourLineAttribute(val));
  }
  /**
   * Set the DefaultContourLineAttribute
   */
  public void setDefaultContourLineAttribute(DefaultContourLineAttribute attr) {
    defaultAttr_ = attr;
  }
  /**
   * Add a contour level with default ContourLineAttribute.
   */
  public void addLevel(double val) {
    ContourLineAttribute attr = null;
    if(val < 0.0) {
      attr = (ContourLineAttribute)dashed_.copy();
    } else if (val > 0.0) {
      attr = (ContourLineAttribute)solid_.copy();
    } else {
      attr = (ContourLineAttribute)heavy_.copy();
     }
    attr.setStyleOverridden(true);
    addLevel(val, attr);
  }
  /**
   * Add a contour level with a specified
   * ContourLineAttribute.
   */
  public void addLevel(double val, ContourLineAttribute l) {
    Double value = new Double(val);
    levels_.addElement(value);
    lineAttrMap_.put(value, l);
    sorted_ = false;
  }
  /**
   * Get the value of level by index.
   */
  public double getLevel(int indx)
    throws ContourLevelNotFoundException  {
    if(indx < 0 || indx >= levels_.size())
      throw new ContourLevelNotFoundException();
    if(!sorted_) sort();
    Double value = (Double)levels_.elementAt(indx);
    return value.doubleValue();
  }
  /**
   * Remove a level by value.
   */
  public void removeLevel(double val)
    throws ContourLevelNotFoundException  {
    throw new MethodNotImplementedError();
  }
  /**
   * Remove a level by index.
   */
  public void removeLevel(int indx)
    throws ContourLevelNotFoundException  {
    throw new MethodNotImplementedError();
  }
  /**
   * Get the index of a level by value
   */
  public int getIndex(Double dval) {
    if(!sorted_) sort();
    return levels_.indexOf(dval);
  }
  /**
   * Get the index of a level by value
   */
  public int getIndex(double val) {
    if(!sorted_) sort();
    return getIndex(new Double(val));
  }
  /**
   * Get the maximum level index.
   */
  public int getMaximumIndex() {
    return levels_.size() - 1;
  }
  /**
   * Get the range of levels
   */
  public Range2D getRange() {
    double min = Double.MAX_VALUE;
    double max = Double.MIN_VALUE;
    double value;
    for(int i=0; i < levels_.size(); i++) {
      value = ((Double)levels_.get(i)).doubleValue();
      min = Math.min(min, value);
      max = Math.max(max, value);
    }
    return new Range2D(min, max);
  }
  /**
   * Get the number of levels.
   */
  public int size() {
    return levels_.size();
  }

  private void sort() {
    //
    // use brain-dead bubble sort (there will be few lines)
    //
    int i, temp;
    int size = levels_.size();
    Double a, b;
    int[] index = new int[size];
    boolean flipped = true;
    for(i=0; i < size; i++) {
      index[i] = i;
    }
    while(flipped) {
      flipped = false;
      for(i=0; i < size-1; i++) {
        a = (Double)levels_.elementAt(index[i]);
        b = (Double)levels_.elementAt(index[i+1]);
        if(a.doubleValue() > b.doubleValue()) {
          //	  if(a.compareTo(b) > 0) { // jdk1.2
          temp = index[i];
          index[i] = index[i+1];
          index[i+1] = temp;
          flipped = true;
        }
      }
    }
    Vector oldValues = levels_;
    levels_ = new Vector(size);
    for(i=0; i < size; i++) {
      levels_.addElement(oldValues.elementAt(index[i]));
    }
    sorted_ = true;
  }

  /**
   * Add listener to changes in ColorMap properties.
   */
  public void addPropertyChangeListener(PropertyChangeListener listener) {
    changes_.addPropertyChangeListener(listener);
  }
  public void removePropertyChangeListener(PropertyChangeListener listener) {
    changes_.removePropertyChangeListener(listener);
  }
}


 

Ads help maintain this website.