/*
* $Id: Annote.java,v 1.8 2003/08/22 23:02:38 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.dm;
import java.io.Serializable;
import java.awt.Color;
import java.awt.Rectangle;
import java.beans.PropertyChangeSupport;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeEvent;
import sgtplot.CartesianGraph;
import sgtplot.Graph;
import sgtplot.LineAttribute;
import sgtplot.PointAttribute;
import sgtplot.SGLabel;
import sgtplot.util.GeoDate;
import sgtplot.util.GeoDateArray;
import sgtplot.util.Rectangle2D;
import sgtplot.util.SoTDomain;
import sgtplot.util.SoTPoint;
import sgtplot.util.SoTRange;
import sgtplot.util.SoTValue;
/**
* Abstract class for annotations.
* @author Donald Denbo
* @version $Revision: 1.8 $
* @since 3.0
*/
public abstract class Annote implements SGTData, Serializable, PropertyChangeListener {
protected transient PropertyChangeSupport changes_;
// serial version ref 1.7.2.5
private static final long serialVersionUID = 7305616377566581275L;
protected String id_ = null;
/**
* Class for line annotations.
* @author Donald Denbo
* @version $Revision: 1.8 $
* @since 3.0
*/
public static class Line extends Annote {
SGTLine line;
LineAttribute attr;
public Line(String id, SGTLine line, LineAttribute attr) {
id_ = id;
this.line = line;
this.attr = attr;
init();
}
public void init() {
if(attr != null) attr.addPropertyChangeListener(this);
changes_ = new PropertyChangeSupport(this);
}
public SGTLine getLine() {
return line;
}
public LineAttribute getAttribute() {
return attr;
}
public SoTDomain getDomain() {
return new SoTDomain(line.getXRange(), line.getYRange());
}
public Rectangle getBounds(Graph graph) {
return computeBounds(graph, this.getDomain());
}
public void moveBy(SoTPoint point) {
double[] xu = null;
double[] yu = null;
long[] tu = null;
double delta;
long tdelta;
if(!(line instanceof SimpleLine)) return;
if(line.isXTime()) {
tu = line.getGeoDateArray().getTime();
tdelta = point.getX().getLongTime();
for(int i=0; i < tu.length; i++) {
tu[i] += tdelta;
}
((SimpleLine)line).setTimeArray(new GeoDateArray(tu));
} else {
xu = line.getXArray();
delta = ((Number)point.getX().getObjectValue()).doubleValue();
for(int i=0; i < xu.length; i++) {
xu[i] += delta;
}
((SimpleLine)line).setXArray(xu);
}
if(line.isYTime()) {
tu = line.getGeoDateArray().getTime();
tdelta = point.getY().getLongTime();
for(int i=0; i < tu.length; i++) {
tu[i] += tdelta;
}
((SimpleLine)line).setTimeArray(new GeoDateArray(tu));
} else {
yu = line.getYArray();
delta = ((Number)point.getY().getObjectValue()).doubleValue();
for(int i=0; i < yu.length; i++) {
yu[i] += delta;
}
((SimpleLine)line).setYArray(yu);
}
changes_.firePropertyChange("lineMoved", true, false);
}
public void setXArray(double[] xa) {
}
public void setYArray(double[] ya) {
}
public void setTimeArray(GeoDateArray gda) {
}
public void propertyChange(PropertyChangeEvent evt) {
changes_.firePropertyChange(evt);
}
/* SGTData required methods */
public SGTData copy() {
SGTData copy = null;
try {
copy = (SGTData)this.clone();
} catch (CloneNotSupportedException ex) {
ex.printStackTrace();
}
return copy;
}
public String getId() {
return line.getId();
}
public SGLabel getKeyTitle() {
return line.getKeyTitle();
}
public String getTitle() {
return line.getTitle();
}
public SGTMetaData getXMetaData() {
return line.getXMetaData();
}
public SoTRange getXRange() {
return line.getXRange();
}
public SGTMetaData getYMetaData() {
return line.getYMetaData();
}
public SoTRange getYRange() {
return line.getYRange();
}
public boolean isXTime() {
return line.isXTime();
}
public boolean isYTime() {
return line.isYTime();
}
}
/**
* Class for point annotations.
* @author Donald Denbo
* @version $Revision: 1.8 $
* @since 3.0
*/
public static class Point extends Annote {
SGTPoint point;
PointAttribute attr;
public Point(String id, SGTPoint point, PointAttribute attr) {
id_ = id;
this.point = point;
this.attr = attr;
init();
}
public void init() {
if(attr != null) attr.addPropertyChangeListener(this);
changes_ = new PropertyChangeSupport(this);
}
public SGTPoint getPoint() {
return point;
}
public PointAttribute getAttribute() {
return attr;
}
public SoTDomain getDomain() {
return new SoTDomain(point.getXRange(), point.getYRange());
}
public Rectangle getBounds(Graph graph) {
/** @todo add text bounds */
Rectangle rect = computeBounds(graph, this.getDomain());
double hgt = attr.getMarkHeightP();
int ihgt = graph.getLayer().getXPtoD(hgt);
rect.setBounds(rect.x-ihgt/2,
rect.y-ihgt/2,
ihgt, ihgt);
return rect;
}
public void moveBy(SoTPoint pnt) {
double xu = 0.0;
double yu = 0.0;
long tu = 0;
double delta;
long tdelta;
if(!(point instanceof SimplePoint)) return;
if(point.isXTime()) {
tu = point.getLongTime();
tdelta = pnt.getX().getLongTime();
tu += tdelta;
((SimplePoint)point).setTime(tu);
} else {
xu = point.getX();
delta = ((Number)pnt.getX().getObjectValue()).doubleValue();
xu += delta;
((SimplePoint)point).setX(xu);
}
if(point.isYTime()) {
tu = point.getLongTime();
tdelta = pnt.getY().getLongTime();
tu += tdelta;
((SimplePoint)point).setTime(tu);
} else {
yu = point.getY();
delta = ((Number)pnt.getY().getObjectValue()).doubleValue();
yu += delta;
((SimplePoint)point).setY(yu);
}
changes_.firePropertyChange("pointMoved", true, false);
}
public void propertyChange(PropertyChangeEvent evt) {
changes_.firePropertyChange(evt);
}
/* SGTData required methods */
public SGTData copy() {
SGTData copy = null;
try {
copy = (SGTData)this.clone();
} catch (CloneNotSupportedException ex) {
ex.printStackTrace();
}
return copy;
}
public String getId() {
return point.getId();
}
public SGLabel getKeyTitle() {
return point.getKeyTitle();
}
public String getTitle() {
return point.getTitle();
}
public SGTMetaData getXMetaData() {
return point.getXMetaData();
}
public SoTRange getXRange() {
return point.getXRange();
}
public SGTMetaData getYMetaData() {
return point.getYMetaData();
}
public SoTRange getYRange() {
return point.getYRange();
}
public boolean isXTime() {
return point.isXTime();
}
public boolean isYTime() {
return point.isYTime();
}
}
/**
* Class for text annotations.
* @author Donald Denbo
* @version $Revision: 1.8 $
* @since 3.0
*/
public static class Text extends Annote {
SoTPoint location;
SGLabel text;
public Text(String id, SoTPoint location, SGLabel text) {
id_ = id;
this.location = location;
this.text = text;
init();
}
public void init() {
if(text != null) text.addPropertyChangeListener(this);
changes_ = new PropertyChangeSupport(this);
}
public SoTPoint getLocation() {
return location;
}
public SGLabel getText() {
return text;
}
public SoTDomain getDomain() {
return null;
}
private SoTDomain getDomain(Graph graph) {
CartesianGraph cg = (CartesianGraph)graph;
SoTRange xRange = null;
SoTRange yRange = null;
Rectangle2D.Double bnds = text.getBoundsP();
/** @todo rewrite to go directly to device units */
double xloc = cg.getXUtoP(location.getX());
double yloc = cg.getYUtoP(location.getY());
double width = bnds.width;
double height = bnds.height;
if(location.isXTime()) {
long min = cg.getXPtoLongTime(xloc);
long max = cg.getXPtoLongTime(xloc + width);
xRange = new SoTRange.Time(min, max);
} else {
double min = cg.getXPtoU(xloc);
double max = cg.getXPtoU(xloc + width);
xRange = new SoTRange.Double(min, max);
}
if(location.isYTime()) {
long min = cg.getYPtoLongTime(yloc);
long max = cg.getYPtoLongTime(yloc + height);
yRange = new SoTRange.Time(min, max);
} else {
double min = cg.getYPtoU(yloc);
double max = cg.getYPtoU(yloc + height);
yRange = new SoTRange.Double(min, max);
}
return new SoTDomain(xRange, yRange);
}
public Rectangle getBounds(Graph graph) {
return computeBounds(graph, this.getDomain(graph));
}
public void moveBy(SoTPoint point) {
location.add(point);
changes_.firePropertyChange("textMoved", true, false);
}
public void propertyChange(PropertyChangeEvent evt) {
changes_.firePropertyChange(evt);
}
/* SGTData required methods */
public SGTData copy() {
SGTData copy = null;
try {
copy = (SGTData)this.clone();
} catch (CloneNotSupportedException ex) {
ex.printStackTrace();
}
return copy;
}
public String getId() {
return text.getId();
}
public SGLabel getKeyTitle() {
return null;
}
public String getTitle() {
return null;
}
public SGTMetaData getXMetaData() {
return null;
}
public SoTRange getXRange() {
return null;
}
public SGTMetaData getYMetaData() {
return null;
}
public SoTRange getYRange() {
return null;
}
public boolean isXTime() {
return location.isXTime();
}
public boolean isYTime() {
return location.isYTime();
}
}
/**
* Class for oval annotations.
* @author Donald Denbo
* @version $Revision: 1.8 $
* @since 3.0
*/
public static class Oval extends Annote {
SoTPoint upperLeft;
SoTPoint lowerRight;
LineAttribute attr;
Color color;
SoTRange xRange_ = null;
SoTRange yRange_ = null;
public Oval(String id, SoTPoint upperLeft, SoTPoint lowerRight,
LineAttribute attr, Color color) {
id_ = id;
this.upperLeft = upperLeft;
this.lowerRight = lowerRight;
this.attr = attr;
this.color = color;
init();
computeRange();
}
public void init() {
if(attr != null) attr.addPropertyChangeListener(this);
changes_ = new PropertyChangeSupport(this);
}
public SoTPoint getUpperLeft() {
return upperLeft;
}
public void setUpperLeft(SoTPoint ul) {
upperLeft = ul;
computeRange();
changes_.firePropertyChange("ovalMoved", true, false);
}
public SoTPoint getLowerRight() {
return lowerRight;
}
public void setLowerRight(SoTPoint lr) {
lowerRight = lr;
computeRange();
changes_.firePropertyChange("ovalMoved", true, false);
}
public void setLocation(SoTPoint ul, SoTPoint lr) {
upperLeft = ul;
lowerRight = lr;
computeRange();
changes_.firePropertyChange("ovalMoved", true, false);
}
public LineAttribute getLineAttribute() {
return attr;
}
public Color getFillColor() {
return color;
}
public void setFillColor(Color color) {
this.color = color;
changes_.firePropertyChange("colorChanged", true, false);
}
public SoTDomain getDomain() {
return new SoTDomain(xRange_, yRange_);
}
public Rectangle getBounds(Graph graph) {
return computeBounds(graph, this.getDomain());
}
public void moveBy(SoTPoint point) {
upperLeft.add(point);
lowerRight.add(point);
computeRange();
changes_.firePropertyChange("ovalMoved", true, false);
}
private void computeRange() {
if(upperLeft.getX().isTime()) {
xRange_ = new SoTRange.Time(upperLeft.getX().getLongTime(),
lowerRight.getX().getLongTime());
} else {
double xmin = ((Number)upperLeft.getX().getObjectValue()).doubleValue();
double xmax = ((Number)lowerRight.getX().getObjectValue()).doubleValue();
xRange_ = new SoTRange.Double(xmin, xmax);
}
if(upperLeft.getY().isTime()) {
yRange_ = new SoTRange.Time(lowerRight.getY().getLongTime(),
upperLeft.getY().getLongTime());
} else {
double ymin = ((Number)lowerRight.getY().getObjectValue()).doubleValue();
double ymax = ((Number)upperLeft.getY().getObjectValue()).doubleValue();
yRange_ = new SoTRange.Double(ymin, ymax);
}
}
public void propertyChange(PropertyChangeEvent evt) {
changes_.firePropertyChange(evt);
}
/* SGTData required methods */
public SGTData copy() {
SGTData copy = null;
try {
copy = (SGTData)this.clone();
} catch (CloneNotSupportedException ex) {
ex.printStackTrace();
}
return copy;
}
public String getId() {
return null;
}
public SGLabel getKeyTitle() {
return null;
}
public String getTitle() {
return null;
}
public SGTMetaData getXMetaData() {
return null;
}
public SoTRange getXRange() {
return xRange_;
}
public SGTMetaData getYMetaData() {
return null;
}
public SoTRange getYRange() {
return yRange_;
}
public boolean isXTime() {
return upperLeft.isXTime();
}
public boolean isYTime() {
return upperLeft.isYTime();
}
}
/**
* Class for rectangle annotations.
* @author Donald Denbo
* @version $Revision: 1.8 $
* @since 3.0
*/
public static class Rect extends Annote {
SoTPoint upperLeft;
SoTPoint lowerRight;
LineAttribute attr;
Color color;
SoTRange xRange_ = null;
SoTRange yRange_ = null;
public Rect(String id, SoTPoint upperLeft, SoTPoint lowerRight,
LineAttribute attr, Color color) {
id_ = id;
this.upperLeft = upperLeft;
this.lowerRight = lowerRight;
this.attr = attr;
this.color = color;
init();
computeRange();
}
public void init() {
if(attr != null) attr.addPropertyChangeListener(this);
changes_ = new PropertyChangeSupport(this);
}
public SoTPoint getUpperLeft() {
return upperLeft;
}
public void setUpperLeft(SoTPoint ul) {
upperLeft = ul;
computeRange();
changes_.firePropertyChange("rectMoved", true, false);
}
public SoTPoint getLowerRight() {
return lowerRight;
}
public void setLowerRight(SoTPoint lr) {
lowerRight = lr;
computeRange();
changes_.firePropertyChange("rectMoved", true, false);
}
public void setLocation(SoTPoint ul, SoTPoint lr) {
upperLeft = ul;
lowerRight = lr;
computeRange();
changes_.firePropertyChange("rectMoved", true, false);
}
public LineAttribute getLineAttribute() {
return attr;
}
public Color getFillColor() {
return color;
}
public void setFillColor(Color color) {
this.color = color;
changes_.firePropertyChange("colorChanged", true, false);
}
public SoTDomain getDomain() {
return new SoTDomain(xRange_, yRange_);
}
public Rectangle getBounds(Graph graph) {
return computeBounds(graph, this.getDomain());
}
public void moveBy(SoTPoint point) {
upperLeft.add(point);
lowerRight.add(point);
computeRange();
changes_.firePropertyChange("rectMoved", true, false);
}
private void computeRange() {
if(upperLeft.getX().isTime()) {
xRange_ = new SoTRange.Time(upperLeft.getX().getLongTime(),
lowerRight.getX().getLongTime());
} else {
double xmin = ((Number)upperLeft.getX().getObjectValue()).doubleValue();
double xmax = ((Number)lowerRight.getX().getObjectValue()).doubleValue();
xRange_ = new SoTRange.Double(xmin, xmax);
}
if(upperLeft.getY().isTime()) {
yRange_ = new SoTRange.Time(lowerRight.getY().getLongTime(),
upperLeft.getY().getLongTime());
} else {
double ymin = ((Number)lowerRight.getY().getObjectValue()).doubleValue();
double ymax = ((Number)upperLeft.getY().getObjectValue()).doubleValue();
yRange_ = new SoTRange.Double(ymin, ymax);
}
}
public void propertyChange(PropertyChangeEvent evt) {
changes_.firePropertyChange(evt);
}
/* SGTData required methods */
public SGTData copy() {
SGTData copy = null;
try {
copy = (SGTData)this.clone();
} catch (CloneNotSupportedException ex) {
ex.printStackTrace();
}
return copy;
}
public String getId() {
return null;
}
public SGLabel getKeyTitle() {
return null;
}
public String getTitle() {
return null;
}
public SGTMetaData getXMetaData() {
return null;
}
public SoTRange getXRange() {
return xRange_;
}
public SGTMetaData getYMetaData() {
return null;
}
public SoTRange getYRange() {
return yRange_;
}
public boolean isXTime() {
return upperLeft.isXTime();
}
public boolean isYTime() {
return upperLeft.isYTime();
}
}
protected Annote() {
}
protected Rectangle computeBounds(Graph graph, SoTDomain domain) {
Rectangle rect = null;
if(domain == null || !(graph instanceof CartesianGraph)) return rect;
CartesianGraph cg = (CartesianGraph)graph;
int xd, yd;
int width, height;
int xd1 = cg.getXUtoD(domain.getXRange().getStart());
int yd1 = cg.getYUtoD(domain.getYRange().getStart());
int xd2 = cg.getXUtoD(domain.getXRange().getEnd());
int yd2 = cg.getYUtoD(domain.getYRange().getEnd());
if(xd1 < xd2) {
xd = xd1;
width = xd2 - xd1;
} else {
xd = xd2;
width = xd1 - xd2;
}
if(yd1 < yd2) {
yd = yd1;
height = yd2 - yd1;
} else {
yd = yd2;
height = yd1 - yd2;
}
rect = new Rectangle(xd, yd, width, height);
return rect;
}
public abstract Rectangle getBounds(Graph graph);
public abstract SoTDomain getDomain();
public abstract void moveBy(SoTPoint point);
public abstract void propertyChange(PropertyChangeEvent evt);
public String getAnnoteId() {
return id_;
}
/**
* Init method used to setup serialized object.
*/
public abstract void init();
/* SGTData required methods */
public void addPropertyChangeListener(PropertyChangeListener l) {
if(changes_ == null) changes_ = new PropertyChangeSupport(this);
changes_.addPropertyChangeListener(l);
}
public void removePropertyChangeListener(PropertyChangeListener l) {
if(changes_ == null) changes_ = new PropertyChangeSupport(this);
changes_.removePropertyChangeListener(l);
}
}
Ads help maintain this website.