/* * $Id: PointCollectionKey.java,v 1.9 2003/08/22 23:02:32 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 gov.noaa.pmel.sgt; import gov.noaa.pmel.util.Point2D; import gov.noaa.pmel.util.Rectangle2D; import gov.noaa.pmel.util.Debug; import java.util.Vector; import java.util.Enumeration; import java.awt.Graphics; import java.awt.Rectangle; import java.awt.Point; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeSupport; // jdk1.2 //import java.awt.geom.Point2D; /** * PointCollectionKey is used to create a key for the * PointCartesianRenderer. Multiple * lines can be included in the key. * * @author Donald Denbo * @version $Revision: 1.9 $, $Date: 2003/08/22 23:02:32 $ * @since 2.0 **/ public class PointCollectionKey implements Cloneable, DataKey, Moveable, PropertyChangeListener { private String ident_; /** @directed */ private Layer layer_; private Vector points_; private Vector label_; private int columns_; private int style_; private int valign_; private int halign_; private Point2D.Double porigin_; private double lineLengthP_; private int maxLabelLength_; private int maxLabelHeight_; private boolean selected_; private boolean selectable_; private boolean visible_; private boolean moveable_; private PropertyChangeSupport changes_ = new PropertyChangeSupport(this); private static final int VERTICAL_BORDER_ = 3; private static final int HORIZONTAL_BORDER_ = 15; private static final int COLUMN_SPACE_ = 10; private static final int ROW_SPACE_ = 3; private static final int LABEL_SPACE_ = 15; /** * Use plain line border. */ public static final int PLAIN_LINE = 0; /** * Use raised border. */ public static final int RAISED = 1; /** * Do not draw a border. */ public static final int NO_BORDER = 2; /** * Align to top of key. */ public static final int TOP = 0; /** * Align to middle of key. */ public static final int MIDDLE = 1; /** * Align to bottom of key. */ public static final int BOTTOM = 2; /** * Align to left of key. */ public static final int LEFT = 0; /** * Align to center of key. */ public static final int CENTER = 1; /** * Align to right of key. */ public static final int RIGHT = 2; /** * @link aggregation * @supplierCardinality * * @label points */ /*#PointCartesianRenderer lnkPointCartesianRenderer;*/ /** @link aggregation * @label label * @supplierCardinality **/ /*#SGLabel lnkSGLabel;*/ /** * Default constructor. */ public PointCollectionKey() { this(new Point2D.Double(0.0, 0.0), BOTTOM, LEFT); } /** * Create PointCollectionKey. */ public PointCollectionKey(Point2D.Double loc,int valign,int halign) { porigin_ = loc; valign_ = valign; halign_ = halign; points_ = new Vector(2,2); label_ = new Vector(2,2); // // set defaults // style_ = PLAIN_LINE; columns_ = 1; ident_ = ""; lineLengthP_ = 0.3f; selected_ = false; selectable_ = true; visible_ = true; moveable_ = true; } /** * Create of copy of PointCollectionKey. */ public LayerChild copy() { PointCollectionKey newKey; try { newKey = (PointCollectionKey)clone(); } catch (CloneNotSupportedException e) { newKey = new PointCollectionKey(); } newKey.points_ = new Vector(2,2); newKey.label_ = new Vector(2,2); return newKey; } public void setSelected(boolean sel) { selected_ = sel; } public boolean isSelected() { return selected_; } public void setSelectable(boolean select) { selectable_ = select; } public boolean isSelectable() { return selectable_; } public boolean isMoveable() { return moveable_; } public void setMoveable(boolean moveable) { moveable_ = moveable; } /** * Set parent layer. * * @param l parent layer */ public void setLayer(Layer l) { layer_ = l; } /** * Get layer. * * @return layer */ public Layer getLayer() { return layer_; } public AbstractPane getPane() { return layer_.getPane(); } public void modified(String mess) { if(layer_ != null) layer_.modified(mess); } /** * Set PointCollectionKey identifier. * * @param id key identifier */ public void setId(String id) { ident_ = id; } /** * Get PointCollectionKey identifier * * @return identifier */ public String getId() { return ident_; } /** * Set line length. * * @param len line length */ public void setLineLengthP(double len) { if(lineLengthP_ != len) { lineLengthP_ = len; modified("PointCollectionKey: setLineLengthP()"); } } /** * Get line length * * @return line length */ public double getLineLengthP() { return lineLengthP_; } /** * Set the number of columns. * * @param col number of columns */ public void setColumns(int col) { if(columns_ != col) { columns_ = col; modified("PointCollectionKey: setColumms()"); } } /** * Get the number of columns. * * @return number of columns */ public int getColumns() { return columns_; } /** * Set border style. * * @param style border style * @see #PLAIN_LINE * @see #RAISED * @see #NO_BORDER */ public void setBorderStyle(int style) { if(style_ != style) { style_ = style; modified("PointCollectionKey: setBorderStyle()"); } } /** * Get border style. * * @return border style */ public int getBorderStyle() { return style_; } /** * Set alignment. * * @param vert vertical alignment * @param horz horizontal alignment */ public void setAlign(int vert,int horz) { if(valign_ != vert || halign_ != horz) { valign_ = vert; halign_ = horz; modified("PointCollectionKey: setAlign()"); } } /** * Set vertical alignment * * @param vert vertical alignment */ public void setVAlign(int vert) { if(valign_ != vert) { valign_ = vert; modified("PointCollectionKey: setVAlign()"); } } /** * Set horizontal alignment * * @param horz horizontal alignment */ public void setHAlign(int horz) { if(halign_ != horz) { halign_ = horz; modified("PointCollectionKey: setHAlign()"); } } /** * Get vertical alignment * * @return vertical alignment */ public int getVAlign() { return valign_; } /** * Get horizontal alignment * * @return horizontal alignment */ public int getHAlign() { return halign_; } /** * Set location of key *
Property Change: location. * * @param loc key location */ public void setLocationP(Point2D.Double loc) { if(porigin_ == null || !porigin_.equals(loc)) { Point2D.Double temp = porigin_; porigin_ = loc; changes_.firePropertyChange("location", temp, porigin_); modified("PointCollectionKey: setLocationP()"); } } /** * Set the bounds, in physical units, of the PointCollectionKey */ public void setBoundsP(Rectangle2D.Double r) { setLocationP(new Point2D.Double(r.x, r.y)); } public Rectangle2D.Double getBoundsP() { throw new MethodNotImplementedError(); } /** * Get location of key. * * @return Key location */ public Point2D.Double getLocationP() { return porigin_; } /** * Add a PointCartesianRenderer and label to the PointCollectionKey. * * @param line PointCartesianRenderer object * @param label descriptive label */ public void addPointGraph(PointCartesianRenderer points, SGLabel label) { points_.addElement(points); label.setLayer(layer_); label.setMoveable(false); label.setSelectable(false); label_.addElement(label); ((PointAttribute)points.getAttribute()).addPropertyChangeListener(this); modified("PointCollectionKey: addPointGraph()"); } /** * Add a PointCartesianRenderer and label to the PointCollectionKey. * * @param rend CartesianRenderer object * @param label descriptive label * @since 3.0 */ public void addGraph(CartesianRenderer rend, SGLabel label) throws IllegalArgumentException { if(!(rend instanceof PointCartesianRenderer)) throw new IllegalArgumentException("Renderer is not a PointCartesianRenderer"); addPointGraph((PointCartesianRenderer)rend, label); } /** * Remove a line from the PointCollectionKey. * */ public void removePointGraph(SGLabel label) { } /** * Remove a line from the PointCollectionKey. * */ public void removePointRenderer(PointCartesianRenderer line) { } /** * Remove a line from the PointCollectionKey. * */ public void removePointGraph(String ident) { } /** * Remove all lines from the PointCollectionKey. */ public void clearAll() { PointAttribute attr; for(Enumeration e = points_.elements(); e.hasMoreElements(); ) { attr = (PointAttribute)((PointCartesianRenderer)e.nextElement()).getAttribute(); attr.removePropertyChangeListener(this); } points_.removeAllElements(); label_.removeAllElements(); modified("PointCollectionKey: clearAll()"); } /** * Remove data from key by id. */ public void clear(String data_id) { PointCartesianRenderer pcr; int indx = -1; for(Enumeration it = points_.elements(); it.hasMoreElements();) { indx++; pcr = (PointCartesianRenderer)it.nextElement(); // if(pcr.getLine().getId().equals(data_id)) { // pcr.getAttribute().removePropertyChangeListener(this); // points_.removeElement(lcr); // label_.removeElementAt(indx); // modified("PointCollectionKey: clear()"); // break; // } } } /** * Return height of key row in pixels. */ public int getRowHeight() { Rectangle bounds; bounds = getBounds(); return ROW_SPACE_ + maxLabelHeight_; } /** * Draw the Key. */ public void draw(Graphics g) { double maxLabelLength, maxLabelHeight; int numLines, numRows, i, lineLength; int col, row, ytemp; double xloc, labelSpace; double[] xp, yp; int[] xd, yd; int[] xout, yout; Rectangle bounds; PointCartesianRenderer render = null; SGLabel label; PointAttribute attr = null; // numLines = points_.size(); if((numLines <= 0) || !visible_) return; numRows = numLines/columns_; if(numLines%columns_ != 0) numRows++; xp = new double[columns_]; xd = new int[columns_]; yp = new double[numRows]; yd = new int[numRows]; xout = new int[2]; yout = new int[2]; g.setColor(layer_.getPane().getComponent().getForeground()); bounds = getBounds(); // // compute location of rows and columns in device and physical coordinates // lineLength = layer_.getXPtoD(lineLengthP_) - layer_.getXPtoD(0.0f); labelSpace = layer_.getXDtoP(LABEL_SPACE_) - layer_.getXDtoP(0); // yd[0] = bounds.y + VERTICAL_BORDER_ + maxLabelHeight_; yp[0] = layer_.getYDtoP(yd[0]); for(i=1; i < numRows; i++) { yd[i] = yd[i-1] + ROW_SPACE_ + maxLabelHeight_; yp[i] = layer_.getYDtoP(yd[i]); } xd[0] = bounds.x + HORIZONTAL_BORDER_; xp[0] = layer_.getXDtoP(xd[0]); for(i=1; i < columns_; i++) { xd[i] = xd[i-1] + COLUMN_SPACE_ + lineLength + LABEL_SPACE_ + maxLabelLength_; xp[i] = layer_.getXDtoP(xd[i]); } // row = 0; col = 0; Object obj; Enumeration labelIt = label_.elements(); for(Enumeration lineIt = points_.elements(); lineIt.hasMoreElements();) { obj = lineIt.nextElement(); render = (PointCartesianRenderer)obj; attr = (PointAttribute)render.getAttribute(); label = (SGLabel)labelIt.nextElement(); // // draw line // g.setColor(attr.getColor()); xout[0] = xd[col]; xout[1] = xout[0] + lineLength; yout[0] = yd[row] - maxLabelHeight_/2; yout[1] = yout[0]; // hack because mark is a little too high int ymark = yout[0] ; PlotMark pm = new PlotMark(attr); pm.setMarkHeightP(label.getHeightP()); pm.paintMark(g, layer_, xout[0], ymark); pm.paintMark(g, layer_, xout[1], ymark); // xloc = xp[col] + lineLengthP_ + labelSpace; label.setLocationP(new Point2D.Double(xloc, yp[row])); try { label.draw(g); } catch (SGException e) {} // col++; if(col >= columns_) { col = 0; row++; } } switch(style_) { case PLAIN_LINE: g.drawRect(bounds.x, bounds.y, bounds.width-1, bounds.height-1); break; case RAISED: break; default: case NO_BORDER: } } /** * Get the bounding rectangle. * * @return bounding rectangle */ public Rectangle getBounds() { int lineLength; int numLines, rows; int x, y, height, width; numLines = points_.size(); if(numLines <= 0) return new Rectangle(0, 0, 0, 0); // // find longest label // maxLabelLength_ = 0; maxLabelHeight_ = 0; SGLabel label; for(Enumeration it = label_.elements(); it.hasMoreElements();) { label = (SGLabel)it.nextElement(); Rectangle sz = label.getBounds(); maxLabelLength_ = Math.max(maxLabelLength_, sz.width); maxLabelHeight_ = Math.max(maxLabelHeight_, sz.height); } // rows = numLines/columns_; if(numLines%columns_ != 0) rows++; lineLength = layer_.getXPtoD(lineLengthP_) - layer_.getXPtoD(0.0f); width = 2*HORIZONTAL_BORDER_ + columns_*(lineLength + LABEL_SPACE_ + maxLabelLength_) + (columns_ - 1)*COLUMN_SPACE_; height = 2*VERTICAL_BORDER_ + rows*maxLabelHeight_ + (rows-1)*ROW_SPACE_; // temp fudge height = height + 5; // x = layer_.getXPtoD(porigin_.x); y = layer_.getYPtoD(porigin_.y); switch(halign_) { case RIGHT: x = x - width; break; case CENTER: x = x - width/2; } switch(valign_) { case BOTTOM: y = y - height; break; case MIDDLE: y = y - height/2; } return new Rectangle(x, y, width, height); } public Point getLocation() { Rectangle bnds = getBounds(); return new Point(bnds.x, bnds.y); } public void setLocation(Point loc) { Rectangle bnds = getBounds(); setBounds(loc.x, loc.y, bnds.width, bnds.height); } /** * Set the bounds, in pixels, of the PointCollectionKey */ public void setBounds(Rectangle r) { setBounds(r.x, r.y, r.width, r.height); } /** * Set the bounds, in pixels, of the PointCollectionKey *
Property Change: location. */ public void setBounds(int x, int y, int width, int height) { switch(halign_) { case RIGHT: x = x + width; break; case CENTER: x = x + width/2; } switch(valign_) { case BOTTOM: y = y + height; break; case MIDDLE: y = y + height/2; } double xp = layer_.getXDtoP(x); double yp = layer_.getYDtoP(y); if(porigin_.x != xp || porigin_.y != yp) { Point2D.Double temp = porigin_; porigin_.x = xp; porigin_.y = yp; changes_.firePropertyChange("location", temp, new Point2D.Double(xp, yp)); modified("PointCollectionKey: setBounds()"); } } Object getObjectAt(Point pt) { Rectangle lbnds; Rectangle bounds; PointCartesianRenderer point; int[] xout, yout; int[] xd, yd; int numLines, numRows; int lineLength; double labelSpace; int i; numLines = points_.size(); if(numLines <= 0) return null; numRows = numLines/columns_; if(numLines%columns_ != 0) numRows++; xd = new int[columns_]; yd = new int[numRows]; xout = new int[2]; yout = new int[2]; bounds = getBounds(); // // compute location of rows and columns in device and physical coordinates // lineLength = layer_.getXPtoD(lineLengthP_) - layer_.getXPtoD(0.0); labelSpace = layer_.getXDtoP(LABEL_SPACE_) - layer_.getXDtoP(0); // yd[0] = bounds.y + VERTICAL_BORDER_ + maxLabelHeight_; for(i=1; i < numRows; i++) { yd[i] = yd[i-1] + ROW_SPACE_ + maxLabelHeight_; } xd[0] = bounds.x + HORIZONTAL_BORDER_; for(i=1; i < columns_; i++) { xd[i] = xd[i-1] + COLUMN_SPACE_ + lineLength + LABEL_SPACE_ + maxLabelLength_; } // loop over all the lines int row = 0; int col = 0; for(Enumeration lineIt = points_.elements(); lineIt.hasMoreElements();) { point = (PointCartesianRenderer)lineIt.nextElement(); xout[0] = xd[col]; // xout[1] = xout[0] + lineLength + LABEL_SPACE_ + maxLabelLength_; xout[1] = xout[0] + lineLength + LABEL_SPACE_; yout[0] = yd[row] - maxLabelHeight_; yout[1] = yd[row]; lbnds = new Rectangle(xout[0], yout[0], xout[1] - xout[0], yout[1] - yout[0]); if(lbnds.contains(pt)) { return point; } // col++; if(col >= columns_) { col = 0; row++; } } if(bounds.contains(pt)) { return this; } return null; } public String toString() { String name = getClass().getName(); return name.substring(name.lastIndexOf(".")+1) + ": " + ident_; } public boolean isVisible() { return visible_; } public void setVisible(boolean visible) { if(visible_ != visible) { visible_ = visible; modified("PointCollectionKey: setVisible()"); } } public void propertyChange(PropertyChangeEvent evt) { // if(Debug.EVENT) { // System.out.println("PointCollectionKey: " + evt); // System.out.println(" " + evt.getPropertyName()); // } modified("PointCollectionKey: propertyChange(" + evt.getSource().toString() + "[" + evt.getPropertyName() + "]" + ")"); } public void addPropertyChangeListener(PropertyChangeListener l) { changes_.addPropertyChangeListener(l); } public void removePropertyChangeListener(PropertyChangeListener l) { changes_.removePropertyChangeListener(l); } }