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 * LegendItem.java 029 * --------------- 030 * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors. 031 * 032 * Original Author: David Gilbert (for Object Refinery Limited); 033 * Contributor(s): Andrzej Porebski; 034 * David Li; 035 * Wolfgang Irler; 036 * Luke Quinane; 037 * 038 * $Id: LegendItem.java,v 1.9.2.3 2005/11/28 12:06:34 mungady Exp $ 039 * 040 * Changes (from 2-Oct-2002) 041 * ------------------------- 042 * 02-Oct-2002 : Fixed errors reported by Checkstyle (DG); 043 * 17-Jan-2003 : Dropped outlineStroke attribute (DG); 044 * 08-Oct-2003 : Applied patch for displaying series line style, contributed by 045 * Luke Quinane (DG); 046 * 21-Jan-2004 : Added the shapeFilled flag (DG); 047 * 04-Jun-2004 : Added equals() method, implemented Serializable (DG); 048 * 25-Nov-2004 : Changes required by new LegendTitle implementation (DG); 049 * 11-Jan-2005 : Removed deprecated code in preparation for the 1.0.0 050 * release (DG); 051 * 20-Apr-2005 : Added tooltip and URL text (DG); 052 * 28-Nov-2005 : Separated constructors for AttributedString labels (DG); 053 * 054 */ 055 056 package org.jfree.chart; 057 058 import java.awt.BasicStroke; 059 import java.awt.Color; 060 import java.awt.Paint; 061 import java.awt.Shape; 062 import java.awt.Stroke; 063 import java.awt.geom.Line2D; 064 import java.io.IOException; 065 import java.io.ObjectInputStream; 066 import java.io.ObjectOutputStream; 067 import java.io.Serializable; 068 import java.text.AttributedString; 069 import java.text.CharacterIterator; 070 071 import org.jfree.io.SerialUtilities; 072 import org.jfree.util.AttributedStringUtilities; 073 import org.jfree.util.ObjectUtilities; 074 import org.jfree.util.ShapeUtilities; 075 076 /** 077 * A storage object for recording the properties of a legend item, without any 078 * consideration for layout issues. Instances of this class are immutable. 079 */ 080 public class LegendItem implements Serializable { 081 082 // TODO: keeping this class immutable is becoming a lot of overhead, need 083 // to look at the consequences of dropping immutability 084 085 /** For serialization. */ 086 private static final long serialVersionUID = -797214582948827144L; 087 088 /** The label. */ 089 private String label; 090 091 /** The attributed label (if null, fall back to the regular label). */ 092 private AttributedString attributedLabel; 093 094 /** 095 * The description (not currently used - could be displayed as a tool tip). 096 */ 097 private String description; 098 099 /** The tool tip text. */ 100 private String toolTipText; 101 102 /** The url text. */ 103 private String urlText; 104 105 /** A flag that controls whether or not the shape is visible. */ 106 private boolean shapeVisible; 107 108 /** The shape. */ 109 private transient Shape shape; 110 111 /** A flag that controls whether or not the shape is filled. */ 112 private boolean shapeFilled; 113 114 /** The paint. */ 115 private transient Paint fillPaint; 116 117 /** A flag that controls whether or not the shape outline is visible. */ 118 private boolean shapeOutlineVisible; 119 120 /** The outline paint. */ 121 private transient Paint outlinePaint; 122 123 /** The outline stroke. */ 124 private transient Stroke outlineStroke; 125 126 /** A flag that controls whether or not the line is visible. */ 127 private boolean lineVisible; 128 129 /** The line. */ 130 private transient Shape line; 131 132 /** The stroke. */ 133 private transient Stroke lineStroke; 134 135 /** The line paint. */ 136 private transient Paint linePaint; 137 138 /** 139 * The shape must be non-null for a LegendItem - if no shape is required, 140 * use this. 141 */ 142 private static final Shape UNUSED_SHAPE = new Line2D.Float(); 143 144 /** 145 * The stroke must be non-null for a LegendItem - if no stroke is required, 146 * use this. 147 */ 148 private static final Stroke UNUSED_STROKE = new BasicStroke(0.0f); 149 150 /** 151 * Creates a legend item with a filled shape. The shape is not outlined, 152 * and no line is visible. 153 * 154 * @param label the label (<code>null</code> not permitted). 155 * @param description the description (<code>null</code> permitted). 156 * @param toolTipText the tool tip text (<code>null</code> permitted). 157 * @param urlText the URL text (<code>null</code> permitted). 158 * @param shape the shape (<code>null</code> not permitted). 159 * @param fillPaint the paint used to fill the shape (<code>null</code> 160 * not permitted). 161 */ 162 public LegendItem(String label, String description, 163 String toolTipText, String urlText, 164 Shape shape, Paint fillPaint) { 165 166 this(label, description, toolTipText, urlText, 167 /* shape visible = */ true, shape, 168 /* shape filled = */ true, fillPaint, 169 /* shape outlined */ false, Color.black, UNUSED_STROKE, 170 /* line visible */ false, UNUSED_SHAPE, UNUSED_STROKE, 171 Color.black); 172 173 } 174 175 /** 176 * Creates a legend item with a filled and outlined shape. 177 * 178 * @param label the label (<code>null</code> not permitted). 179 * @param description the description (<code>null</code> permitted). 180 * @param toolTipText the tool tip text (<code>null</code> permitted). 181 * @param urlText the URL text (<code>null</code> permitted). 182 * @param shape the shape (<code>null</code> not permitted). 183 * @param fillPaint the paint used to fill the shape (<code>null</code> 184 * not permitted). 185 * @param outlineStroke the outline stroke (<code>null</code> not 186 * permitted). 187 * @param outlinePaint the outline paint (<code>null</code> not 188 * permitted). 189 */ 190 public LegendItem(String label, String description, 191 String toolTipText, String urlText, 192 Shape shape, Paint fillPaint, 193 Stroke outlineStroke, Paint outlinePaint) { 194 195 this(label, description, toolTipText, urlText, 196 /* shape visible = */ true, shape, 197 /* shape filled = */ true, fillPaint, 198 /* shape outlined = */ true, outlinePaint, outlineStroke, 199 /* line visible */ false, UNUSED_SHAPE, UNUSED_STROKE, 200 Color.black); 201 202 } 203 204 /** 205 * Creates a legend item using a line. 206 * 207 * @param label the label (<code>null</code> not permitted). 208 * @param description the description (<code>null</code> permitted). 209 * @param toolTipText the tool tip text (<code>null</code> permitted). 210 * @param urlText the URL text (<code>null</code> permitted). 211 * @param line the line (<code>null</code> not permitted). 212 * @param lineStroke the line stroke (<code>null</code> not permitted). 213 * @param linePaint the line paint (<code>null</code> not permitted). 214 */ 215 public LegendItem(String label, String description, 216 String toolTipText, String urlText, 217 Shape line, Stroke lineStroke, Paint linePaint) { 218 219 this(label, description, toolTipText, urlText, 220 /* shape visible = */ false, UNUSED_SHAPE, 221 /* shape filled = */ false, Color.black, 222 /* shape outlined = */ false, Color.black, UNUSED_STROKE, 223 /* line visible = */ true, line, lineStroke, linePaint); 224 } 225 226 /** 227 * Creates a new legend item. 228 * 229 * @param label the label (<code>null</code> not permitted). 230 * @param description the description (not currently used, 231 * <code>null</code> permitted). 232 * @param toolTipText the tool tip text (<code>null</code> permitted). 233 * @param urlText the URL text (<code>null</code> permitted). 234 * @param shapeVisible a flag that controls whether or not the shape is 235 * displayed. 236 * @param shape the shape (<code>null</code> permitted). 237 * @param shapeFilled a flag that controls whether or not the shape is 238 * filled. 239 * @param fillPaint the fill paint (<code>null</code> not permitted). 240 * @param shapeOutlineVisible a flag that controls whether or not the 241 * shape is outlined. 242 * @param outlinePaint the outline paint (<code>null</code> not permitted). 243 * @param outlineStroke the outline stroke (<code>null</code> not 244 * permitted). 245 * @param lineVisible a flag that controls whether or not the line is 246 * visible. 247 * @param line the line. 248 * @param lineStroke the stroke (<code>null</code> not permitted). 249 * @param linePaint the line paint (<code>null</code> not permitted). 250 */ 251 public LegendItem(String label, String description, 252 String toolTipText, String urlText, 253 boolean shapeVisible, Shape shape, 254 boolean shapeFilled, Paint fillPaint, 255 boolean shapeOutlineVisible, Paint outlinePaint, 256 Stroke outlineStroke, 257 boolean lineVisible, Shape line, 258 Stroke lineStroke, Paint linePaint) { 259 260 if (label == null) { 261 throw new IllegalArgumentException("Null 'label' argument."); 262 } 263 if (fillPaint == null) { 264 throw new IllegalArgumentException("Null 'fillPaint' argument."); 265 } 266 if (lineStroke == null) { 267 throw new IllegalArgumentException("Null 'lineStroke' argument."); 268 } 269 if (outlinePaint == null) { 270 throw new IllegalArgumentException("Null 'outlinePaint' argument."); 271 } 272 if (outlineStroke == null) { 273 throw new IllegalArgumentException( 274 "Null 'outlineStroke' argument."); 275 } 276 this.label = label; 277 this.attributedLabel = null; 278 this.description = description; 279 this.shapeVisible = shapeVisible; 280 this.shape = shape; 281 this.shapeFilled = shapeFilled; 282 this.fillPaint = fillPaint; 283 this.shapeOutlineVisible = shapeOutlineVisible; 284 this.outlinePaint = outlinePaint; 285 this.outlineStroke = outlineStroke; 286 this.lineVisible = lineVisible; 287 this.line = line; 288 this.lineStroke = lineStroke; 289 this.linePaint = linePaint; 290 this.toolTipText = toolTipText; 291 this.urlText = urlText; 292 } 293 294 /** 295 * Creates a legend item with a filled shape. The shape is not outlined, 296 * and no line is visible. 297 * 298 * @param label the label (<code>null</code> not permitted). 299 * @param description the description (<code>null</code> permitted). 300 * @param toolTipText the tool tip text (<code>null</code> permitted). 301 * @param urlText the URL text (<code>null</code> permitted). 302 * @param shape the shape (<code>null</code> not permitted). 303 * @param fillPaint the paint used to fill the shape (<code>null</code> 304 * not permitted). 305 */ 306 public LegendItem(AttributedString label, String description, 307 String toolTipText, String urlText, 308 Shape shape, Paint fillPaint) { 309 310 this(label, description, toolTipText, urlText, 311 /* shape visible = */ true, shape, 312 /* shape filled = */ true, fillPaint, 313 /* shape outlined = */ false, Color.black, UNUSED_STROKE, 314 /* line visible = */ false, UNUSED_SHAPE, UNUSED_STROKE, 315 Color.black); 316 317 } 318 319 /** 320 * Creates a legend item with a filled and outlined shape. 321 * 322 * @param label the label (<code>null</code> not permitted). 323 * @param description the description (<code>null</code> permitted). 324 * @param toolTipText the tool tip text (<code>null</code> permitted). 325 * @param urlText the URL text (<code>null</code> permitted). 326 * @param shape the shape (<code>null</code> not permitted). 327 * @param fillPaint the paint used to fill the shape (<code>null</code> 328 * not permitted). 329 * @param outlineStroke the outline stroke (<code>null</code> not 330 * permitted). 331 * @param outlinePaint the outline paint (<code>null</code> not 332 * permitted). 333 */ 334 public LegendItem(AttributedString label, String description, 335 String toolTipText, String urlText, 336 Shape shape, Paint fillPaint, 337 Stroke outlineStroke, Paint outlinePaint) { 338 339 this(label, description, toolTipText, urlText, 340 /* shape visible = */ true, shape, 341 /* shape filled = */ true, fillPaint, 342 /* shape outlined = */ true, outlinePaint, outlineStroke, 343 /* line visible = */ false, UNUSED_SHAPE, UNUSED_STROKE, 344 Color.black); 345 } 346 347 /** 348 * Creates a legend item using a line. 349 * 350 * @param label the label (<code>null</code> not permitted). 351 * @param description the description (<code>null</code> permitted). 352 * @param toolTipText the tool tip text (<code>null</code> permitted). 353 * @param urlText the URL text (<code>null</code> permitted). 354 * @param line the line (<code>null</code> not permitted). 355 * @param lineStroke the line stroke (<code>null</code> not permitted). 356 * @param linePaint the line paint (<code>null</code> not permitted). 357 */ 358 public LegendItem(AttributedString label, String description, 359 String toolTipText, String urlText, 360 Shape line, Stroke lineStroke, Paint linePaint) { 361 362 this(label, description, toolTipText, urlText, 363 /* shape visible = */ false, UNUSED_SHAPE, 364 /* shape filled = */ false, Color.black, 365 /* shape outlined = */ false, Color.black, UNUSED_STROKE, 366 /* line visible = */ true, line, lineStroke, linePaint 367 ); 368 } 369 370 /** 371 * Creates a new legend item. 372 * 373 * @param label the label (<code>null</code> not permitted). 374 * @param description the description (not currently used, 375 * <code>null</code> permitted). 376 * @param toolTipText the tool tip text (<code>null</code> permitted). 377 * @param urlText the URL text (<code>null</code> permitted). 378 * @param shapeVisible a flag that controls whether or not the shape is 379 * displayed. 380 * @param shape the shape (<code>null</code> permitted). 381 * @param shapeFilled a flag that controls whether or not the shape is 382 * filled. 383 * @param fillPaint the fill paint (<code>null</code> not permitted). 384 * @param shapeOutlineVisible a flag that controls whether or not the 385 * shape is outlined. 386 * @param outlinePaint the outline paint (<code>null</code> not permitted). 387 * @param outlineStroke the outline stroke (<code>null</code> not 388 * permitted). 389 * @param lineVisible a flag that controls whether or not the line is 390 * visible. 391 * @param line the line. 392 * @param lineStroke the stroke (<code>null</code> not permitted). 393 * @param linePaint the line paint (<code>null</code> not permitted). 394 */ 395 public LegendItem(AttributedString label, String description, 396 String toolTipText, String urlText, 397 boolean shapeVisible, Shape shape, 398 boolean shapeFilled, Paint fillPaint, 399 boolean shapeOutlineVisible, Paint outlinePaint, 400 Stroke outlineStroke, 401 boolean lineVisible, Shape line, Stroke lineStroke, 402 Paint linePaint) { 403 404 if (label == null) { 405 throw new IllegalArgumentException("Null 'label' argument."); 406 } 407 if (fillPaint == null) { 408 throw new IllegalArgumentException("Null 'fillPaint' argument."); 409 } 410 if (lineStroke == null) { 411 throw new IllegalArgumentException("Null 'lineStroke' argument."); 412 } 413 if (outlinePaint == null) { 414 throw new IllegalArgumentException("Null 'outlinePaint' argument."); 415 } 416 if (outlineStroke == null) { 417 throw new IllegalArgumentException( 418 "Null 'outlineStroke' argument."); 419 } 420 this.label = characterIteratorToString(label.getIterator()); 421 this.attributedLabel = label; 422 this.description = description; 423 this.shapeVisible = shapeVisible; 424 this.shape = shape; 425 this.shapeFilled = shapeFilled; 426 this.fillPaint = fillPaint; 427 this.shapeOutlineVisible = shapeOutlineVisible; 428 this.outlinePaint = outlinePaint; 429 this.outlineStroke = outlineStroke; 430 this.lineVisible = lineVisible; 431 this.line = line; 432 this.lineStroke = lineStroke; 433 this.linePaint = linePaint; 434 this.toolTipText = toolTipText; 435 this.urlText = urlText; 436 } 437 438 /** 439 * Returns a string containing the characters from the given iterator. 440 * 441 * @param iterator the iterator (<code>null</code> not permitted). 442 * 443 * @return A string. 444 */ 445 private String characterIteratorToString(CharacterIterator iterator) { 446 int endIndex = iterator.getEndIndex(); 447 int beginIndex = iterator.getBeginIndex(); 448 int count = endIndex - beginIndex; 449 if (count <= 0) { 450 return ""; 451 } 452 char[] chars = new char[count]; 453 int i = 0; 454 char c = iterator.first(); 455 while (c != CharacterIterator.DONE) { 456 chars[i] = c; 457 i++; 458 c = iterator.next(); 459 } 460 return new String(chars); 461 } 462 463 /** 464 * Returns the label. 465 * 466 * @return The label (never <code>null</code>). 467 */ 468 public String getLabel() { 469 return this.label; 470 } 471 472 /** 473 * Returns the attributed label. 474 * 475 * @return The attributed label (possibly <code>null</code>). 476 */ 477 public AttributedString getAttributedLabel() { 478 return this.attributedLabel; 479 } 480 481 /** 482 * Returns the description for the legend item. 483 * 484 * @return The description. 485 */ 486 public String getDescription() { 487 return this.description; 488 } 489 490 /** 491 * Returns the tool tip text. 492 * 493 * @return The tool tip text (possibly <code>null</code>). 494 */ 495 public String getToolTipText() { 496 return this.toolTipText; 497 } 498 499 /** 500 * Returns the URL text. 501 * 502 * @return The URL text (possibly <code>null</code>). 503 */ 504 public String getURLText() { 505 return this.urlText; 506 } 507 508 /** 509 * Returns a flag that indicates whether or not the shape is visible. 510 * 511 * @return A boolean. 512 */ 513 public boolean isShapeVisible() { 514 return this.shapeVisible; 515 } 516 517 /** 518 * Returns the shape used to label the series represented by this legend 519 * item. 520 * 521 * @return The shape (never <code>null</code>). 522 */ 523 public Shape getShape() { 524 return this.shape; 525 } 526 527 /** 528 * Returns a flag that controls whether or not the shape is filled. 529 * 530 * @return A boolean. 531 */ 532 public boolean isShapeFilled() { 533 return this.shapeFilled; 534 } 535 536 /** 537 * Returns the fill paint. 538 * 539 * @return The fill paint (never <code>null</code>). 540 */ 541 public Paint getFillPaint() { 542 return this.fillPaint; 543 } 544 545 /** 546 * Returns the flag that controls whether or not the shape outline 547 * is visible. 548 * 549 * @return A boolean. 550 */ 551 public boolean isShapeOutlineVisible() { 552 return this.shapeOutlineVisible; 553 } 554 555 /** 556 * Returns the line stroke for the series. 557 * 558 * @return The stroke (never <code>null</code>). 559 */ 560 public Stroke getLineStroke() { 561 return this.lineStroke; 562 } 563 564 /** 565 * Returns the paint used for lines. 566 * 567 * @return The paint. 568 */ 569 public Paint getLinePaint() { 570 return this.linePaint; 571 } 572 573 /** 574 * Returns the outline paint. 575 * 576 * @return The outline paint (never <code>null</code>). 577 */ 578 public Paint getOutlinePaint() { 579 return this.outlinePaint; 580 } 581 582 /** 583 * Returns the outline stroke. 584 * 585 * @return The outline stroke (never <code>null</code>). 586 */ 587 public Stroke getOutlineStroke() { 588 return this.outlineStroke; 589 } 590 591 /** 592 * Returns a flag that indicates whether or not the line is visible. 593 * 594 * @return A boolean. 595 */ 596 public boolean isLineVisible() { 597 return this.lineVisible; 598 } 599 600 /** 601 * Returns the line. 602 * 603 * @return The line. 604 */ 605 public Shape getLine() { 606 return this.line; 607 } 608 609 /** 610 * Tests this item for equality with an arbitrary object. 611 * 612 * @param obj the object (<code>null</code> permitted). 613 * 614 * @return A boolean. 615 */ 616 public boolean equals(Object obj) { 617 if (obj == this) { 618 return true; 619 } 620 if (!(obj instanceof LegendItem)) { 621 return false; 622 } 623 LegendItem that = (LegendItem) obj; 624 if (!this.label.equals(that.label)) { 625 return false; 626 } 627 if (!AttributedStringUtilities.equal(this.attributedLabel, 628 that.attributedLabel)) { 629 return false; 630 } 631 if (!ObjectUtilities.equal(this.description, that.description)) { 632 return false; 633 } 634 if (this.shapeVisible != that.shapeVisible) { 635 return false; 636 } 637 if (!ShapeUtilities.equal(this.shape, that.shape)) { 638 return false; 639 } 640 if (this.shapeFilled != that.shapeFilled) { 641 return false; 642 } 643 if (!this.fillPaint.equals(that.fillPaint)) { 644 return false; 645 } 646 if (this.shapeOutlineVisible != that.shapeOutlineVisible) { 647 return false; 648 } 649 if (!this.outlineStroke.equals(that.outlineStroke)) { 650 return false; 651 } 652 if (!this.outlinePaint.equals(that.outlinePaint)) { 653 return false; 654 } 655 if (!this.lineVisible == that.lineVisible) { 656 return false; 657 } 658 if (!ShapeUtilities.equal(this.line, that.line)) { 659 return false; 660 } 661 if (!this.lineStroke.equals(that.lineStroke)) { 662 return false; 663 } 664 if (!this.linePaint.equals(that.linePaint)) { 665 return false; 666 } 667 return true; 668 } 669 670 /** 671 * Provides serialization support. 672 * 673 * @param stream the output stream (<code>null</code> not permitted). 674 * 675 * @throws IOException if there is an I/O error. 676 */ 677 private void writeObject(ObjectOutputStream stream) throws IOException { 678 stream.defaultWriteObject(); 679 SerialUtilities.writeShape(this.shape, stream); 680 SerialUtilities.writePaint(this.fillPaint, stream); 681 SerialUtilities.writeStroke(this.outlineStroke, stream); 682 SerialUtilities.writePaint(this.outlinePaint, stream); 683 SerialUtilities.writeShape(this.line, stream); 684 SerialUtilities.writeStroke(this.lineStroke, stream); 685 SerialUtilities.writePaint(this.linePaint, stream); 686 } 687 688 /** 689 * Provides serialization support. 690 * 691 * @param stream the input stream (<code>null</code> not permitted). 692 * 693 * @throws IOException if there is an I/O error. 694 * @throws ClassNotFoundException if there is a classpath problem. 695 */ 696 private void readObject(ObjectInputStream stream) 697 throws IOException, ClassNotFoundException { 698 stream.defaultReadObject(); 699 this.shape = SerialUtilities.readShape(stream); 700 this.fillPaint = SerialUtilities.readPaint(stream); 701 this.outlineStroke = SerialUtilities.readStroke(stream); 702 this.outlinePaint = SerialUtilities.readPaint(stream); 703 this.line = SerialUtilities.readShape(stream); 704 this.lineStroke = SerialUtilities.readStroke(stream); 705 this.linePaint = SerialUtilities.readPaint(stream); 706 } 707 708 }