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