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