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 * CategoryItemEntity.java
029 * -----------------------
030 * (C) Copyright 2002-2008, by Object Refinery Limited and Contributors.
031 *
032 * Original Author:  David Gilbert (for Object Refinery Limited);
033 * Contributor(s):   Richard Atkinson;
034 *                   Christian W. Zuckschwerdt;
035 *
036 * Changes:
037 * --------
038 * 23-May-2002 : Version 1 (DG);
039 * 12-Jun-2002 : Added Javadoc comments (DG);
040 * 26-Jun-2002 : Added getImageMapAreaTag() method (DG);
041 * 05-Aug-2002 : Added new constructor to populate URLText
042 *               Moved getImageMapAreaTag() to ChartEntity (superclass) (RA);
043 * 03-Oct-2002 : Fixed errors reported by Checkstyle (DG);
044 * 30-Jul-2003 : Added CategoryDataset reference (CZ);
045 * 20-May-2004 : Added equals() and clone() methods, and implemented
046 *               Serializable (DG);
047 * 11-Jan-2005 : Removed deprecated code in preparation for 1.0.0 release (DG);
048 * ------------- JFREECHART 1.0.x ---------------------------------------------
049 * 18-May-2007 : Updated to use row and column keys to identify item (DG);
050 *
051 */
052
053package org.jfree.chart.entity;
054
055import java.awt.Shape;
056import java.io.Serializable;
057
058import org.jfree.data.category.CategoryDataset;
059import org.jfree.util.ObjectUtilities;
060
061/**
062 * A chart entity that represents one item within a category plot.
063 */
064public class CategoryItemEntity extends ChartEntity
065        implements Cloneable, Serializable {
066
067    /** For serialization. */
068    private static final long serialVersionUID = -8657249457902337349L;
069
070    /** The dataset. */
071    private CategoryDataset dataset;
072
073    /**
074     * The series (zero-based index).
075     *
076     * @deprecated As of 1.0.6, this field is redundant as you can derive the
077     *         index from the <code>rowKey</code> field.
078     */
079    private int series;
080
081    /**
082     * The category.
083     *
084     * @deprecated As of 1.0.6, this field is deprecated in favour of the
085     *         <code>columnKey</code> field.
086     */
087    private Object category;
088
089    /**
090     * The category index.
091     *
092     * @deprecated As of 1.0.6, this field is redundant as you can derive the
093     *         index from the <code>columnKey</code> field.
094     */
095    private int categoryIndex;
096
097    /**
098     * The row key.
099     *
100     * @since 1.0.6
101     */
102    private Comparable rowKey;
103
104    /**
105     * The column key.
106     *
107     * @since 1.0.6
108     */
109    private Comparable columnKey;
110
111    /**
112     * Creates a new category item entity.
113     *
114     * @param area  the area (<code>null</code> not permitted).
115     * @param toolTipText  the tool tip text.
116     * @param urlText  the URL text for HTML image maps.
117     * @param dataset  the dataset.
118     * @param series  the series (zero-based index).
119     * @param category  the category.
120     * @param categoryIndex  the category index.
121     *
122     * @deprecated As of 1.0.6, use {@link #CategoryItemEntity(Shape, String,
123     *         String, CategoryDataset, Comparable, Comparable)}.
124     */
125    public CategoryItemEntity(Shape area, String toolTipText, String urlText,
126                              CategoryDataset dataset,
127                              int series, Object category, int categoryIndex) {
128
129        super(area, toolTipText, urlText);
130        if (dataset == null) {
131            throw new IllegalArgumentException("Null 'dataset' argument.");
132        }
133        this.dataset = dataset;
134        this.series = series;
135        this.category = category;
136        this.categoryIndex = categoryIndex;
137        this.rowKey = dataset.getRowKey(series);
138        this.columnKey = dataset.getColumnKey(categoryIndex);
139    }
140
141    /**
142     * Creates a new entity instance for an item in the specified dataset.
143     *
144     * @param area  the 'hotspot' area (<code>null</code> not permitted).
145     * @param toolTipText  the tool tip text.
146     * @param urlText  the URL text.
147     * @param dataset  the dataset (<code>null</code> not permitted).
148     * @param rowKey  the row key (<code>null</code> not permitted).
149     * @param columnKey  the column key (<code>null</code> not permitted).
150     *
151     * @since 1.0.6
152     */
153    public CategoryItemEntity(Shape area, String toolTipText, String urlText,
154            CategoryDataset dataset, Comparable rowKey, Comparable columnKey) {
155        super(area, toolTipText, urlText);
156        if (dataset == null) {
157            throw new IllegalArgumentException("Null 'dataset' argument.");
158        }
159        this.dataset = dataset;
160        this.rowKey = rowKey;
161        this.columnKey = columnKey;
162
163        // populate the deprecated fields
164        this.series = dataset.getRowIndex(rowKey);
165        this.category = columnKey;
166        this.categoryIndex = dataset.getColumnIndex(columnKey);
167    }
168
169    /**
170     * Returns the dataset this entity refers to.  This can be used to
171     * differentiate between items in a chart that displays more than one
172     * dataset.
173     *
174     * @return The dataset (never <code>null</code>).
175     *
176     * @see #setDataset(CategoryDataset)
177     */
178    public CategoryDataset getDataset() {
179        return this.dataset;
180    }
181
182    /**
183     * Sets the dataset this entity refers to.
184     *
185     * @param dataset  the dataset (<code>null</code> not permitted).
186     *
187     * @see #getDataset()
188     */
189    public void setDataset(CategoryDataset dataset) {
190        if (dataset == null) {
191            throw new IllegalArgumentException("Null 'dataset' argument.");
192        }
193        this.dataset = dataset;
194    }
195
196    /**
197     * Returns the row key.
198     *
199     * @return The row key (never <code>null</code>).
200     *
201     * @since 1.0.6
202     *
203     * @see #setRowKey(Comparable)
204     */
205    public Comparable getRowKey() {
206        return this.rowKey;
207    }
208
209    /**
210     * Sets the row key.
211     *
212     * @param rowKey  the row key (<code>null</code> not permitted).
213     *
214     * @since 1.0.6
215     *
216     * @see #getRowKey()
217     */
218    public void setRowKey(Comparable rowKey) {
219        this.rowKey = rowKey;
220        // update the deprecated field
221        this.series = this.dataset.getRowIndex(rowKey);
222    }
223
224    /**
225     * Returns the column key.
226     *
227     * @return The column key (never <code>null</code>).
228     *
229     * @since 1.0.6
230     *
231     * @see #setColumnKey(Comparable)
232     */
233    public Comparable getColumnKey() {
234        return this.columnKey;
235    }
236
237    /**
238     * Sets the column key.
239     *
240     * @param columnKey  the column key (<code>null</code> not permitted).
241     *
242     * @since 1.0.6
243     *
244     * @see #getColumnKey()
245     */
246    public void setColumnKey(Comparable columnKey) {
247        this.columnKey = columnKey;
248        // update the deprecated fields
249        this.category = columnKey;
250        this.categoryIndex = this.dataset.getColumnIndex(columnKey);
251    }
252
253    /**
254     * Returns the series index.
255     *
256     * @return The series index.
257     *
258     * @see #setSeries(int)
259     *
260     * @deprecated As of 1.0.6, you can derive this information from the
261     *         {@link #getRowKey()} method.
262     */
263    public int getSeries() {
264        return this.series;
265    }
266
267    /**
268     * Sets the series index.
269     *
270     * @param series  the series index (zero-based).
271     *
272     * @see #getSeries()
273     *
274     * @deprecated As of 1.0.6, you should use {@link #setRowKey(Comparable)}
275     *         to designate the series.
276     */
277    public void setSeries(int series) {
278        this.series = series;
279    }
280
281    /**
282     * Returns the category.
283     *
284     * @return The category (possibly <code>null</code>).
285     *
286     * @see #setCategory(Object)
287     *
288     * @deprecated The return type for this method should be
289     *         <code>Comparable</code>, so it has been deprecated as of
290     *         version 1.0.6 and replaced by {@link #getColumnKey()}.
291     */
292    public Object getCategory() {
293        return this.category;
294    }
295
296    /**
297     * Sets the category.
298     *
299     * @param category  the category (<code>null</code> permitted).
300     *
301     * @see #getCategory()
302     *
303     * @deprecated As of version 1.0.6, use {@link #setColumnKey(Comparable)}.
304     */
305    public void setCategory(Object category) {
306        this.category = category;
307    }
308
309    /**
310     * Returns the category index.
311     *
312     * @return The index.
313     *
314     * @see #setCategoryIndex(int)
315     *
316     * @deprecated As of 1.0.6, you can derive this information from the
317     *         {@link #getColumnKey()} method.
318     */
319    public int getCategoryIndex() {
320        return this.categoryIndex;
321    }
322
323    /**
324     * Sets the category index.
325     *
326     * @param index  the category index.
327     *
328     * @see #getCategoryIndex()
329     *
330     * @deprecated As of 1.0.6, use {@link #setColumnKey(Comparable)} to
331     *         designate the category.
332     */
333    public void setCategoryIndex(int index) {
334        this.categoryIndex = index;
335    }
336
337    /**
338     * Returns a string representing this object (useful for debugging
339     * purposes).
340     *
341     * @return A string (never <code>null</code>).
342     */
343    public String toString() {
344        return "CategoryItemEntity: rowKey=" + this.rowKey
345               + ", columnKey=" + this.columnKey + ", dataset=" + this.dataset;
346    }
347
348    /**
349     * Tests the entity for equality with an arbitrary object.
350     *
351     * @param obj  the object (<code>null</code> permitted).
352     *
353     * @return A boolean.
354     */
355    public boolean equals(Object obj) {
356        if (obj == this) {
357            return true;
358        }
359        if (!(obj instanceof CategoryItemEntity)) {
360            return false;
361        }
362        CategoryItemEntity that = (CategoryItemEntity) obj;
363        if (!this.rowKey.equals(that.rowKey)) {
364            return false;
365        }
366        if (!this.columnKey.equals(that.columnKey)) {
367            return false;
368        }
369        if (!ObjectUtilities.equal(this.dataset, that.dataset)) {
370            return false;
371        }
372
373        // check the deprecated fields
374        if (this.categoryIndex != that.categoryIndex) {
375            return false;
376        }
377        if (this.series != that.series) {
378            return false;
379        }
380        if (!ObjectUtilities.equal(this.category, that.category)) {
381            return false;
382        }
383        return super.equals(obj);
384    }
385
386}