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 }