Frames | No Frames |
1: /* =========================================================== 2: * JFreeChart : a free chart library for the Java(tm) platform 3: * =========================================================== 4: * 5: * (C) Copyright 2000-2006, by Object Refinery Limited and Contributors. 6: * 7: * Project Info: http://www.jfree.org/jfreechart/index.html 8: * 9: * This library is free software; you can redistribute it and/or modify it 10: * under the terms of the GNU Lesser General Public License as published by 11: * the Free Software Foundation; either version 2.1 of the License, or 12: * (at your option) any later version. 13: * 14: * This library is distributed in the hope that it will be useful, but 15: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 16: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 17: * License for more details. 18: * 19: * You should have received a copy of the GNU Lesser General Public 20: * License along with this library; if not, write to the Free Software 21: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 22: * USA. 23: * 24: * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 25: * in the United States and other countries.] 26: * 27: * ----------- 28: * Marker.java 29: * ----------- 30: * (C) Copyright 2002-2006, by Object Refinery Limited. 31: * 32: * Original Author: David Gilbert (for Object Refinery Limited); 33: * Contributor(s): Nicolas Brodu; 34: * 35: * $Id: Marker.java,v 1.10.2.4 2006/07/03 15:55:15 mungady Exp $ 36: * 37: * Changes (since 2-Jul-2002) 38: * -------------------------- 39: * 02-Jul-2002 : Added extra constructor, standard header and Javadoc 40: * comments (DG); 41: * 20-Aug-2002 : Added the outline stroke attribute (DG); 42: * 02-Oct-2002 : Fixed errors reported by Checkstyle (DG); 43: * 16-Oct-2002 : Added new constructor (DG); 44: * 26-Mar-2003 : Implemented Serializable (DG); 45: * 21-May-2003 : Added labels (DG); 46: * 11-Sep-2003 : Implemented Cloneable (NB); 47: * 05-Nov-2003 : Added checks to ensure some attributes are never null (DG); 48: * 11-Feb-2003 : Moved to org.jfree.chart.plot package, plus significant API 49: * changes to support IntervalMarker in plots (DG); 50: * 14-Jun-2004 : Updated equals() method (DG); 51: * 21-Jan-2005 : Added settings to control direction of horizontal and 52: * vertical label offsets (DG); 53: * 01-Jun-2005 : Modified to use only one label offset type - this will be 54: * applied to the domain or range axis as appropriate (DG); 55: * 06-Jun-2005 : Fix equals() method to handle GradientPaint (DG); 56: * 19-Aug-2005 : Changed constructor from public --> protected (DG); 57: * 58: */ 59: 60: package org.jfree.chart.plot; 61: 62: import java.awt.BasicStroke; 63: import java.awt.Color; 64: import java.awt.Font; 65: import java.awt.Paint; 66: import java.awt.Stroke; 67: import java.io.IOException; 68: import java.io.ObjectInputStream; 69: import java.io.ObjectOutputStream; 70: import java.io.Serializable; 71: 72: import org.jfree.io.SerialUtilities; 73: import org.jfree.ui.LengthAdjustmentType; 74: import org.jfree.ui.RectangleAnchor; 75: import org.jfree.ui.RectangleInsets; 76: import org.jfree.ui.TextAnchor; 77: import org.jfree.util.ObjectUtilities; 78: import org.jfree.util.PaintUtilities; 79: 80: /** 81: * The base class for markers that can be added to plots to highlight a value 82: * or range of values. 83: * <br><br> 84: * Note that there is no listener mechanism for markers, so changing the 85: * attributes for a marker will not lead to any automatic chart repainting. 86: */ 87: public abstract class Marker implements Cloneable, Serializable { 88: 89: /** For serialization. */ 90: private static final long serialVersionUID = -734389651405327166L; 91: 92: /** The paint. */ 93: private transient Paint paint; 94: 95: /** The stroke. */ 96: private transient Stroke stroke; 97: 98: /** The outline paint. */ 99: private transient Paint outlinePaint; 100: 101: /** The outline stroke. */ 102: private transient Stroke outlineStroke; 103: 104: /** The alpha transparency. */ 105: private float alpha; 106: 107: /** The label. */ 108: private String label = null; 109: 110: /** The label font. */ 111: private Font labelFont; 112: 113: /** The label paint. */ 114: private transient Paint labelPaint; 115: 116: /** The label position. */ 117: private RectangleAnchor labelAnchor; 118: 119: /** The text anchor for the label. */ 120: private TextAnchor labelTextAnchor; 121: 122: /** The label offset from the marker rectangle. */ 123: private RectangleInsets labelOffset; 124: 125: /** 126: * The offset type for the domain or range axis (never <code>null</code>). 127: */ 128: private LengthAdjustmentType labelOffsetType; 129: 130: /** 131: * Creates a new marker with default attributes. 132: */ 133: protected Marker() { 134: this(Color.gray); 135: } 136: 137: /** 138: * Constructs a new marker. 139: * 140: * @param paint the paint (<code>null</code> not permitted). 141: */ 142: protected Marker(Paint paint) { 143: this(paint, new BasicStroke(0.5f), Color.gray, new BasicStroke(0.5f), 144: 0.80f); 145: } 146: 147: /** 148: * Constructs a new marker. 149: * 150: * @param paint the paint (<code>null</code> not permitted). 151: * @param stroke the stroke (<code>null</code> not permitted). 152: * @param outlinePaint the outline paint (<code>null</code> permitted). 153: * @param outlineStroke the outline stroke (<code>null</code> permitted). 154: * @param alpha the alpha transparency (must be in the range 0.0f to 155: * 1.0f). 156: * 157: * @throws IllegalArgumentException if <code>paint</code> or 158: * <code>stroke</code> is <code>null</code>, or <code>alpha</code> is 159: * not in the specified range. 160: */ 161: protected Marker(Paint paint, Stroke stroke, 162: Paint outlinePaint, Stroke outlineStroke, 163: float alpha) { 164: 165: if (paint == null) { 166: throw new IllegalArgumentException("Null 'paint' argument."); 167: } 168: if (stroke == null) { 169: throw new IllegalArgumentException("Null 'stroke' argument."); 170: } 171: if (alpha < 0.0f || alpha > 1.0f) 172: throw new IllegalArgumentException( 173: "The 'alpha' value must be in the range 0.0f to 1.0f"); 174: 175: this.paint = paint; 176: this.stroke = stroke; 177: this.outlinePaint = outlinePaint; 178: this.outlineStroke = outlineStroke; 179: this.alpha = alpha; 180: 181: this.labelFont = new Font("SansSerif", Font.PLAIN, 9); 182: this.labelPaint = Color.black; 183: this.labelAnchor = RectangleAnchor.TOP_LEFT; 184: this.labelOffset = new RectangleInsets(3.0, 3.0, 3.0, 3.0); 185: this.labelOffsetType = LengthAdjustmentType.CONTRACT; 186: this.labelTextAnchor = TextAnchor.CENTER; 187: 188: } 189: 190: /** 191: * Returns the paint. 192: * 193: * @return The paint (never <code>null</code>). 194: * 195: * @see #setPaint(Paint) 196: */ 197: public Paint getPaint() { 198: return this.paint; 199: } 200: 201: /** 202: * Sets the paint. 203: * 204: * @param paint the paint (<code>null</code> not permitted). 205: * 206: * @see #getPaint() 207: */ 208: public void setPaint(Paint paint) { 209: if (paint == null) { 210: throw new IllegalArgumentException("Null 'paint' argument."); 211: } 212: this.paint = paint; 213: } 214: 215: /** 216: * Returns the stroke. 217: * 218: * @return The stroke (never <code>null</code>). 219: * 220: * @see #setStroke(Stroke) 221: */ 222: public Stroke getStroke() { 223: return this.stroke; 224: } 225: 226: /** 227: * Sets the stroke. 228: * 229: * @param stroke the stroke (<code>null</code> not permitted). 230: * 231: * @see #getStroke() 232: */ 233: public void setStroke(Stroke stroke) { 234: if (stroke == null) { 235: throw new IllegalArgumentException("Null 'stroke' argument."); 236: } 237: this.stroke = stroke; 238: } 239: 240: /** 241: * Returns the outline paint. 242: * 243: * @return The outline paint (possibly <code>null</code>). 244: * 245: * @see #setOutlinePaint(Paint) 246: */ 247: public Paint getOutlinePaint() { 248: return this.outlinePaint; 249: } 250: 251: /** 252: * Sets the outline paint. 253: * 254: * @param paint the paint (<code>null</code> permitted). 255: * 256: * @see #getOutlinePaint() 257: */ 258: public void setOutlinePaint(Paint paint) { 259: this.outlinePaint = paint; 260: } 261: 262: /** 263: * Returns the outline stroke. 264: * 265: * @return The outline stroke (possibly <code>null</code>). 266: * 267: * @see #setOutlineStroke(Stroke) 268: */ 269: public Stroke getOutlineStroke() { 270: return this.outlineStroke; 271: } 272: 273: /** 274: * Sets the outline stroke. 275: * 276: * @param stroke the stroke (<code>null</code> permitted). 277: * 278: * @see #getOutlineStroke() 279: */ 280: public void setOutlineStroke(Stroke stroke) { 281: this.outlineStroke = stroke; 282: } 283: 284: /** 285: * Returns the alpha transparency. 286: * 287: * @return The alpha transparency. 288: * 289: * @see #setAlpha(float) 290: */ 291: public float getAlpha() { 292: return this.alpha; 293: } 294: 295: /** 296: * Sets the alpha transparency that should be used when drawing the 297: * marker. This is a value in the range 0.0f (completely transparent) to 298: * 1.0f (completely opaque). 299: * 300: * @param alpha the alpha transparency (must be in the range 0.0f to 301: * 1.0f). 302: * 303: * @throws IllegalArgumentException if <code>alpha</code> is not in the 304: * specified range. 305: * 306: * @see #getAlpha() 307: */ 308: public void setAlpha(float alpha) { 309: if (alpha < 0.0f || alpha > 1.0f) 310: throw new IllegalArgumentException( 311: "The 'alpha' value must be in the range 0.0f to 1.0f"); 312: this.alpha = alpha; 313: } 314: 315: /** 316: * Returns the label (if <code>null</code> no label is displayed). 317: * 318: * @return The label (possibly <code>null</code>). 319: * 320: * @see #setLabel(String) 321: */ 322: public String getLabel() { 323: return this.label; 324: } 325: 326: /** 327: * Sets the label (if <code>null</code> no label is displayed). 328: * 329: * @param label the label (<code>null</code> permitted). 330: * 331: * @see #getLabel() 332: */ 333: public void setLabel(String label) { 334: this.label = label; 335: } 336: 337: /** 338: * Returns the label font. 339: * 340: * @return The label font (never <code>null</code>). 341: * 342: * @see #setLabelFont(Font) 343: */ 344: public Font getLabelFont() { 345: return this.labelFont; 346: } 347: 348: /** 349: * Sets the label font. 350: * 351: * @param font the font (<code>null</code> not permitted). 352: * 353: * @see #getLabelFont() 354: */ 355: public void setLabelFont(Font font) { 356: if (font == null) { 357: throw new IllegalArgumentException("Null 'font' argument."); 358: } 359: this.labelFont = font; 360: } 361: 362: /** 363: * Returns the label paint. 364: * 365: * @return The label paint (never </code>null</code>). 366: * 367: * @see #setLabelPaint(Paint) 368: */ 369: public Paint getLabelPaint() { 370: return this.labelPaint; 371: } 372: 373: /** 374: * Sets the label paint. 375: * 376: * @param paint the paint (<code>null</code> not permitted). 377: * 378: * @see #getLabelPaint() 379: */ 380: public void setLabelPaint(Paint paint) { 381: if (paint == null) { 382: throw new IllegalArgumentException("Null 'paint' argument."); 383: } 384: this.labelPaint = paint; 385: } 386: 387: /** 388: * Returns the label anchor. This defines the position of the label 389: * anchor, relative to the bounds of the marker. 390: * 391: * @return The label anchor (never <code>null</code>). 392: * 393: * @see #setLabelAnchor(RectangleAnchor) 394: */ 395: public RectangleAnchor getLabelAnchor() { 396: return this.labelAnchor; 397: } 398: 399: /** 400: * Sets the label anchor. This defines the position of the label 401: * anchor, relative to the bounds of the marker. 402: * 403: * @param anchor the anchor (<code>null</code> not permitted). 404: * 405: * @see #getLabelAnchor() 406: */ 407: public void setLabelAnchor(RectangleAnchor anchor) { 408: if (anchor == null) { 409: throw new IllegalArgumentException("Null 'anchor' argument."); 410: } 411: this.labelAnchor = anchor; 412: } 413: 414: /** 415: * Returns the label offset. 416: * 417: * @return The label offset (never <code>null</code>). 418: * 419: * @see #setLabelOffset(RectangleInsets) 420: */ 421: public RectangleInsets getLabelOffset() { 422: return this.labelOffset; 423: } 424: 425: /** 426: * Sets the label offset. 427: * 428: * @param offset the label offset (<code>null</code> not permitted). 429: * 430: * @see #getLabelOffset() 431: */ 432: public void setLabelOffset(RectangleInsets offset) { 433: if (offset == null) { 434: throw new IllegalArgumentException("Null 'offset' argument."); 435: } 436: this.labelOffset = offset; 437: } 438: 439: /** 440: * Returns the label offset type. 441: * 442: * @return The type (never <code>null</code>). 443: * 444: * @see #setLabelOffsetType(LengthAdjustmentType) 445: */ 446: public LengthAdjustmentType getLabelOffsetType() { 447: return this.labelOffsetType; 448: } 449: 450: /** 451: * Sets the label offset type. 452: * 453: * @param adj the type (<code>null</code> not permitted). 454: * 455: * @see #getLabelOffsetType() 456: */ 457: public void setLabelOffsetType(LengthAdjustmentType adj) { 458: if (adj == null) { 459: throw new IllegalArgumentException("Null 'adj' argument."); 460: } 461: this.labelOffsetType = adj; 462: } 463: 464: /** 465: * Returns the label text anchor. 466: * 467: * @return The label text anchor (never <code>null</code>). 468: * 469: * @see #setLabelTextAnchor(TextAnchor) 470: */ 471: public TextAnchor getLabelTextAnchor() { 472: return this.labelTextAnchor; 473: } 474: 475: /** 476: * Sets the label text anchor. 477: * 478: * @param anchor the label text anchor (<code>null</code> not permitted). 479: * 480: * @see #getLabelTextAnchor() 481: */ 482: public void setLabelTextAnchor(TextAnchor anchor) { 483: if (anchor == null) { 484: throw new IllegalArgumentException("Null 'anchor' argument."); 485: } 486: this.labelTextAnchor = anchor; 487: } 488: 489: /** 490: * Tests the marker for equality with an arbitrary object. 491: * 492: * @param obj the object (<code>null</code> permitted). 493: * 494: * @return A boolean. 495: */ 496: public boolean equals(Object obj) { 497: if (obj == this) { 498: return true; 499: } 500: if (!(obj instanceof Marker)) { 501: return false; 502: } 503: Marker that = (Marker) obj; 504: if (!PaintUtilities.equal(this.paint, that.paint)) { 505: return false; 506: } 507: if (!ObjectUtilities.equal(this.stroke, that.stroke)) { 508: return false; 509: } 510: if (!PaintUtilities.equal(this.outlinePaint, that.outlinePaint)) { 511: return false; 512: } 513: if (!ObjectUtilities.equal(this.outlineStroke, that.outlineStroke)) { 514: return false; 515: } 516: if (this.alpha != that.alpha) { 517: return false; 518: } 519: if (!ObjectUtilities.equal(this.label, that.label)) { 520: return false; 521: } 522: if (!ObjectUtilities.equal(this.labelFont, that.labelFont)) { 523: return false; 524: } 525: if (!PaintUtilities.equal(this.labelPaint, that.labelPaint)) { 526: return false; 527: } 528: if (this.labelAnchor != that.labelAnchor) { 529: return false; 530: } 531: if (this.labelTextAnchor != that.labelTextAnchor) { 532: return false; 533: } 534: if (!ObjectUtilities.equal(this.labelOffset, that.labelOffset)) { 535: return false; 536: } 537: if (!this.labelOffsetType.equals(that.labelOffsetType)) { 538: return false; 539: } 540: return true; 541: } 542: 543: /** 544: * Creates a clone of the marker. 545: * 546: * @return A clone. 547: * 548: * @throws CloneNotSupportedException never. 549: */ 550: public Object clone() throws CloneNotSupportedException { 551: return super.clone(); 552: } 553: 554: /** 555: * Provides serialization support. 556: * 557: * @param stream the output stream. 558: * 559: * @throws IOException if there is an I/O error. 560: */ 561: private void writeObject(ObjectOutputStream stream) throws IOException { 562: stream.defaultWriteObject(); 563: SerialUtilities.writePaint(this.paint, stream); 564: SerialUtilities.writeStroke(this.stroke, stream); 565: SerialUtilities.writePaint(this.outlinePaint, stream); 566: SerialUtilities.writeStroke(this.outlineStroke, stream); 567: SerialUtilities.writePaint(this.labelPaint, stream); 568: } 569: 570: /** 571: * Provides serialization support. 572: * 573: * @param stream the input stream. 574: * 575: * @throws IOException if there is an I/O error. 576: * @throws ClassNotFoundException if there is a classpath problem. 577: */ 578: private void readObject(ObjectInputStream stream) 579: throws IOException, ClassNotFoundException { 580: stream.defaultReadObject(); 581: this.paint = SerialUtilities.readPaint(stream); 582: this.stroke = SerialUtilities.readStroke(stream); 583: this.outlinePaint = SerialUtilities.readPaint(stream); 584: this.outlineStroke = SerialUtilities.readStroke(stream); 585: this.labelPaint = SerialUtilities.readPaint(stream); 586: } 587: 588: }