Save This Page
Home » jcommon-1.0.13 » org.jfree » chart » annotations » [javadoc | source]
    1   /* ===========================================================
    2    * JFreeChart : a free chart library for the Java(tm) platform
    3    * ===========================================================
    4    *
    5    * (C) Copyright 2000-2007, by Object Refinery Limited and Contributors.
    6    *
    7    * Project Info:  http://www.jfree.org/jfreechart/index.html
    8    *
    9    * This library is free software; you can redistribute it and/or modify it 
   10    * under the terms of the GNU Lesser General Public License as published by 
   11    * the Free Software Foundation; either version 2.1 of the License, or 
   12    * (at your option) any later version.
   13    *
   14    * This library is distributed in the hope that it will be useful, but 
   15    * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
   16    * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
   17    * License for more details.
   18    *
   19    * You should have received a copy of the GNU Lesser General Public
   20    * License along with this library; if not, write to the Free Software
   21    * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
   22    * USA.  
   23    *
   24    * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 
   25    * in the United States and other countries.]
   26    *
   27    * ---------------------
   28    * XYTextAnnotation.java
   29    * ---------------------
   30    * (C) Copyright 2002-2007, by Object Refinery Limited.
   31    *
   32    * Original Author:  David Gilbert (for Object Refinery Limited);
   33    * Contributor(s):   -;
   34    *
   35    * Changes:
   36    * --------
   37    * 28-Aug-2002 : Version 1 (DG);
   38    * 07-Nov-2002 : Fixed errors reported by Checkstyle (DG);
   39    * 13-Jan-2003 : Reviewed Javadocs (DG);
   40    * 26-Mar-2003 : Implemented Serializable (DG);
   41    * 02-Jul-2003 : Added new text alignment and rotation options (DG);
   42    * 19-Aug-2003 : Implemented Cloneable (DG);
   43    * 17-Jan-2003 : Added fix for bug 878706, where the annotation is placed 
   44    *               incorrectly for a plot with horizontal orientation (thanks to
   45    *               Ed Yu for the fix) (DG);
   46    * 21-Jan-2004 : Update for renamed method in ValueAxis (DG);
   47    * ------------- JFREECHART 1.0.x ---------------------------------------------
   48    * 26-Jan-2006 : Fixed equals() method (bug 1415480) (DG);
   49    * 06-Mar-2007 : Added argument checks, re-implemented hashCode() method (DG);
   50    *
   51    */
   52   
   53   package org.jfree.chart.annotations;
   54   
   55   import java.awt.Color;
   56   import java.awt.Font;
   57   import java.awt.Graphics2D;
   58   import java.awt.Paint;
   59   import java.awt.Shape;
   60   import java.awt.geom.Rectangle2D;
   61   import java.io.IOException;
   62   import java.io.ObjectInputStream;
   63   import java.io.ObjectOutputStream;
   64   import java.io.Serializable;
   65   
   66   import org.jfree.chart.HashUtilities;
   67   import org.jfree.chart.axis.ValueAxis;
   68   import org.jfree.chart.plot.Plot;
   69   import org.jfree.chart.plot.PlotOrientation;
   70   import org.jfree.chart.plot.PlotRenderingInfo;
   71   import org.jfree.chart.plot.XYPlot;
   72   import org.jfree.io.SerialUtilities;
   73   import org.jfree.text.TextUtilities;
   74   import org.jfree.ui.RectangleEdge;
   75   import org.jfree.ui.TextAnchor;
   76   import org.jfree.util.PaintUtilities;
   77   import org.jfree.util.PublicCloneable;
   78   
   79   /**
   80    * A text annotation that can be placed at a particular (x, y) location on an 
   81    * {@link XYPlot}.
   82    */
   83   public class XYTextAnnotation extends AbstractXYAnnotation
   84                                 implements Cloneable, PublicCloneable, 
   85                                            Serializable {
   86   
   87       /** For serialization. */
   88       private static final long serialVersionUID = -2946063342782506328L;
   89       
   90       /** The default font. */
   91       public static final Font DEFAULT_FONT = new Font("SansSerif", Font.PLAIN, 
   92               10);
   93   
   94       /** The default paint. */
   95       public static final Paint DEFAULT_PAINT = Color.black;
   96       
   97       /** The default text anchor. */
   98       public static final TextAnchor DEFAULT_TEXT_ANCHOR = TextAnchor.CENTER;
   99   
  100       /** The default rotation anchor. */    
  101       public static final TextAnchor DEFAULT_ROTATION_ANCHOR = TextAnchor.CENTER;
  102       
  103       /** The default rotation angle. */
  104       public static final double DEFAULT_ROTATION_ANGLE = 0.0;
  105   
  106       /** The text. */
  107       private String text;
  108   
  109       /** The font. */
  110       private Font font;
  111   
  112       /** The paint. */
  113       private transient Paint paint;
  114       
  115       /** The x-coordinate. */
  116       private double x;
  117   
  118       /** The y-coordinate. */
  119       private double y;
  120   
  121       /** The text anchor (to be aligned with (x, y)). */
  122       private TextAnchor textAnchor;
  123       
  124       /** The rotation anchor. */
  125       private TextAnchor rotationAnchor;
  126       
  127       /** The rotation angle. */
  128       private double rotationAngle;
  129       
  130       /**
  131        * Creates a new annotation to be displayed at the given coordinates.  The
  132        * coordinates are specified in data space (they will be converted to 
  133        * Java2D space for display).
  134        *
  135        * @param text  the text (<code>null</code> not permitted).
  136        * @param x  the x-coordinate (in data space).
  137        * @param y  the y-coordinate (in data space).
  138        */
  139       public XYTextAnnotation(String text, double x, double y) {
  140           if (text == null) {
  141               throw new IllegalArgumentException("Null 'text' argument.");
  142           }
  143           this.text = text;
  144           this.font = DEFAULT_FONT;
  145           this.paint = DEFAULT_PAINT;
  146           this.x = x;
  147           this.y = y;
  148           this.textAnchor = DEFAULT_TEXT_ANCHOR;
  149           this.rotationAnchor = DEFAULT_ROTATION_ANCHOR;
  150           this.rotationAngle = DEFAULT_ROTATION_ANGLE;
  151       }
  152       
  153       /**
  154        * Returns the text for the annotation.
  155        *
  156        * @return The text (never <code>null</code>).
  157        * 
  158        * @see #setText(String)
  159        */
  160       public String getText() {
  161           return this.text;
  162       }
  163   
  164       /**
  165        * Sets the text for the annotation.
  166        * 
  167        * @param text  the text (<code>null</code> not permitted).
  168        * 
  169        * @see #getText()
  170        */
  171       public void setText(String text) {
  172           if (text == null) {
  173               throw new IllegalArgumentException("Null 'text' argument.");
  174           }
  175           this.text = text;
  176       }
  177       
  178       /**
  179        * Returns the font for the annotation.
  180        *
  181        * @return The font (never <code>null</code>).
  182        * 
  183        * @see #setFont(Font)
  184        */
  185       public Font getFont() {
  186           return this.font;
  187       }
  188   
  189       /**
  190        * Sets the font for the annotation.
  191        * 
  192        * @param font  the font (<code>null</code> not permitted).
  193        * 
  194        * @see #getFont()
  195        */
  196       public void setFont(Font font) {
  197           if (font == null) {
  198               throw new IllegalArgumentException("Null 'font' argument.");
  199           }
  200           this.font = font;
  201       }
  202       
  203       /**
  204        * Returns the paint for the annotation.
  205        *
  206        * @return The paint (never <code>null</code>).
  207        * 
  208        * @see #setPaint(Paint)
  209        */
  210       public Paint getPaint() {
  211           return this.paint;
  212       }
  213       
  214       /**
  215        * Sets the paint for the annotation.
  216        * 
  217        * @param paint  the paint (<code>null</code> not permitted).
  218        * 
  219        * @see #getPaint()
  220        */
  221       public void setPaint(Paint paint) {
  222           if (paint == null) {
  223               throw new IllegalArgumentException("Null 'paint' argument.");
  224           }
  225           this.paint = paint;
  226       }
  227   
  228       /**
  229        * Returns the text anchor.
  230        * 
  231        * @return The text anchor (never <code>null</code>).
  232        * 
  233        * @see #setTextAnchor(TextAnchor)
  234        */
  235       public TextAnchor getTextAnchor() {
  236           return this.textAnchor;
  237       }
  238       
  239       /**
  240        * Sets the text anchor (the point on the text bounding rectangle that is 
  241        * aligned to the (x, y) coordinate of the annotation).
  242        * 
  243        * @param anchor  the anchor point (<code>null</code> not permitted).
  244        * 
  245        * @see #getTextAnchor()
  246        */
  247       public void setTextAnchor(TextAnchor anchor) {
  248           if (anchor == null) {
  249               throw new IllegalArgumentException("Null 'anchor' argument.");
  250           }
  251           this.textAnchor = anchor;
  252       }
  253       
  254       /**
  255        * Returns the rotation anchor.
  256        * 
  257        * @return The rotation anchor point (never <code>null</code>).
  258        * 
  259        * @see #setRotationAnchor(TextAnchor)
  260        */
  261       public TextAnchor getRotationAnchor() {
  262           return this.rotationAnchor;
  263       }
  264       
  265       /**
  266        * Sets the rotation anchor point.
  267        * 
  268        * @param anchor  the anchor (<code>null</code> not permitted).
  269        * 
  270        * @see #getRotationAnchor()
  271        */
  272       public void setRotationAnchor(TextAnchor anchor) {
  273           if (anchor == null) {
  274               throw new IllegalArgumentException("Null 'anchor' argument.");
  275           }
  276           this.rotationAnchor = anchor;    
  277       }
  278       
  279       /**
  280        * Returns the rotation angle.
  281        * 
  282        * @return The rotation angle.
  283        * 
  284        * @see #setRotationAngle(double)
  285        */
  286       public double getRotationAngle() {
  287           return this.rotationAngle; 
  288       }
  289       
  290       /**
  291        * Sets the rotation angle.  The angle is measured clockwise in radians.
  292        * 
  293        * @param angle  the angle (in radians).
  294        * 
  295        * @see #getRotationAngle()
  296        */
  297       public void setRotationAngle(double angle) {
  298           this.rotationAngle = angle;    
  299       }
  300       
  301       /**
  302        * Returns the x coordinate for the text anchor point (measured against the
  303        * domain axis).
  304        * 
  305        * @return The x coordinate (in data space).
  306        * 
  307        * @see #setX(double)
  308        */
  309       public double getX() {
  310           return this.x;
  311       }
  312       
  313       /**
  314        * Sets the x coordinate for the text anchor point (measured against the 
  315        * domain axis).
  316        * 
  317        * @param x  the x coordinate (in data space).
  318        * 
  319        * @see #getX()
  320        */
  321       public void setX(double x) {
  322           this.x = x;
  323       }
  324       
  325       /**
  326        * Returns the y coordinate for the text anchor point (measured against the
  327        * range axis).
  328        * 
  329        * @return The y coordinate (in data space).
  330        * 
  331        * @see #setY(double)
  332        */
  333       public double getY() {
  334           return this.y;
  335       }
  336       
  337       /**
  338        * Sets the y coordinate for the text anchor point (measured against the
  339        * range axis).
  340        * 
  341        * @param y  the y coordinate.
  342        * 
  343        * @see #getY()
  344        */
  345       public void setY(double y) {
  346           this.y = y;
  347       }    
  348   
  349       /**
  350        * Draws the annotation.
  351        *
  352        * @param g2  the graphics device.
  353        * @param plot  the plot.
  354        * @param dataArea  the data area.
  355        * @param domainAxis  the domain axis.
  356        * @param rangeAxis  the range axis.
  357        * @param rendererIndex  the renderer index.
  358        * @param info  an optional info object that will be populated with
  359        *              entity information.
  360        */
  361       public void draw(Graphics2D g2, XYPlot plot, Rectangle2D dataArea,
  362                        ValueAxis domainAxis, ValueAxis rangeAxis, 
  363                        int rendererIndex,
  364                        PlotRenderingInfo info) {
  365   
  366           PlotOrientation orientation = plot.getOrientation();
  367           RectangleEdge domainEdge = Plot.resolveDomainAxisLocation(
  368                   plot.getDomainAxisLocation(), orientation);
  369           RectangleEdge rangeEdge = Plot.resolveRangeAxisLocation(
  370                   plot.getRangeAxisLocation(), orientation);
  371   
  372           float anchorX = (float) domainAxis.valueToJava2D(
  373                   this.x, dataArea, domainEdge);
  374           float anchorY = (float) rangeAxis.valueToJava2D(
  375                   this.y, dataArea, rangeEdge);
  376   
  377           if (orientation == PlotOrientation.HORIZONTAL) {
  378               float tempAnchor = anchorX;
  379               anchorX = anchorY;
  380               anchorY = tempAnchor;
  381           }
  382           
  383           g2.setFont(getFont());
  384           g2.setPaint(getPaint());
  385           TextUtilities.drawRotatedString(getText(), g2, anchorX, anchorY,
  386                   getTextAnchor(), getRotationAngle(), getRotationAnchor());
  387           Shape hotspot = TextUtilities.calculateRotatedStringBounds(
  388                   getText(), g2, anchorX, anchorY, getTextAnchor(), 
  389                   getRotationAngle(), getRotationAnchor());
  390           
  391           String toolTip = getToolTipText();
  392           String url = getURL();
  393           if (toolTip != null || url != null) {
  394               addEntity(info, hotspot, rendererIndex, toolTip, url);
  395           }
  396   
  397       }
  398       
  399       /**
  400        * Tests this annotation for equality with an arbitrary object.
  401        * 
  402        * @param obj  the object (<code>null</code> permitted).
  403        * 
  404        * @return A boolean.
  405        */
  406       public boolean equals(Object obj) {
  407           if (obj == this) {
  408               return true;   
  409           }
  410           if (!(obj instanceof XYTextAnnotation)) {
  411               return false;   
  412           }
  413           if (!super.equals(obj)) {
  414               return false;
  415           }
  416           XYTextAnnotation that = (XYTextAnnotation) obj;
  417           if (!this.text.equals(that.text)) {
  418               return false;   
  419           }
  420           if (this.x != that.x) {
  421               return false;
  422           }
  423           if (this.y != that.y) {
  424               return false;
  425           }
  426           if (!this.font.equals(that.font)) {
  427               return false;   
  428           }
  429           if (!PaintUtilities.equal(this.paint, that.paint)) {
  430               return false;   
  431           }
  432           if (!this.rotationAnchor.equals(that.rotationAnchor)) {
  433               return false;   
  434           }
  435           if (this.rotationAngle != that.rotationAngle) {
  436               return false;   
  437           }
  438           if (!this.textAnchor.equals(that.textAnchor)) {
  439               return false;   
  440           }
  441           return true;   
  442       }
  443       
  444       /**
  445        * Returns a hash code for the object.
  446        * 
  447        * @return A hash code.
  448        */
  449       public int hashCode() {
  450           int result = 193;
  451           result = 37 * this.text.hashCode();
  452           result = 37 * this.font.hashCode();
  453           result = 37 * result + HashUtilities.hashCodeForPaint(this.paint);
  454           long temp = Double.doubleToLongBits(this.x);
  455           result = 37 * result + (int) (temp ^ (temp >>> 32));
  456           temp = Double.doubleToLongBits(this.y);
  457           result = 37 * result + (int) (temp ^ (temp >>> 32));
  458           result = 37 * result + this.textAnchor.hashCode();
  459           result = 37 * result + this.rotationAnchor.hashCode();
  460           temp = Double.doubleToLongBits(this.rotationAngle);
  461           result = 37 * result + (int) (temp ^ (temp >>> 32));
  462           return result;   
  463       }
  464       
  465       /**
  466        * Returns a clone of the annotation.
  467        * 
  468        * @return A clone.
  469        * 
  470        * @throws CloneNotSupportedException  if the annotation can't be cloned.
  471        */
  472       public Object clone() throws CloneNotSupportedException {
  473           return super.clone();
  474       }
  475       
  476       /**
  477        * Provides serialization support.
  478        *
  479        * @param stream  the output stream.
  480        *
  481        * @throws IOException  if there is an I/O error.
  482        */
  483       private void writeObject(ObjectOutputStream stream) throws IOException {
  484           stream.defaultWriteObject();
  485           SerialUtilities.writePaint(this.paint, stream);
  486       }
  487   
  488       /**
  489        * Provides serialization support.
  490        *
  491        * @param stream  the input stream.
  492        *
  493        * @throws IOException  if there is an I/O error.
  494        * @throws ClassNotFoundException  if there is a classpath problem.
  495        */
  496       private void readObject(ObjectInputStream stream) 
  497           throws IOException, ClassNotFoundException {
  498           stream.defaultReadObject();
  499           this.paint = SerialUtilities.readPaint(stream);
  500       }
  501   
  502   }

Save This Page
Home » jcommon-1.0.13 » org.jfree » chart » annotations » [javadoc | source]