001/* ===========================================================
002 * JFreeChart : a free chart library for the Java(tm) platform
003 * ===========================================================
004 *
005 * (C) Copyright 2000-present, by David Gilbert 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 * [Oracle and Java are registered trademarks of Oracle and/or its affiliates. 
025 * Other names may be trademarks of their respective owners.]
026 *
027 * -------------------------
028 * AbstractXYAnnotation.java
029 * -------------------------
030 * (C) Copyright 2004-present, by David Gilbert.
031 *
032 * Original Author:  David Gilbert;
033 * Contributor(s):   Peter Kolb (patch 2809117);
034 *                   Tracy Hiltbrand (equals/hashCode comply with EqualsVerifier);
035 *
036 */
037
038package org.jfree.chart.annotations;
039
040import java.awt.Graphics2D;
041import java.awt.Shape;
042import java.awt.geom.Rectangle2D;
043import java.util.Objects;
044
045import org.jfree.chart.axis.ValueAxis;
046import org.jfree.chart.entity.EntityCollection;
047import org.jfree.chart.entity.XYAnnotationEntity;
048import org.jfree.chart.plot.PlotRenderingInfo;
049import org.jfree.chart.plot.XYPlot;
050
051/**
052 * The interface that must be supported by annotations that are to be added to
053 * an {@link XYPlot}.
054 */
055public abstract class AbstractXYAnnotation extends AbstractAnnotation
056        implements XYAnnotation {
057
058    /** The tool tip text. */
059    private String toolTipText;
060
061    /** The URL. */
062    private String url;
063
064    /**
065     * Creates a new instance that has no tool tip or URL specified.
066     */
067    protected AbstractXYAnnotation() {
068        super();
069        this.toolTipText = null;
070        this.url = null;
071    }
072
073    /**
074     * Returns the tool tip text for the annotation.  This will be displayed in
075     * a {@link org.jfree.chart.ChartPanel} when the mouse pointer hovers over
076     * the annotation.
077     *
078     * @return The tool tip text (possibly {@code null}).
079     *
080     * @see #setToolTipText(String)
081     */
082    public String getToolTipText() {
083        return this.toolTipText;
084    }
085
086    /**
087     * Sets the tool tip text for the annotation.
088     *
089     * @param text  the tool tip text ({@code null} permitted).
090     *
091     * @see #getToolTipText()
092     */
093    public void setToolTipText(String text) {
094        this.toolTipText = text;
095    }
096
097    /**
098     * Returns the URL for the annotation.  This URL will be used to provide
099     * hyperlinks when an HTML image map is created for the chart.
100     *
101     * @return The URL (possibly {@code null}).
102     *
103     * @see #setURL(String)
104     */
105    public String getURL() {
106        return this.url;
107    }
108
109    /**
110     * Sets the URL for the annotation.
111     *
112     * @param url  the URL ({@code null} permitted).
113     *
114     * @see #getURL()
115     */
116    public void setURL(String url) {
117        this.url = url;
118    }
119
120    /**
121     * Draws the annotation.
122     *
123     * @param g2  the graphics device.
124     * @param plot  the plot.
125     * @param dataArea  the data area.
126     * @param domainAxis  the domain axis.
127     * @param rangeAxis  the range axis.
128     * @param rendererIndex  the renderer index.
129     * @param info  if supplied, this info object will be populated with
130     *              entity information.
131     */
132    @Override
133    public abstract void draw(Graphics2D g2, XYPlot plot, Rectangle2D dataArea,
134                              ValueAxis domainAxis, ValueAxis rangeAxis,
135                              int rendererIndex,
136                              PlotRenderingInfo info);
137
138    /**
139     * A utility method for adding an {@link XYAnnotationEntity} to
140     * a {@link PlotRenderingInfo} instance.
141     *
142     * @param info  the plot rendering info ({@code null} permitted).
143     * @param hotspot  the hotspot area.
144     * @param rendererIndex  the renderer index.
145     * @param toolTipText  the tool tip text.
146     * @param urlText  the URL text.
147     */
148    protected void addEntity(PlotRenderingInfo info,
149                             Shape hotspot, int rendererIndex,
150                             String toolTipText, String urlText) {
151        if (info == null) {
152            return;
153        }
154        EntityCollection entities = info.getOwner().getEntityCollection();
155        if (entities == null) {
156            return;
157        }
158        XYAnnotationEntity entity = new XYAnnotationEntity(hotspot,
159                rendererIndex, toolTipText, urlText);
160        entities.add(entity);
161    }
162
163    /**
164     * Tests this annotation for equality with an arbitrary object.
165     *
166     * @param obj  the object ({@code null} permitted).
167     *
168     * @return A boolean.
169     */
170    @Override
171    public boolean equals(Object obj) {
172        if (obj == this) {
173            return true;
174        }
175        if (!(obj instanceof AbstractXYAnnotation)) {
176            return false;
177        }
178        AbstractXYAnnotation that = (AbstractXYAnnotation) obj;
179        if (!Objects.equals(this.toolTipText, that.toolTipText)) {
180            return false;
181        }
182        if (!Objects.equals(this.url, that.url)) {
183            return false;
184        }
185
186        // fix the "equals not symmetric" problem
187        if (!that.canEqual(this)) {
188            return false;
189        }
190
191        return super.equals(obj);
192    }
193
194    /**
195     * Ensures symmetry between super/subclass implementations of equals. For
196     * more detail, see http://jqno.nl/equalsverifier/manual/inheritance.
197     *
198     * @param other Object
199     * 
200     * @return true ONLY if the parameter is THIS class type
201     */
202    @Override
203    public boolean canEqual(Object other) {
204        // fix the "equals not symmetric" problem
205        return (other instanceof AbstractXYAnnotation);
206    }
207
208    /**
209     * Returns a hash code for this instance.
210     *
211     * @return A hash code.
212     */
213    @Override
214    public int hashCode() {
215        int result = super.hashCode(); // equals calls superclass, hashCode must also
216        result = 37 * result + Objects.hashCode(this.toolTipText);
217        result = 37 * result + Objects.hashCode(this.url);
218        return result;
219    }
220
221}