001 /* =========================================================== 002 * JFreeChart : a free chart library for the Java(tm) platform 003 * =========================================================== 004 * 005 * (C) Copyright 2000-2005, 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 * Marker.java 029 * ----------- 030 * (C) Copyright 2002-2005, by Object Refinery Limited. 031 * 032 * Original Author: David Gilbert (for Object Refinery Limited); 033 * Contributor(s): Nicolas Brodu; 034 * 035 * $Id: Marker.java,v 1.10.2.3 2005/10/25 20:52:08 mungady Exp $ 036 * 037 * Changes (since 2-Jul-2002) 038 * -------------------------- 039 * 02-Jul-2002 : Added extra constructor, standard header and Javadoc 040 * comments (DG); 041 * 20-Aug-2002 : Added the outline stroke attribute (DG); 042 * 02-Oct-2002 : Fixed errors reported by Checkstyle (DG); 043 * 16-Oct-2002 : Added new constructor (DG); 044 * 26-Mar-2003 : Implemented Serializable (DG); 045 * 21-May-2003 : Added labels (DG); 046 * 11-Sep-2003 : Implemented Cloneable (NB); 047 * 05-Nov-2003 : Added checks to ensure some attributes are never null (DG); 048 * 11-Feb-2003 : Moved to org.jfree.chart.plot package, plus significant API 049 * changes to support IntervalMarker in plots (DG); 050 * 14-Jun-2004 : Updated equals() method (DG); 051 * 21-Jan-2005 : Added settings to control direction of horizontal and 052 * vertical label offsets (DG); 053 * 01-Jun-2005 : Modified to use only one label offset type - this will be 054 * applied to the domain or range axis as appropriate (DG); 055 * 06-Jun-2005 : Fix equals() method to handle GradientPaint (DG); 056 * 19-Aug-2005 : Changed constructor from public --> protected (DG); 057 * 058 */ 059 060 package org.jfree.chart.plot; 061 062 import java.awt.BasicStroke; 063 import java.awt.Color; 064 import java.awt.Font; 065 import java.awt.Paint; 066 import java.awt.Stroke; 067 import java.io.IOException; 068 import java.io.ObjectInputStream; 069 import java.io.ObjectOutputStream; 070 import java.io.Serializable; 071 072 import org.jfree.io.SerialUtilities; 073 import org.jfree.ui.LengthAdjustmentType; 074 import org.jfree.ui.RectangleAnchor; 075 import org.jfree.ui.RectangleInsets; 076 import org.jfree.ui.TextAnchor; 077 import org.jfree.util.ObjectUtilities; 078 import org.jfree.util.PaintUtilities; 079 080 /** 081 * The base class for markers that can be added to plots to highlight a value 082 * or range of values. 083 */ 084 public abstract class Marker implements Cloneable, Serializable { 085 086 /** For serialization. */ 087 private static final long serialVersionUID = -734389651405327166L; 088 089 /** The paint. */ 090 private transient Paint paint; 091 092 /** The stroke. */ 093 private transient Stroke stroke; 094 095 /** The outline paint. */ 096 private transient Paint outlinePaint; 097 098 /** The outline stroke. */ 099 private transient Stroke outlineStroke; 100 101 /** The alpha transparency. */ 102 private float alpha; 103 104 /** The label. */ 105 private String label = null; 106 107 /** The label font. */ 108 private Font labelFont; 109 110 /** The label paint. */ 111 private transient Paint labelPaint; 112 113 /** The label position. */ 114 private RectangleAnchor labelAnchor; 115 116 /** The text anchor for the label. */ 117 private TextAnchor labelTextAnchor; 118 119 /** The label offset from the marker rectangle. */ 120 private RectangleInsets labelOffset; 121 122 /** 123 * The offset type for the domain or range axis (never <code>null</code>). 124 */ 125 private LengthAdjustmentType labelOffsetType; 126 127 /** 128 * Creates a new marker with default attributes. 129 */ 130 protected Marker() { 131 this(Color.gray); 132 } 133 134 /** 135 * Constructs a new marker. 136 * 137 * @param paint the paint (<code>null</code> not permitted). 138 */ 139 protected Marker(Paint paint) { 140 this( 141 paint, new BasicStroke(0.5f), Color.gray, 142 new BasicStroke(0.5f), 0.80f 143 ); 144 } 145 146 /** 147 * Constructs a new marker. 148 * 149 * @param paint the paint (<code>null</code> not permitted). 150 * @param stroke the stroke (<code>null</code> not permitted). 151 * @param outlinePaint the outline paint (<code>null</code> permitted). 152 * @param outlineStroke the outline stroke (<code>null</code> permitted). 153 * @param alpha the alpha transparency. 154 */ 155 protected Marker(Paint paint, Stroke stroke, 156 Paint outlinePaint, Stroke outlineStroke, 157 float alpha) { 158 159 if (paint == null) { 160 throw new IllegalArgumentException("Null 'paint' argument."); 161 } 162 if (stroke == null) { 163 throw new IllegalArgumentException("Null 'stroke' argument."); 164 } 165 166 this.paint = paint; 167 this.stroke = stroke; 168 this.outlinePaint = outlinePaint; 169 this.outlineStroke = outlineStroke; 170 this.alpha = alpha; 171 172 this.labelFont = new Font("SansSerif", Font.PLAIN, 9); 173 this.labelPaint = Color.black; 174 this.labelAnchor = RectangleAnchor.TOP_LEFT; 175 this.labelOffset = new RectangleInsets(3.0, 3.0, 3.0, 3.0); 176 this.labelOffsetType = LengthAdjustmentType.CONTRACT; 177 this.labelTextAnchor = TextAnchor.CENTER; 178 179 } 180 181 /** 182 * Returns the paint. 183 * 184 * @return The paint (never <code>null</code>). 185 */ 186 public Paint getPaint() { 187 return this.paint; 188 } 189 190 /** 191 * Sets the paint. 192 * 193 * @param paint the paint (<code>null</code> not permitted). 194 */ 195 public void setPaint(Paint paint) { 196 if (paint == null) { 197 throw new IllegalArgumentException("Null 'paint' argument."); 198 } 199 this.paint = paint; 200 } 201 202 /** 203 * Returns the stroke. 204 * 205 * @return The stroke (never <code>null</code>). 206 */ 207 public Stroke getStroke() { 208 return this.stroke; 209 } 210 211 /** 212 * Sets the stroke. 213 * 214 * @param stroke the stroke (<code>null</code> not permitted). 215 */ 216 public void setStroke(Stroke stroke) { 217 if (stroke == null) { 218 throw new IllegalArgumentException("Null 'stroke' argument."); 219 } 220 this.stroke = stroke; 221 } 222 223 /** 224 * Returns the outline paint. 225 * 226 * @return The outline paint (possibly <code>null</code>). 227 */ 228 public Paint getOutlinePaint() { 229 return this.outlinePaint; 230 } 231 232 /** 233 * Sets the outline paint. 234 * 235 * @param paint the paint (<code>null</code> permitted). 236 */ 237 public void setOutlinePaint(Paint paint) { 238 this.outlinePaint = paint; 239 } 240 241 /** 242 * Returns the outline stroke. 243 * 244 * @return The outline stroke (possibly <code>null</code>). 245 */ 246 public Stroke getOutlineStroke() { 247 return this.outlineStroke; 248 } 249 250 /** 251 * Sets the outline stroke. 252 * 253 * @param stroke the stroke (<code>null</code> permitted). 254 */ 255 public void setOutlineStroke(Stroke stroke) { 256 this.outlineStroke = stroke; 257 } 258 259 /** 260 * Returns the alpha transparency. 261 * 262 * @return The alpha transparency. 263 */ 264 public float getAlpha() { 265 return this.alpha; 266 } 267 268 /** 269 * Sets the alpha transparency. 270 * 271 * @param alpha the alpha transparency. 272 */ 273 public void setAlpha(float alpha) { 274 this.alpha = alpha; 275 } 276 277 /** 278 * Returns the label (if <code>null</code> no label is displayed). 279 * 280 * @return The label (possibly <code>null</code>). 281 */ 282 public String getLabel() { 283 return this.label; 284 } 285 286 /** 287 * Sets the label (if <code>null</code> no label is displayed). 288 * 289 * @param label the label (<code>null</code> permitted). 290 */ 291 public void setLabel(String label) { 292 this.label = label; 293 } 294 295 /** 296 * Returns the label font. 297 * 298 * @return The label font (never <code>null</code>). 299 */ 300 public Font getLabelFont() { 301 return this.labelFont; 302 } 303 304 /** 305 * Sets the label font. 306 * 307 * @param font the font (<code>null</code> not permitted). 308 */ 309 public void setLabelFont(Font font) { 310 if (font == null) { 311 throw new IllegalArgumentException("Null 'font' argument."); 312 } 313 this.labelFont = font; 314 } 315 316 /** 317 * Returns the label paint. 318 * 319 * @return The label paint (never </code>null</code>). 320 */ 321 public Paint getLabelPaint() { 322 return this.labelPaint; 323 } 324 325 /** 326 * Sets the label paint. 327 * 328 * @param paint the paint (<code>null</code> not permitted). 329 */ 330 public void setLabelPaint(Paint paint) { 331 if (paint == null) { 332 throw new IllegalArgumentException("Null 'paint' argument."); 333 } 334 this.labelPaint = paint; 335 } 336 337 /** 338 * Returns the label anchor. 339 * 340 * @return The label anchor (never <code>null</code>). 341 */ 342 public RectangleAnchor getLabelAnchor() { 343 return this.labelAnchor; 344 } 345 346 /** 347 * Sets the label anchor. 348 * 349 * @param anchor the anchor (<code>null</code> not permitted). 350 */ 351 public void setLabelAnchor(RectangleAnchor anchor) { 352 if (anchor == null) { 353 throw new IllegalArgumentException("Null 'anchor' argument."); 354 } 355 this.labelAnchor = anchor; 356 } 357 358 /** 359 * Returns the label offset. 360 * 361 * @return The label offset (never <code>null</code>). 362 */ 363 public RectangleInsets getLabelOffset() { 364 return this.labelOffset; 365 } 366 367 /** 368 * Sets the label offset. 369 * 370 * @param offset the label offset (<code>null</code> not permitted). 371 */ 372 public void setLabelOffset(RectangleInsets offset) { 373 if (offset == null) { 374 throw new IllegalArgumentException("Null 'offset' argument."); 375 } 376 this.labelOffset = offset; 377 } 378 379 /** 380 * Returns the label offset type. 381 * 382 * @return The type (never <code>null</code>). 383 */ 384 public LengthAdjustmentType getLabelOffsetType() { 385 return this.labelOffsetType; 386 } 387 388 /** 389 * Sets the label offset type. 390 * 391 * @param adj the type (<code>null</code> not permitted). 392 */ 393 public void setLabelOffsetType(LengthAdjustmentType adj) { 394 if (adj == null) { 395 throw new IllegalArgumentException("Null 'adj' argument."); 396 } 397 this.labelOffsetType = adj; 398 } 399 400 /** 401 * Returns the label text anchor. 402 * 403 * @return The label text anchor (never <code>null</code>). 404 */ 405 public TextAnchor getLabelTextAnchor() { 406 return this.labelTextAnchor; 407 } 408 409 /** 410 * Sets the label text anchor. 411 * 412 * @param anchor the label text anchor (<code>null</code> not permitted). 413 */ 414 public void setLabelTextAnchor(TextAnchor anchor) { 415 if (anchor == null) { 416 throw new IllegalArgumentException("Null 'anchor' argument."); 417 } 418 this.labelTextAnchor = anchor; 419 } 420 421 /** 422 * Tests the marker for equality with an arbitrary object. 423 * 424 * @param obj the object (<code>null</code> permitted). 425 * 426 * @return A boolean. 427 */ 428 public boolean equals(Object obj) { 429 if (obj == this) { 430 return true; 431 } 432 if (!(obj instanceof Marker)) { 433 return false; 434 } 435 Marker that = (Marker) obj; 436 if (!PaintUtilities.equal(this.paint, that.paint)) { 437 return false; 438 } 439 if (!ObjectUtilities.equal(this.stroke, that.stroke)) { 440 return false; 441 } 442 if (!PaintUtilities.equal(this.outlinePaint, that.outlinePaint)) { 443 return false; 444 } 445 if (!ObjectUtilities.equal(this.outlineStroke, that.outlineStroke)) { 446 return false; 447 } 448 if (this.alpha != that.alpha) { 449 return false; 450 } 451 if (!ObjectUtilities.equal(this.label, that.label)) { 452 return false; 453 } 454 if (!ObjectUtilities.equal(this.labelFont, that.labelFont)) { 455 return false; 456 } 457 if (!PaintUtilities.equal(this.labelPaint, that.labelPaint)) { 458 return false; 459 } 460 if (this.labelAnchor != that.labelAnchor) { 461 return false; 462 } 463 if (this.labelTextAnchor != that.labelTextAnchor) { 464 return false; 465 } 466 if (!ObjectUtilities.equal(this.labelOffset, that.labelOffset)) { 467 return false; 468 } 469 if (!this.labelOffsetType.equals(that.labelOffsetType)) { 470 return false; 471 } 472 return true; 473 } 474 475 /** 476 * Creates a clone of the marker. 477 * 478 * @return A clone. 479 * 480 * @throws CloneNotSupportedException never. 481 */ 482 public Object clone() throws CloneNotSupportedException { 483 return super.clone(); 484 } 485 486 /** 487 * Provides serialization support. 488 * 489 * @param stream the output stream. 490 * 491 * @throws IOException if there is an I/O error. 492 */ 493 private void writeObject(ObjectOutputStream stream) throws IOException { 494 stream.defaultWriteObject(); 495 SerialUtilities.writePaint(this.paint, stream); 496 SerialUtilities.writeStroke(this.stroke, stream); 497 SerialUtilities.writePaint(this.outlinePaint, stream); 498 SerialUtilities.writeStroke(this.outlineStroke, stream); 499 SerialUtilities.writePaint(this.labelPaint, stream); 500 } 501 502 /** 503 * Provides serialization support. 504 * 505 * @param stream the input stream. 506 * 507 * @throws IOException if there is an I/O error. 508 * @throws ClassNotFoundException if there is a classpath problem. 509 */ 510 private void readObject(ObjectInputStream stream) 511 throws IOException, ClassNotFoundException { 512 stream.defaultReadObject(); 513 this.paint = SerialUtilities.readPaint(stream); 514 this.stroke = SerialUtilities.readStroke(stream); 515 this.outlinePaint = SerialUtilities.readPaint(stream); 516 this.outlineStroke = SerialUtilities.readStroke(stream); 517 this.labelPaint = SerialUtilities.readPaint(stream); 518 } 519 520 }