    001/* ===========================================================
    002 * JFreeChart : a free chart library for the Java(tm) platform
    003 * ===========================================================
    004 *
    005 * (C) Copyright 2000-2011, 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 * [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 * PlotRenderingInfo.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 * 16-Sep-2003 : Version 1 (DG);
    038 * 23-Sep-2003 : Added Javadocs (DG);
    039 * 12-Nov-2004 : Added getSubplotCount() and findSubplot() methods (DG);
    040 * 01-Nov-2005 : Made 'owner' non-transient to fix bug 1344048 (DG);
    041 * ------------- JFREECHART 1.0.x ---------------------------------------------
    042 * 01-Dec-2006 : Implemented clone() method properly (DG);
    043 * 17-Apr-2007 : Fixed bug 1698965 (NPE in CombinedDomainXYPlot) (DG);
    044 *
    045 */
    046
    047package org.jfree.chart.plot;
    048
    049import java.awt.geom.Point2D;
    050import java.awt.geom.Rectangle2D;
    051import java.io.IOException;
    052import java.io.ObjectInputStream;
    053import java.io.ObjectOutputStream;
    054import java.io.Serializable;
    055import java.util.List;
    056
    057import org.jfree.chart.ChartRenderingInfo;
    058import org.jfree.io.SerialUtilities;
    059import org.jfree.util.ObjectUtilities;
    060
    061/**
    062 * Stores information about the dimensions of a plot and its subplots.
    063 */
    064public class PlotRenderingInfo implements Cloneable, Serializable {
    065
    066    /** For serialization. */
    067    private static final long serialVersionUID = 8446720134379617220L;
    068
    069    /** The owner of this info. */
    070    private ChartRenderingInfo owner;
    071
    072    /** The plot area. */
    073    private transient Rectangle2D plotArea;
    074
    075    /** The data area. */
    076    private transient Rectangle2D dataArea;
    077
    078    /**
    079     * Storage for the plot rendering info objects belonging to the subplots.
    080     */
    081    private List subplotInfo;
    082
    083    /**
    084     * Creates a new instance.
    085     *
    086     * @param owner  the owner (<code>null</code> permitted).
    087     */
    088    public PlotRenderingInfo(ChartRenderingInfo owner) {
    089        this.owner = owner;
    090        this.dataArea = new Rectangle2D.Double();
    091        this.subplotInfo = new java.util.ArrayList();
    092    }
    093
    094    /**
    095     * Returns the owner (as specified in the constructor).
    096     *
    097     * @return The owner (possibly <code>null</code>).
    098     */
    099    public ChartRenderingInfo getOwner() {
    100        return this.owner;
    101    }
    102
    103    /**
    104     * Returns the plot area (in Java2D space).
    105     *
    106     * @return The plot area (possibly <code>null</code>).
    107     *
    108     * @see #setPlotArea(Rectangle2D)
    109     */
    110    public Rectangle2D getPlotArea() {
    111        return this.plotArea;
    112    }
    113
    114    /**
    115     * Sets the plot area.
    116     *
    117     * @param area  the plot area (in Java2D space, <code>null</code>
    118     *     permitted but discouraged)
    119     *
    120     * @see #getPlotArea()
    121     */
    122    public void setPlotArea(Rectangle2D area) {
    123        this.plotArea = area;
    124    }
    125
    126    /**
    127     * Returns the plot's data area (in Java2D space).
    128     *
    129     * @return The data area (possibly <code>null</code>).
    130     *
    131     * @see #setDataArea(Rectangle2D)
    132     */
    133    public Rectangle2D getDataArea() {
    134        return this.dataArea;
    135    }
    136
    137    /**
    138     * Sets the data area.
    139     *
    140     * @param area  the data area (in Java2D space, <code>null</code> permitted
    141     *     but discouraged).
    142     *
    143     * @see #getDataArea()
    144     */
    145    public void setDataArea(Rectangle2D area) {
    146        this.dataArea = area;
    147    }
    148
    149    /**
    150     * Returns the number of subplots (possibly zero).
    151     *
    152     * @return The subplot count.
    153     */
    154    public int getSubplotCount() {
    155        return this.subplotInfo.size();
    156    }
    157
    158    /**
    159     * Adds the info for a subplot.
    160     *
    161     * @param info  the subplot info.
    162     *
    163     * @see #getSubplotInfo(int)
    164     */
    165    public void addSubplotInfo(PlotRenderingInfo info) {
    166        this.subplotInfo.add(info);
    167    }
    168
    169    /**
    170     * Returns the info for a subplot.
    171     *
    172     * @param index  the subplot index.
    173     *
    174     * @return The info.
    175     *
    176     * @see #addSubplotInfo(PlotRenderingInfo)
    177     */
    178    public PlotRenderingInfo getSubplotInfo(int index) {
    179        return (PlotRenderingInfo) this.subplotInfo.get(index);
    180    }
    181
    182    /**
    183     * Returns the index of the subplot that contains the specified
    184     * (x, y) point (the "source" point).  The source point will usually
    185     * come from a mouse click on a {@link org.jfree.chart.ChartPanel},
    186     * and this method is then used to determine the subplot that
    187     * contains the source point.
    188     *
    189     * @param source  the source point (in Java2D space, <code>null</code> not
    190     * permitted).
    191     *
    192     * @return The subplot index (or -1 if no subplot contains
    193     *         <code>source</code>).
    194     */
    195    public int getSubplotIndex(Point2D source) {
    196        if (source == null) {
    197            throw new IllegalArgumentException("Null 'source' argument.");
    198        }
    199        int subplotCount = getSubplotCount();
    200        for (int i = 0; i < subplotCount; i++) {
    201            PlotRenderingInfo info = getSubplotInfo(i);
    202            Rectangle2D area = info.getDataArea();
    203            if (area.contains(source)) {
    204                return i;
    205            }
    206        }
    207        return -1;
    208    }
    209
    210    /**
    211     * Tests this instance for equality against an arbitrary object.
    212     *
    213     * @param obj  the object (<code>null</code> permitted).
    214     *
    215     * @return A boolean.
    216     */
    217    public boolean equals(Object obj) {
    218        if (this == obj) {
    219            return true;
    220        }
    221        if (!(obj instanceof PlotRenderingInfo)) {
    222            return false;
    223        }
    224        PlotRenderingInfo that = (PlotRenderingInfo) obj;
    225        if (!ObjectUtilities.equal(this.dataArea, that.dataArea)) {
    226            return false;
    227        }
    228        if (!ObjectUtilities.equal(this.plotArea, that.plotArea)) {
    229            return false;
    230        }
    231        if (!ObjectUtilities.equal(this.subplotInfo, that.subplotInfo)) {
    232            return false;
    233        }
    234        return true;
    235    }
    236
    237    /**
    238     * Returns a clone of this object.
    239     *
    240     * @return A clone.
    241     *
    242     * @throws CloneNotSupportedException if there is a problem cloning.
    243     */
    244    public Object clone() throws CloneNotSupportedException {
    245        PlotRenderingInfo clone = (PlotRenderingInfo) super.clone();
    246        if (this.plotArea != null) {
    247            clone.plotArea = (Rectangle2D) this.plotArea.clone();
    248        }
    249        if (this.dataArea != null) {
    250            clone.dataArea = (Rectangle2D) this.dataArea.clone();
    251        }
    252        clone.subplotInfo = new java.util.ArrayList(this.subplotInfo.size());
    253        for (int i = 0; i < this.subplotInfo.size(); i++) {
    254            PlotRenderingInfo info
    255                    = (PlotRenderingInfo) this.subplotInfo.get(i);
    256            clone.subplotInfo.add(info.clone());
    257        }
    258        return clone;
    259    }
    260
    261    /**
    262     * Provides serialization support.
    263     *
    264     * @param stream  the output stream.
    265     *
    266     * @throws IOException  if there is an I/O error.
    267     */
    268    private void writeObject(ObjectOutputStream stream) throws IOException {
    269        stream.defaultWriteObject();
    270        SerialUtilities.writeShape(this.dataArea, stream);
    271        SerialUtilities.writeShape(this.plotArea, stream);
    272    }
    273
    274    /**
    275     * Provides serialization support.
    276     *
    277     * @param stream  the input stream.
    278     *
    279     * @throws IOException  if there is an I/O error.
    280     * @throws ClassNotFoundException  if there is a classpath problem.
    281     */
    282    private void readObject(ObjectInputStream stream)
    283            throws IOException, ClassNotFoundException {
    284        stream.defaultReadObject();
    285        this.dataArea = (Rectangle2D) SerialUtilities.readShape(stream);
    286        this.plotArea = (Rectangle2D) SerialUtilities.readShape(stream);
    287    }
    288
    289}