001    /* ===========================================================
002     * JFreeChart : a free chart library for the Java(tm) platform
003     * ===========================================================
004     *
005     * (C) Copyright 2000-2007, 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     * PlotRenderingInfo.java
029     * ----------------------
030     * (C) Copyright 2003-2007, 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     
047    package org.jfree.chart.plot;
048    
049    import java.awt.geom.Point2D;
050    import java.awt.geom.Rectangle2D;
051    import java.io.IOException;
052    import java.io.ObjectInputStream;
053    import java.io.ObjectOutputStream;
054    import java.io.Serializable;
055    import java.util.List;
056    
057    import org.jfree.chart.ChartRenderingInfo;
058    import org.jfree.io.SerialUtilities;
059    import org.jfree.util.ObjectUtilities;
060    
061    /**
062     * Stores information about the dimensions of a plot and its subplots.
063     */
064    public 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    }