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 * TextAnnotation.java 029 * ------------------- 030 * (C) Copyright 2002-2008, by Object Refinery Limited. 031 * 032 * Original Author: David Gilbert (for Object Refinery Limited); 033 * Contributor(s): -; 034 * 035 * Changes: 036 * -------- 037 * 28-Aug-2002 : Version 1 (DG); 038 * 07-Nov-2002 : Fixed errors reported by Checkstyle, added accessor 039 * methods (DG); 040 * 13-Jan-2003 : Reviewed Javadocs (DG); 041 * 26-Mar-2003 : Implemented Serializable (DG); 042 * 02-Jun-2003 : Added anchor and rotation settings (DG); 043 * 19-Aug-2003 : Added equals() method and implemented Cloneable (DG); 044 * 29-Sep-2004 : Updated equals() method (DG); 045 * 06-Jun-2005 : Fixed equals() method to work with GradientPaint (DG); 046 * ------------- JFREECHART 1.0.x --------------------------------------------- 047 * 16-Jan-2007 : Added argument checks, fixed hashCode() method and updated 048 * API docs (DG); 049 * 050 */ 051 052 package org.jfree.chart.annotations; 053 054 import java.awt.Color; 055 import java.awt.Font; 056 import java.awt.Paint; 057 import java.io.IOException; 058 import java.io.ObjectInputStream; 059 import java.io.ObjectOutputStream; 060 import java.io.Serializable; 061 062 import org.jfree.chart.HashUtilities; 063 import org.jfree.io.SerialUtilities; 064 import org.jfree.ui.TextAnchor; 065 import org.jfree.util.ObjectUtilities; 066 import org.jfree.util.PaintUtilities; 067 068 /** 069 * A base class for text annotations. This class records the content but not 070 * the location of the annotation. 071 */ 072 public class TextAnnotation implements Serializable { 073 074 /** For serialization. */ 075 private static final long serialVersionUID = 7008912287533127432L; 076 077 /** The default font. */ 078 public static final Font DEFAULT_FONT 079 = new Font("SansSerif", Font.PLAIN, 10); 080 081 /** The default paint. */ 082 public static final Paint DEFAULT_PAINT = Color.black; 083 084 /** The default text anchor. */ 085 public static final TextAnchor DEFAULT_TEXT_ANCHOR = TextAnchor.CENTER; 086 087 /** The default rotation anchor. */ 088 public static final TextAnchor DEFAULT_ROTATION_ANCHOR = TextAnchor.CENTER; 089 090 /** The default rotation angle. */ 091 public static final double DEFAULT_ROTATION_ANGLE = 0.0; 092 093 /** The text. */ 094 private String text; 095 096 /** The font. */ 097 private Font font; 098 099 /** The paint. */ 100 private transient Paint paint; 101 102 /** The text anchor. */ 103 private TextAnchor textAnchor; 104 105 /** The rotation anchor. */ 106 private TextAnchor rotationAnchor; 107 108 /** The rotation angle. */ 109 private double rotationAngle; 110 111 /** 112 * Creates a text annotation with default settings. 113 * 114 * @param text the text (<code>null</code> not permitted). 115 */ 116 protected TextAnnotation(String text) { 117 if (text == null) { 118 throw new IllegalArgumentException("Null 'text' argument."); 119 } 120 this.text = text; 121 this.font = DEFAULT_FONT; 122 this.paint = DEFAULT_PAINT; 123 this.textAnchor = DEFAULT_TEXT_ANCHOR; 124 this.rotationAnchor = DEFAULT_ROTATION_ANCHOR; 125 this.rotationAngle = DEFAULT_ROTATION_ANGLE; 126 } 127 128 /** 129 * Returns the text for the annotation. 130 * 131 * @return The text (never <code>null</code>). 132 * 133 * @see #setText(String) 134 */ 135 public String getText() { 136 return this.text; 137 } 138 139 /** 140 * Sets the text for the annotation. 141 * 142 * @param text the text (<code>null</code> not permitted). 143 * 144 * @see #getText() 145 */ 146 public void setText(String text) { 147 if (text == null) { 148 throw new IllegalArgumentException("Null 'text' argument."); 149 } 150 this.text = text; 151 } 152 153 /** 154 * Returns the font for the annotation. 155 * 156 * @return The font (never <code>null</code>). 157 * 158 * @see #setFont(Font) 159 */ 160 public Font getFont() { 161 return this.font; 162 } 163 164 /** 165 * Sets the font for the annotation. 166 * 167 * @param font the font (<code>null</code> not permitted). 168 * 169 * @see #getFont() 170 */ 171 public void setFont(Font font) { 172 if (font == null) { 173 throw new IllegalArgumentException("Null 'font' argument."); 174 } 175 this.font = font; 176 } 177 178 /** 179 * Returns the paint for the annotation. 180 * 181 * @return The paint (never <code>null</code>). 182 * 183 * @see #setPaint(Paint) 184 */ 185 public Paint getPaint() { 186 return this.paint; 187 } 188 189 /** 190 * Sets the paint for the annotation. 191 * 192 * @param paint the paint (<code>null</code> not permitted). 193 * 194 * @see #getPaint() 195 */ 196 public void setPaint(Paint paint) { 197 if (paint == null) { 198 throw new IllegalArgumentException("Null 'paint' argument."); 199 } 200 this.paint = paint; 201 } 202 203 /** 204 * Returns the text anchor. 205 * 206 * @return The text anchor. 207 * 208 * @see #setTextAnchor(TextAnchor) 209 */ 210 public TextAnchor getTextAnchor() { 211 return this.textAnchor; 212 } 213 214 /** 215 * Sets the text anchor (the point on the text bounding rectangle that is 216 * aligned to the (x, y) coordinate of the annotation). 217 * 218 * @param anchor the anchor point (<code>null</code> not permitted). 219 * 220 * @see #getTextAnchor() 221 */ 222 public void setTextAnchor(TextAnchor anchor) { 223 if (anchor == null) { 224 throw new IllegalArgumentException("Null 'anchor' argument."); 225 } 226 this.textAnchor = anchor; 227 } 228 229 /** 230 * Returns the rotation anchor. 231 * 232 * @return The rotation anchor point (never <code>null</code>). 233 * 234 * @see #setRotationAnchor(TextAnchor) 235 */ 236 public TextAnchor getRotationAnchor() { 237 return this.rotationAnchor; 238 } 239 240 /** 241 * Sets the rotation anchor point. 242 * 243 * @param anchor the anchor (<code>null</code> not permitted). 244 * 245 * @see #getRotationAnchor() 246 */ 247 public void setRotationAnchor(TextAnchor anchor) { 248 this.rotationAnchor = anchor; 249 } 250 251 /** 252 * Returns the rotation angle in radians. 253 * 254 * @return The rotation angle. 255 * 256 * @see #setRotationAngle(double) 257 */ 258 public double getRotationAngle() { 259 return this.rotationAngle; 260 } 261 262 /** 263 * Sets the rotation angle. The angle is measured clockwise in radians. 264 * 265 * @param angle the angle (in radians). 266 * 267 * @see #getRotationAngle() 268 */ 269 public void setRotationAngle(double angle) { 270 this.rotationAngle = angle; 271 } 272 273 /** 274 * Tests this object for equality with an arbitrary object. 275 * 276 * @param obj the object (<code>null</code> permitted). 277 * 278 * @return <code>true</code> or <code>false</code>. 279 */ 280 public boolean equals(Object obj) { 281 if (obj == this) { 282 return true; 283 } 284 // now try to reject equality... 285 if (!(obj instanceof TextAnnotation)) { 286 return false; 287 } 288 TextAnnotation that = (TextAnnotation) obj; 289 if (!ObjectUtilities.equal(this.text, that.getText())) { 290 return false; 291 } 292 if (!ObjectUtilities.equal(this.font, that.getFont())) { 293 return false; 294 } 295 if (!PaintUtilities.equal(this.paint, that.getPaint())) { 296 return false; 297 } 298 if (!ObjectUtilities.equal(this.textAnchor, that.getTextAnchor())) { 299 return false; 300 } 301 if (!ObjectUtilities.equal(this.rotationAnchor, 302 that.getRotationAnchor())) { 303 return false; 304 } 305 if (this.rotationAngle != that.getRotationAngle()) { 306 return false; 307 } 308 309 // seem to be the same... 310 return true; 311 312 } 313 314 /** 315 * Returns a hash code for this instance. 316 * 317 * @return A hash code. 318 */ 319 public int hashCode() { 320 int result = 193; 321 result = 37 * result + this.font.hashCode(); 322 result = 37 * result + HashUtilities.hashCodeForPaint(this.paint); 323 result = 37 * result + this.rotationAnchor.hashCode(); 324 long temp = Double.doubleToLongBits(this.rotationAngle); 325 result = 37 * result + (int) (temp ^ (temp >>> 32)); 326 result = 37 * result + this.text.hashCode(); 327 result = 37 * result + this.textAnchor.hashCode(); 328 return result; 329 } 330 331 /** 332 * Provides serialization support. 333 * 334 * @param stream the output stream. 335 * 336 * @throws IOException if there is an I/O error. 337 */ 338 private void writeObject(ObjectOutputStream stream) throws IOException { 339 stream.defaultWriteObject(); 340 SerialUtilities.writePaint(this.paint, stream); 341 } 342 343 /** 344 * Provides serialization support. 345 * 346 * @param stream the input stream. 347 * 348 * @throws IOException if there is an I/O error. 349 * @throws ClassNotFoundException if there is a classpath problem. 350 */ 351 private void readObject(ObjectInputStream stream) 352 throws IOException, ClassNotFoundException { 353 stream.defaultReadObject(); 354 this.paint = SerialUtilities.readPaint(stream); 355 } 356 357 }