Source for org.jfree.chart.plot.Marker

   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: }