    001    /* ===========================================================
    002     * JFreeChart : a free chart library for the Java(tm) platform
    003     * ===========================================================
    004     *
    005     * (C) Copyright 2000-2008, by Object Refinery Limited and Contributors.
    006     *
    007     * Project Info:  http://www.jfree.org/jfreechart/index.html
    008     *
    009     * This library is free software; you can redistribute it and/or modify it
    010     * under the terms of the GNU Lesser General Public License as published by
    011     * the Free Software Foundation; either version 2.1 of the License, or
    012     * (at your option) any later version.
    013     *
    014     * This library is distributed in the hope that it will be useful, but
    015     * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
    016     * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
    017     * License for more details.
    018     *
    019     * You should have received a copy of the GNU Lesser General Public
    020     * License along with this library; if not, write to the Free Software
    021     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
    022     * USA.
    023     *
    024     * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
    025     * in the United States and other countries.]
    026     *
    027     * -------------------------
    028     * XYDrawableAnnotation.java
    029     * -------------------------
    030     * (C) Copyright 2003-2008, by Object Refinery Limited.
    031     *
    032     * Original Author:  David Gilbert (for Object Refinery Limited);
    033     * Contributor(s):   -;
    034     *
    035     * Changes:
    036     * --------
    037     * 21-May-2003 : Version 1 (DG);
    038     * 21-Jan-2004 : Update for renamed method in ValueAxis (DG);
    039     * 30-Sep-2004 : Added support for tool tips and URLs (DG);
    040     *
    041     */
    042
    043    package org.jfree.chart.annotations;
    044
    045    import java.awt.Graphics2D;
    046    import java.awt.geom.Rectangle2D;
    047    import java.io.Serializable;
    048
    049    import org.jfree.chart.axis.ValueAxis;
    050    import org.jfree.chart.plot.Plot;
    051    import org.jfree.chart.plot.PlotOrientation;
    052    import org.jfree.chart.plot.PlotRenderingInfo;
    053    import org.jfree.chart.plot.XYPlot;
    054    import org.jfree.ui.Drawable;
    055    import org.jfree.ui.RectangleEdge;
    056    import org.jfree.util.ObjectUtilities;
    057    import org.jfree.util.PublicCloneable;
    058
    059    /**
    060     * A general annotation that can be placed on an {@link XYPlot}.
    061     */
    062    public class XYDrawableAnnotation extends AbstractXYAnnotation
    063            implements Cloneable, PublicCloneable, Serializable {
    064
    065        /** For serialization. */
    066        private static final long serialVersionUID = -6540812859722691020L;
    067
    068        /** The x-coordinate. */
    069        private double x;
    070
    071        /** The y-coordinate. */
    072        private double y;
    073
    074        /** The width. */
    075        private double width;
    076
    077        /** The height. */
    078        private double height;
    079
    080        /** The drawable object. */
    081        private Drawable drawable;
    082
    083        /**
    084         * Creates a new annotation to be displayed within the given area.
    085         *
    086         * @param x  the x-coordinate for the area.
    087         * @param y  the y-coordinate for the area.
    088         * @param width  the width of the area.
    089         * @param height  the height of the area.
    090         * @param drawable  the drawable object (<code>null</code> not permitted).
    091         */
    092        public XYDrawableAnnotation(double x, double y, double width, double height,
    093                                    Drawable drawable) {
    094
    095            if (drawable == null) {
    096                throw new IllegalArgumentException("Null 'drawable' argument.");
    097            }
    098            this.x = x;
    099            this.y = y;
    100            this.width = width;
    101            this.height = height;
    102            this.drawable = drawable;
    103
    104        }
    105
    106        /**
    107         * Draws the annotation.
    108         *
    109         * @param g2  the graphics device.
    110         * @param plot  the plot.
    111         * @param dataArea  the data area.
    112         * @param domainAxis  the domain axis.
    113         * @param rangeAxis  the range axis.
    114         * @param rendererIndex  the renderer index.
    115         * @param info  if supplied, this info object will be populated with
    116         *              entity information.
    117         */
    118        public void draw(Graphics2D g2, XYPlot plot, Rectangle2D dataArea,
    119                         ValueAxis domainAxis, ValueAxis rangeAxis,
    120                         int rendererIndex,
    121                         PlotRenderingInfo info) {
    122
    123            PlotOrientation orientation = plot.getOrientation();
    124            RectangleEdge domainEdge = Plot.resolveDomainAxisLocation(
    125                    plot.getDomainAxisLocation(), orientation);
    126            RectangleEdge rangeEdge = Plot.resolveRangeAxisLocation(
    127                    plot.getRangeAxisLocation(), orientation);
    128            float j2DX = (float) domainAxis.valueToJava2D(this.x, dataArea,
    129                    domainEdge);
    130            float j2DY = (float) rangeAxis.valueToJava2D(this.y, dataArea,
    131                    rangeEdge);
    132            Rectangle2D area = new Rectangle2D.Double(j2DX - this.width / 2.0,
    133                    j2DY - this.height / 2.0, this.width, this.height);
    134            this.drawable.draw(g2, area);
    135            String toolTip = getToolTipText();
    136            String url = getURL();
    137            if (toolTip != null || url != null) {
    138                addEntity(info, area, rendererIndex, toolTip, url);
    139            }
    140
    141        }
    142
    143        /**
    144         * Tests this annotation for equality with an arbitrary object.
    145         *
    146         * @param obj  the object to test against.
    147         *
    148         * @return <code>true</code> or <code>false</code>.
    149         */
    150        public boolean equals(Object obj) {
    151
    152            if (obj == this) { // simple case
    153                return true;
    154            }
    155            // now try to reject equality...
    156            if (!super.equals(obj)) {
    157                return false;
    158            }
    159            if (!(obj instanceof XYDrawableAnnotation)) {
    160                return false;
    161            }
    162            XYDrawableAnnotation that = (XYDrawableAnnotation) obj;
    163            if (this.x != that.x) {
    164                return false;
    165            }
    166            if (this.y != that.y) {
    167                return false;
    168            }
    169            if (this.width != that.width) {
    170                return false;
    171            }
    172            if (this.height != that.height) {
    173                return false;
    174            }
    175            if (!ObjectUtilities.equal(this.drawable, that.drawable)) {
    176                return false;
    177            }
    178            // seem to be the same...
    179            return true;
    180
    181        }
    182
    183        /**
    184         * Returns a hash code.
    185         *
    186         * @return A hash code.
    187         */
    188        public int hashCode() {
    189            int result;
    190            long temp;
    191            temp = Double.doubleToLongBits(this.x);
    192            result = (int) (temp ^ (temp >>> 32));
    193            temp = Double.doubleToLongBits(this.y);
    194            result = 29 * result + (int) (temp ^ (temp >>> 32));
    195            temp = Double.doubleToLongBits(this.width);
    196            result = 29 * result + (int) (temp ^ (temp >>> 32));
    197            temp = Double.doubleToLongBits(this.height);
    198            result = 29 * result + (int) (temp ^ (temp >>> 32));
    199            return result;
    200        }
    201
    202        /**
    203         * Returns a clone of the annotation.
    204         *
    205         * @return A clone.
    206         *
    207         * @throws CloneNotSupportedException  if the annotation can't be cloned.
    208         */
    209        public Object clone() throws CloneNotSupportedException {
    210            return super.clone();
    211        }
    212
    213    }