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