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