/*
* $Id: ValueIcon.java,v 1.19 2003/08/22 23:02:39 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.swing;
import javax.swing.ImageIcon;
import sgtplot.AbstractPane;
import sgtplot.CartesianGraph;
import sgtplot.Layer;
import sgtplot.LayerChild;
import sgtplot.util.Debug;
import sgtplot.util.Point2D;
import sgtplot.util.SoTPoint;
import java.awt.Rectangle;
import java.awt.Point;
import java.awt.Image;
import java.net.URL;
import java.awt.Graphics;
import java.awt.Component;
import java.awt.Font;
import java.awt.Color;
import java.awt.FontMetrics;
import java.beans.PropertyChangeSupport;
import java.beans.PropertyChangeListener;
import java.beans.PropertyVetoException;
import java.beans.VetoableChangeSupport;
import java.beans.VetoableChangeListener;
import org.freehep.graphics2d.VectorGraphics;
/**
* ValueIcon extends ImageIcon to create a
* icon than can be dragged on a sgtplot plot displaying the
* local coordinates along with the image. Typically a cross-hairs
* image is used, but others can be substituted.
*
* @author Donald Denbo
* @version $Revision: 1.19 $, $Date: 2003/08/22 23:02:39 $
* @since 2.0
* @see UserIcon
* @see ValueIconFormat
*/
public class ValueIcon extends ImageIcon implements LayerChild, Draggable {
private int iWidth_ = 0;
private int iHeight_ = 0;
private boolean selected_ = false;
private boolean selectable_ = true;
private boolean moved_ = false;
private Layer layer_ = null;
private String id_ = null;
private boolean visible_ = true;
private Rectangle bounds_ = new Rectangle();
private Point2D.Double loc_ = new Point2D.Double();
private SoTPoint uLoc_ = new SoTPoint(0.0, 0.0);
private Font font_ = new Font("Dialog", Font.PLAIN, 12);
private Color textColor_ = Color.black;
private PropertyChangeSupport changes_ = new PropertyChangeSupport(this);
private VetoableChangeSupport vetos_ = new VetoableChangeSupport(this);
private ValueIconFormat frmt_ = new ValueIconFormat("#####.##", "#.#");
private final static String defTFrmt = "yyyy-MM-dd";
/**
* Construct a ValueIcon using an image from a
* specified file.
*
* @param filename name of image file
* @param description brief textual description of the image
*/
public ValueIcon(String filename, String description) {
super(filename, description);
getImageSize();
frmt_.setTimeFormat(defTFrmt);
}
/**
* Construct a ValueIcon using an image from a
* specified URL.
*
* @param location URL of image file
* @param description brief textual description of the image
*/
public ValueIcon(URL location, String description) {
super(location, description);
getImageSize();
frmt_.setTimeFormat(defTFrmt);
}
/**
* Construct a ValueIcon using an Image.
*
* @param image the image
* @param description brief textual description of the image
*/
public ValueIcon(Image image, String description) {
super(image, description);
getImageSize();
frmt_.setTimeFormat(defTFrmt);
}
/**
* Set format to be used to create the value string. Default format
* is new ValueIconFormat("#####.##", "#").
*
* @param the value format
*/
public void setValueFormat(ValueIconFormat vf) {
frmt_ = vf;
}
/**
* Paint the icon at the specified location.
*/
public void paintIcon(Component c, VectorGraphics g2, int x, int y) {
String text;
double xu, yu;
double xt, yt;
//
// compute bounds
//
text = frmt_.format(uLoc_);
FontMetrics fmet = g2.getFontMetrics();
int wid = fmet.stringWidth(text);
int hgt = fmet.getMaxAscent() + fmet.getMaxDescent();
bounds_.x = x;
bounds_.y = y;
bounds_.width = iWidth_ + wid;
bounds_.height = iHeight_ + fmet.getMaxDescent();
//
if(visible_) {
g2.drawImage(getImage(), bounds_.x, bounds_.y, layer_.getPane().getComponent());
int xl = bounds_.x + iWidth_;
int yl = bounds_.y + iHeight_;
g2.setFont(font_);
g2.setColor(layer_.getPane().getComponent().getBackground());
g2.fillRect(xl,yl-fmet.getMaxAscent(),wid,hgt);
g2.setColor(textColor_);
g2.drawString(text, xl, yl);
}
}
/**
* Set the font for the value label.
*
* @param font the font
*/
public void setFont(Font font) {
font_ = font;
}
/**
* Get the value label font
*/
public Font getFont() {
return font_;
}
private void getImageSize() {
iWidth_ = super.getIconWidth();
iHeight_ = super.getIconHeight();
}
/**
* Get the total width, icon + label.
*/
public int getIconWidth() {
return bounds_.width;
}
/**
* Get the total heigth.
*/
public int getIconHeight() {
return bounds_.height;
}
public LayerChild copy() {
return null;
}
public void setVisible(boolean vis) {
if(visible_ != vis) {
visible_ = vis;
}
}
public boolean isVisible() {
return visible_;
}
public void draw(VectorGraphics g) {
int x = ((CartesianGraph)layer_.getGraph()).getXUtoD(uLoc_.getX()) -
iWidth_/2;
int y = ((CartesianGraph)layer_.getGraph()).getYUtoD(uLoc_.getY()) -
iHeight_/2;
paintIcon(layer_.getPane().getComponent(), g, x, y);
}
public String getId() {
return id_;
}
public Layer getLayer() {
return layer_;
}
public AbstractPane getPane() {
return layer_.getPane();
}
public void modified(String mess) {
if(layer_ != null)
layer_.modified(mess);
}
public void setId(String id) {
id_ = id;
}
public void setLayer(Layer l) {
layer_ = l;
}
public String toString() {
return "ValueIcon: " + id_;
}
public Rectangle getBounds() {
return bounds_;
}
public boolean isSelected() {
return selected_;
}
public void setSelected(boolean sel) {
selected_ = sel;
}
public boolean isSelectable() {
return selectable_;
}
public void setSelectable(boolean select) {
selectable_ = select;
}
/**
* Get the icon location in physical units.
*/
public Point2D.Double getLocationP() {
return loc_;
}
/**
* Set the icon location in physical units.
*
Property Change: location.
*/
public void setLocationP(Point2D.Double loc) {
SoTPoint pt;
loc_ = loc;
bounds_.x = layer_.getXPtoD(loc_.x) - iWidth_/2;
bounds_.y = layer_.getYPtoD(loc_.y) - iHeight_/2;
pt = ((CartesianGraph)layer_.getGraph()).getPtoU(loc_);
if(!pt.equals(uLoc_) || moved_) {
SoTPoint temp = new SoTPoint(pt);
changes_.firePropertyChange("location",
uLoc_,
temp);
uLoc_ = temp;
moved_ = false;
}
}
/**
* Get the icon location in user units.
*
* @since 3.0
*/
public SoTPoint getLocationU() {
return uLoc_;
}
/**
* Set the icon location in user units. Location change can't be
* vetoed.
*
* @since 3.0
*/
public void setLocationUNoVeto(SoTPoint loc) {
moved_ = moved_ || !loc.equals(uLoc_);
uLoc_ = loc;
loc_.x = ((CartesianGraph)layer_.getGraph()).getXUtoP(uLoc_.getX());
loc_.y = ((CartesianGraph)layer_.getGraph()).getYUtoP(uLoc_.getY());
bounds_.x = layer_.getXPtoD(loc_.x);
bounds_.y = layer_.getYPtoD(loc_.y);
}
/**
* Set the icon location in user units. Location change can be
* vetoed.
*
Property Change: location.
* @since 3.0
*/
public void setLocationU(SoTPoint loc) throws PropertyVetoException {
if(!loc.equals(uLoc_) || moved_) {
vetos_.fireVetoableChange("location", uLoc_, loc);
changes_.firePropertyChange("location",
uLoc_,
loc);
uLoc_ = loc;
moved_ = false;
loc_.x = ((CartesianGraph)layer_.getGraph()).getXUtoP(uLoc_.getX());
loc_.y = ((CartesianGraph)layer_.getGraph()).getYUtoP(uLoc_.getY());
bounds_.x = layer_.getXPtoD(loc_.x) - iWidth_/2;
bounds_.y = layer_.getYPtoD(loc_.y) - iHeight_/2;
}
}
/**
* Set icon location in device coordinates. Locatoin change can't be
* vetoed.
*/
public void setLocationNoVeto(int x, int y) {
SoTPoint pt;
bounds_.x = x;
bounds_.y = y;
loc_.x = layer_.getXDtoP(x);
loc_.y = layer_.getYDtoP(y);
pt = ((CartesianGraph)layer_.getGraph()).getPtoU(loc_);
moved_ = moved_ || !pt.equals(uLoc_);
uLoc_ = new SoTPoint(pt);
}
/**
* Set icon location in device units
*/
public void setLocation(Point loc) {
setLocation(loc, true);
}
/**
* Set icon location in device units and optionally fire a
* PropertyChangeEvent.
*
* @since 3.0
*/
public void setLocation(Point loc, boolean fireEvent) {
setBounds(loc.x, loc.y, 0, 0, fireEvent);
}
/**
* Set icon bounds.
*
Property Change: location.
*/
public void setBounds(int x, int y, int width, int height) {
setBounds(x, y, width, height, true);
}
private void setBounds(int x, int y, int width, int height, boolean fireEvent) {
SoTPoint pt;
bounds_.x = x;
bounds_.y = y;
loc_.x = layer_.getXDtoP(x + iWidth_/2);
loc_.y = layer_.getYDtoP(y + iHeight_/2);
pt = ((CartesianGraph)layer_.getGraph()).getPtoU(loc_);
moved_ = moved_ || !pt.equals(uLoc_);
if(moved_) {
SoTPoint temp = new SoTPoint(pt);
if(fireEvent) {
changes_.firePropertyChange("location",
uLoc_,
temp);
moved_ = false;
}
uLoc_ = temp;
}
}
/**
* Set icon bounds.
*/
public void setBounds(Rectangle bounds) {
setBounds(bounds.x, bounds.y, bounds.width, bounds.height);
}
public void addVetoableChangeListener(VetoableChangeListener l) {
vetos_.addVetoableChangeListener(l);
}
public void removeVetoableChangeListener(VetoableChangeListener l) {
vetos_.removeVetoableChangeListener(l);
}
public void addPropertyChangeListener(PropertyChangeListener l) {
changes_.addPropertyChangeListener(l);
}
public void removePropertyChangeListener(PropertyChangeListener l) {
changes_.removePropertyChangeListener(l);
}
}
Ads help maintain this website.