001/* =========================================================== 002 * JFreeChart : a free chart library for the Java(tm) platform 003 * =========================================================== 004 * 005 * (C) Copyright 2000-present, by David Gilbert 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 * [Oracle and Java are registered trademarks of Oracle and/or its affiliates. 025 * Other names may be trademarks of their respective owners.] 026 * 027 * --------------- 028 * LegendItem.java 029 * --------------- 030 * (C) Copyright 2000-present, by David Gilbert and Contributors. 031 * 032 * Original Author: David Gilbert; 033 * Contributor(s): Andrzej Porebski; 034 * David Li; 035 * Wolfgang Irler; 036 * Luke Quinane; 037 * Tracy Hiltbrand (equals/hashCode comply with EqualsVerifier); 038 * 039 */ 040 041package org.jfree.chart; 042 043import java.awt.BasicStroke; 044import java.awt.Color; 045import java.awt.Font; 046import java.awt.Paint; 047import java.awt.Shape; 048import java.awt.Stroke; 049import java.awt.geom.Line2D; 050import java.awt.geom.Rectangle2D; 051import java.io.IOException; 052import java.io.ObjectInputStream; 053import java.io.ObjectOutputStream; 054import java.io.Serializable; 055import java.text.AttributedString; 056import java.text.CharacterIterator; 057import java.util.Objects; 058import org.jfree.chart.text.AttributedStringUtils; 059import org.jfree.chart.ui.GradientPaintTransformer; 060import org.jfree.chart.ui.StandardGradientPaintTransformer; 061import org.jfree.chart.util.PaintUtils; 062import org.jfree.chart.util.Args; 063import org.jfree.chart.util.PublicCloneable; 064import org.jfree.chart.util.SerialUtils; 065import org.jfree.chart.util.ShapeUtils; 066import org.jfree.data.general.Dataset; 067 068/** 069 * A temporary storage object for recording the properties of a legend item, 070 * without any consideration for layout issues. 071 */ 072public class LegendItem implements Cloneable, Serializable { 073 074 /** For serialization. */ 075 private static final long serialVersionUID = -797214582948827144L; 076 077 /** 078 * The dataset. 079 */ 080 private Dataset dataset; 081 082 /** 083 * The series key. 084 */ 085 private Comparable seriesKey; 086 087 /** The dataset index. */ 088 private int datasetIndex; 089 090 /** The series index. */ 091 private int series; 092 093 /** The label. */ 094 private String label; 095 096 /** 097 * The label font ({@code null} is permitted). 098 */ 099 private Font labelFont; 100 101 /** 102 * The label paint ({@code null} is permitted). 103 */ 104 private transient Paint labelPaint; 105 106 /** The attributed label (if null, fall back to the regular label). */ 107 private transient AttributedString attributedLabel; 108 109 /** 110 * The description (not currently used - could be displayed as a tool tip). 111 */ 112 private String description; 113 114 /** The tool tip text. */ 115 private String toolTipText; 116 117 /** The url text. */ 118 private String urlText; 119 120 /** A flag that controls whether or not the shape is visible. */ 121 private boolean shapeVisible; 122 123 /** The shape. */ 124 private transient Shape shape; 125 126 /** A flag that controls whether or not the shape is filled. */ 127 private boolean shapeFilled; 128 129 /** The paint. */ 130 private transient Paint fillPaint; 131 132 /** 133 * A gradient paint transformer. 134 */ 135 private GradientPaintTransformer fillPaintTransformer; 136 137 /** A flag that controls whether or not the shape outline is visible. */ 138 private boolean shapeOutlineVisible; 139 140 /** The outline paint. */ 141 private transient Paint outlinePaint; 142 143 /** The outline stroke. */ 144 private transient Stroke outlineStroke; 145 146 /** A flag that controls whether or not the line is visible. */ 147 private boolean lineVisible; 148 149 /** The line. */ 150 private transient Shape line; 151 152 /** The stroke. */ 153 private transient Stroke lineStroke; 154 155 /** The line paint. */ 156 private transient Paint linePaint; 157 158 /** 159 * The shape must be non-null for a LegendItem - if no shape is required, 160 * use this. 161 */ 162 private static final Shape UNUSED_SHAPE = new Line2D.Float(); 163 164 /** 165 * The stroke must be non-null for a LegendItem - if no stroke is required, 166 * use this. 167 */ 168 private static final Stroke UNUSED_STROKE = new BasicStroke(0.0f); 169 170 /** 171 * Creates a legend item with the specified label. The remaining 172 * attributes take default values. 173 * 174 * @param label the label ({@code null} not permitted). 175 */ 176 public LegendItem(String label) { 177 this(label, Color.BLACK); 178 } 179 180 /** 181 * Creates a legend item with the specified label and fill paint. The 182 * remaining attributes take default values. 183 * 184 * @param label the label ({@code null} not permitted). 185 * @param paint the paint ({@code null} not permitted). 186 */ 187 public LegendItem(String label, Paint paint) { 188 this(label, null, null, null, new Rectangle2D.Double(-4.0, -4.0, 8.0, 189 8.0), paint); 190 } 191 192 /** 193 * Creates a legend item with a filled shape. The shape is not outlined, 194 * and no line is visible. 195 * 196 * @param label the label ({@code null} not permitted). 197 * @param description the description ({@code null} permitted). 198 * @param toolTipText the tool tip text ({@code null} permitted). 199 * @param urlText the URL text ({@code null} permitted). 200 * @param shape the shape ({@code null} not permitted). 201 * @param fillPaint the paint used to fill the shape ({@code null} 202 * not permitted). 203 */ 204 public LegendItem(String label, String description, 205 String toolTipText, String urlText, 206 Shape shape, Paint fillPaint) { 207 208 this(label, description, toolTipText, urlText, 209 /* shape visible = */ true, shape, 210 /* shape filled = */ true, fillPaint, 211 /* shape outlined */ false, Color.BLACK, UNUSED_STROKE, 212 /* line visible */ false, UNUSED_SHAPE, UNUSED_STROKE, 213 Color.BLACK); 214 215 } 216 217 /** 218 * Creates a legend item with a filled and outlined shape. 219 * 220 * @param label the label ({@code null} not permitted). 221 * @param description the description ({@code null} permitted). 222 * @param toolTipText the tool tip text ({@code null} permitted). 223 * @param urlText the URL text ({@code null} permitted). 224 * @param shape the shape ({@code null} not permitted). 225 * @param fillPaint the paint used to fill the shape ({@code null} 226 * not permitted). 227 * @param outlineStroke the outline stroke ({@code null} not 228 * permitted). 229 * @param outlinePaint the outline paint ({@code null} not 230 * permitted). 231 */ 232 public LegendItem(String label, String description, String toolTipText, 233 String urlText, Shape shape, Paint fillPaint, Stroke outlineStroke, 234 Paint outlinePaint) { 235 236 this(label, description, toolTipText, urlText, 237 /* shape visible = */ true, shape, 238 /* shape filled = */ true, fillPaint, 239 /* shape outlined = */ true, outlinePaint, outlineStroke, 240 /* line visible */ false, UNUSED_SHAPE, UNUSED_STROKE, 241 Color.BLACK); 242 243 } 244 245 /** 246 * Creates a legend item using a line. 247 * 248 * @param label the label ({@code null} not permitted). 249 * @param description the description ({@code null} permitted). 250 * @param toolTipText the tool tip text ({@code null} permitted). 251 * @param urlText the URL text ({@code null} permitted). 252 * @param line the line ({@code null} not permitted). 253 * @param lineStroke the line stroke ({@code null} not permitted). 254 * @param linePaint the line paint ({@code null} not permitted). 255 */ 256 public LegendItem(String label, String description, String toolTipText, 257 String urlText, Shape line, Stroke lineStroke, Paint linePaint) { 258 259 this(label, description, toolTipText, urlText, 260 /* shape visible = */ false, UNUSED_SHAPE, 261 /* shape filled = */ false, Color.BLACK, 262 /* shape outlined = */ false, Color.BLACK, UNUSED_STROKE, 263 /* line visible = */ true, line, lineStroke, linePaint); 264 } 265 266 /** 267 * Creates a new legend item. 268 * 269 * @param label the label ({@code null} not permitted). 270 * @param description the description (not currently used, 271 * {@code null} permitted). 272 * @param toolTipText the tool tip text ({@code null} permitted). 273 * @param urlText the URL text ({@code null} permitted). 274 * @param shapeVisible a flag that controls whether or not the shape is 275 * displayed. 276 * @param shape the shape ({@code null} permitted). 277 * @param shapeFilled a flag that controls whether or not the shape is 278 * filled. 279 * @param fillPaint the fill paint ({@code null} not permitted). 280 * @param shapeOutlineVisible a flag that controls whether or not the 281 * shape is outlined. 282 * @param outlinePaint the outline paint ({@code null} not permitted). 283 * @param outlineStroke the outline stroke ({@code null} not 284 * permitted). 285 * @param lineVisible a flag that controls whether or not the line is 286 * visible. 287 * @param line the line. 288 * @param lineStroke the stroke ({@code null} not permitted). 289 * @param linePaint the line paint ({@code null} not permitted). 290 */ 291 public LegendItem(String label, String description, 292 String toolTipText, String urlText, 293 boolean shapeVisible, Shape shape, 294 boolean shapeFilled, Paint fillPaint, 295 boolean shapeOutlineVisible, Paint outlinePaint, 296 Stroke outlineStroke, 297 boolean lineVisible, Shape line, 298 Stroke lineStroke, Paint linePaint) { 299 300 Args.nullNotPermitted(label, "label"); 301 Args.nullNotPermitted(fillPaint, "fillPaint"); 302 Args.nullNotPermitted(lineStroke, "lineStroke"); 303 Args.nullNotPermitted(outlinePaint, "outlinePaint"); 304 Args.nullNotPermitted(outlineStroke, "outlineStroke"); 305 this.label = label; 306 this.labelPaint = null; 307 this.attributedLabel = null; 308 this.description = description; 309 this.shapeVisible = shapeVisible; 310 this.shape = shape; 311 this.shapeFilled = shapeFilled; 312 this.fillPaint = fillPaint; 313 this.fillPaintTransformer = new StandardGradientPaintTransformer(); 314 this.shapeOutlineVisible = shapeOutlineVisible; 315 this.outlinePaint = outlinePaint; 316 this.outlineStroke = outlineStroke; 317 this.lineVisible = lineVisible; 318 this.line = line; 319 this.lineStroke = lineStroke; 320 this.linePaint = linePaint; 321 this.toolTipText = toolTipText; 322 this.urlText = urlText; 323 } 324 325 /** 326 * Creates a legend item with a filled shape. The shape is not outlined, 327 * and no line is visible. 328 * 329 * @param label the label ({@code null} not permitted). 330 * @param description the description ({@code null} permitted). 331 * @param toolTipText the tool tip text ({@code null} permitted). 332 * @param urlText the URL text ({@code null} permitted). 333 * @param shape the shape ({@code null} not permitted). 334 * @param fillPaint the paint used to fill the shape ({@code null} 335 * not permitted). 336 */ 337 public LegendItem(AttributedString label, String description, 338 String toolTipText, String urlText, 339 Shape shape, Paint fillPaint) { 340 341 this(label, description, toolTipText, urlText, 342 /* shape visible = */ true, shape, 343 /* shape filled = */ true, fillPaint, 344 /* shape outlined = */ false, Color.BLACK, UNUSED_STROKE, 345 /* line visible = */ false, UNUSED_SHAPE, UNUSED_STROKE, 346 Color.BLACK); 347 348 } 349 350 /** 351 * Creates a legend item with a filled and outlined shape. 352 * 353 * @param label the label ({@code null} not permitted). 354 * @param description the description ({@code null} permitted). 355 * @param toolTipText the tool tip text ({@code null} permitted). 356 * @param urlText the URL text ({@code null} permitted). 357 * @param shape the shape ({@code null} not permitted). 358 * @param fillPaint the paint used to fill the shape ({@code null} 359 * not permitted). 360 * @param outlineStroke the outline stroke ({@code null} not 361 * permitted). 362 * @param outlinePaint the outline paint ({@code null} not 363 * permitted). 364 */ 365 public LegendItem(AttributedString label, String description, 366 String toolTipText, String urlText, 367 Shape shape, Paint fillPaint, 368 Stroke outlineStroke, Paint outlinePaint) { 369 370 this(label, description, toolTipText, urlText, 371 /* shape visible = */ true, shape, 372 /* shape filled = */ true, fillPaint, 373 /* shape outlined = */ true, outlinePaint, outlineStroke, 374 /* line visible = */ false, UNUSED_SHAPE, UNUSED_STROKE, 375 Color.BLACK); 376 } 377 378 /** 379 * Creates a legend item using a line. 380 * 381 * @param label the label ({@code null} not permitted). 382 * @param description the description ({@code null} permitted). 383 * @param toolTipText the tool tip text ({@code null} permitted). 384 * @param urlText the URL text ({@code null} permitted). 385 * @param line the line ({@code null} not permitted). 386 * @param lineStroke the line stroke ({@code null} not permitted). 387 * @param linePaint the line paint ({@code null} not permitted). 388 */ 389 public LegendItem(AttributedString label, String description, 390 String toolTipText, String urlText, 391 Shape line, Stroke lineStroke, Paint linePaint) { 392 393 this(label, description, toolTipText, urlText, 394 /* shape visible = */ false, UNUSED_SHAPE, 395 /* shape filled = */ false, Color.BLACK, 396 /* shape outlined = */ false, Color.BLACK, UNUSED_STROKE, 397 /* line visible = */ true, line, lineStroke, linePaint); 398 } 399 400 /** 401 * Creates a new legend item. 402 * 403 * @param label the label ({@code null} not permitted). 404 * @param description the description (not currently used, 405 * {@code null} permitted). 406 * @param toolTipText the tool tip text ({@code null} permitted). 407 * @param urlText the URL text ({@code null} permitted). 408 * @param shapeVisible a flag that controls whether or not the shape is 409 * displayed. 410 * @param shape the shape ({@code null} permitted). 411 * @param shapeFilled a flag that controls whether or not the shape is 412 * filled. 413 * @param fillPaint the fill paint ({@code null} not permitted). 414 * @param shapeOutlineVisible a flag that controls whether or not the 415 * shape is outlined. 416 * @param outlinePaint the outline paint ({@code null} not permitted). 417 * @param outlineStroke the outline stroke ({@code null} not 418 * permitted). 419 * @param lineVisible a flag that controls whether or not the line is 420 * visible. 421 * @param line the line ({@code null} not permitted). 422 * @param lineStroke the stroke ({@code null} not permitted). 423 * @param linePaint the line paint ({@code null} not permitted). 424 */ 425 public LegendItem(AttributedString label, String description, 426 String toolTipText, String urlText, 427 boolean shapeVisible, Shape shape, 428 boolean shapeFilled, Paint fillPaint, 429 boolean shapeOutlineVisible, Paint outlinePaint, 430 Stroke outlineStroke, 431 boolean lineVisible, Shape line, Stroke lineStroke, 432 Paint linePaint) { 433 434 Args.nullNotPermitted(label, "label"); 435 Args.nullNotPermitted(fillPaint, "fillPaint"); 436 Args.nullNotPermitted(lineStroke, "lineStroke"); 437 Args.nullNotPermitted(line, "line"); 438 Args.nullNotPermitted(linePaint, "linePaint"); 439 Args.nullNotPermitted(outlinePaint, "outlinePaint"); 440 Args.nullNotPermitted(outlineStroke, "outlineStroke"); 441 this.label = characterIteratorToString(label.getIterator()); 442 this.attributedLabel = label; 443 this.description = description; 444 this.shapeVisible = shapeVisible; 445 this.shape = shape; 446 this.shapeFilled = shapeFilled; 447 this.fillPaint = fillPaint; 448 this.fillPaintTransformer = new StandardGradientPaintTransformer(); 449 this.shapeOutlineVisible = shapeOutlineVisible; 450 this.outlinePaint = outlinePaint; 451 this.outlineStroke = outlineStroke; 452 this.lineVisible = lineVisible; 453 this.line = line; 454 this.lineStroke = lineStroke; 455 this.linePaint = linePaint; 456 this.toolTipText = toolTipText; 457 this.urlText = urlText; 458 } 459 460 /** 461 * Returns a string containing the characters from the given iterator. 462 * 463 * @param iterator the iterator ({@code null} not permitted). 464 * 465 * @return A string. 466 */ 467 private String characterIteratorToString(CharacterIterator iterator) { 468 int endIndex = iterator.getEndIndex(); 469 int beginIndex = iterator.getBeginIndex(); 470 int count = endIndex - beginIndex; 471 if (count <= 0) { 472 return ""; 473 } 474 char[] chars = new char[count]; 475 int i = 0; 476 char c = iterator.first(); 477 while (c != CharacterIterator.DONE) { 478 chars[i] = c; 479 i++; 480 c = iterator.next(); 481 } 482 return new String(chars); 483 } 484 485 /** 486 * Returns the dataset. 487 * 488 * @return The dataset. 489 * 490 * @see #setDatasetIndex(int) 491 */ 492 public Dataset getDataset() { 493 return this.dataset; 494 } 495 496 /** 497 * Sets the dataset. 498 * 499 * @param dataset the dataset. 500 */ 501 public void setDataset(Dataset dataset) { 502 this.dataset = dataset; 503 } 504 505 /** 506 * Returns the dataset index for this legend item. 507 * 508 * @return The dataset index. 509 * 510 * @see #setDatasetIndex(int) 511 * @see #getDataset() 512 */ 513 public int getDatasetIndex() { 514 return this.datasetIndex; 515 } 516 517 /** 518 * Sets the dataset index for this legend item. 519 * 520 * @param index the index. 521 * 522 * @see #getDatasetIndex() 523 */ 524 public void setDatasetIndex(int index) { 525 this.datasetIndex = index; 526 } 527 528 /** 529 * Returns the series key. 530 * 531 * @return The series key. 532 * 533 * @see #setSeriesKey(Comparable) 534 */ 535 public Comparable getSeriesKey() { 536 return this.seriesKey; 537 } 538 539 /** 540 * Sets the series key. 541 * 542 * @param key the series key. 543 */ 544 public void setSeriesKey(Comparable key) { 545 this.seriesKey = key; 546 } 547 548 /** 549 * Returns the series index for this legend item. 550 * 551 * @return The series index. 552 */ 553 public int getSeriesIndex() { 554 return this.series; 555 } 556 557 /** 558 * Sets the series index for this legend item. 559 * 560 * @param index the index. 561 */ 562 public void setSeriesIndex(int index) { 563 this.series = index; 564 } 565 566 /** 567 * Returns the label. 568 * 569 * @return The label (never {@code null}). 570 */ 571 public String getLabel() { 572 return this.label; 573 } 574 575 /** 576 * Returns the label font. 577 * 578 * @return The label font (possibly {@code null}). 579 */ 580 public Font getLabelFont() { 581 return this.labelFont; 582 } 583 584 /** 585 * Sets the label font. 586 * 587 * @param font the font ({@code null} permitted). 588 */ 589 public void setLabelFont(Font font) { 590 this.labelFont = font; 591 } 592 593 /** 594 * Returns the paint used to draw the label. 595 * 596 * @return The paint (possibly {@code null}). 597 */ 598 public Paint getLabelPaint() { 599 return this.labelPaint; 600 } 601 602 /** 603 * Sets the paint used to draw the label. 604 * 605 * @param paint the paint ({@code null} permitted). 606 */ 607 public void setLabelPaint(Paint paint) { 608 this.labelPaint = paint; 609 } 610 611 /** 612 * Returns the attributed label. 613 * 614 * @return The attributed label (possibly {@code null}). 615 */ 616 public AttributedString getAttributedLabel() { 617 return this.attributedLabel; 618 } 619 620 /** 621 * Returns the description for the legend item. 622 * 623 * @return The description (possibly {@code null}). 624 * 625 * @see #setDescription(java.lang.String) 626 */ 627 public String getDescription() { 628 return this.description; 629 } 630 631 /** 632 * Sets the description for this legend item. 633 * 634 * @param text the description ({@code null} permitted). 635 * 636 * @see #getDescription() 637 */ 638 public void setDescription(String text) { 639 this.description = text; 640 } 641 642 /** 643 * Returns the tool tip text. 644 * 645 * @return The tool tip text (possibly {@code null}). 646 * 647 * @see #setToolTipText(java.lang.String) 648 */ 649 public String getToolTipText() { 650 return this.toolTipText; 651 } 652 653 /** 654 * Sets the tool tip text for this legend item. 655 * 656 * @param text the text ({@code null} permitted). 657 * 658 * @see #getToolTipText() 659 */ 660 public void setToolTipText(String text) { 661 this.toolTipText = text; 662 } 663 664 /** 665 * Returns the URL text. 666 * 667 * @return The URL text (possibly {@code null}). 668 * 669 * @see #setURLText(java.lang.String) 670 */ 671 public String getURLText() { 672 return this.urlText; 673 } 674 675 /** 676 * Sets the URL text. 677 * 678 * @param text the text ({@code null} permitted). 679 * 680 * @see #getURLText() 681 */ 682 public void setURLText(String text) { 683 this.urlText = text; 684 } 685 686 /** 687 * Returns a flag that indicates whether or not the shape is visible. 688 * 689 * @return A boolean. 690 * 691 * @see #setShapeVisible(boolean) 692 */ 693 public boolean isShapeVisible() { 694 return this.shapeVisible; 695 } 696 697 /** 698 * Sets the flag that controls whether or not the shape is visible. 699 * 700 * @param visible the new flag value. 701 * 702 * @see #isShapeVisible() 703 * @see #isLineVisible() 704 */ 705 public void setShapeVisible(boolean visible) { 706 this.shapeVisible = visible; 707 } 708 709 /** 710 * Returns the shape used to label the series represented by this legend 711 * item. 712 * 713 * @return The shape (never {@code null}). 714 * 715 * @see #setShape(java.awt.Shape) 716 */ 717 public Shape getShape() { 718 return this.shape; 719 } 720 721 /** 722 * Sets the shape for the legend item. 723 * 724 * @param shape the shape ({@code null} not permitted). 725 * 726 * @see #getShape() 727 */ 728 public void setShape(Shape shape) { 729 Args.nullNotPermitted(shape, "shape"); 730 this.shape = shape; 731 } 732 733 /** 734 * Returns a flag that controls whether or not the shape is filled. 735 * 736 * @return A boolean. 737 */ 738 public boolean isShapeFilled() { 739 return this.shapeFilled; 740 } 741 742 /** 743 * Returns the fill paint. 744 * 745 * @return The fill paint (never {@code null}). 746 */ 747 public Paint getFillPaint() { 748 return this.fillPaint; 749 } 750 751 /** 752 * Sets the fill paint. 753 * 754 * @param paint the paint ({@code null} not permitted). 755 */ 756 public void setFillPaint(Paint paint) { 757 Args.nullNotPermitted(paint, "paint"); 758 this.fillPaint = paint; 759 } 760 761 /** 762 * Returns the flag that controls whether or not the shape outline 763 * is visible. 764 * 765 * @return A boolean. 766 */ 767 public boolean isShapeOutlineVisible() { 768 return this.shapeOutlineVisible; 769 } 770 771 /** 772 * Returns the line stroke for the series. 773 * 774 * @return The stroke (never {@code null}). 775 */ 776 public Stroke getLineStroke() { 777 return this.lineStroke; 778 } 779 780 /** 781 * Sets the line stroke. 782 * 783 * @param stroke the stroke ({@code null} not permitted). 784 */ 785 public void setLineStroke(Stroke stroke) { 786 Args.nullNotPermitted(stroke, "stroke"); 787 this.lineStroke = stroke; 788 } 789 790 /** 791 * Returns the paint used for lines. 792 * 793 * @return The paint (never {@code null}). 794 */ 795 public Paint getLinePaint() { 796 return this.linePaint; 797 } 798 799 /** 800 * Sets the line paint. 801 * 802 * @param paint the paint ({@code null} not permitted). 803 */ 804 public void setLinePaint(Paint paint) { 805 Args.nullNotPermitted(paint, "paint"); 806 this.linePaint = paint; 807 } 808 809 /** 810 * Returns the outline paint. 811 * 812 * @return The outline paint (never {@code null}). 813 */ 814 public Paint getOutlinePaint() { 815 return this.outlinePaint; 816 } 817 818 /** 819 * Sets the outline paint. 820 * 821 * @param paint the paint ({@code null} not permitted). 822 */ 823 public void setOutlinePaint(Paint paint) { 824 Args.nullNotPermitted(paint, "paint"); 825 this.outlinePaint = paint; 826 } 827 828 /** 829 * Returns the outline stroke. 830 * 831 * @return The outline stroke (never {@code null}). 832 * 833 * @see #setOutlineStroke(java.awt.Stroke) 834 */ 835 public Stroke getOutlineStroke() { 836 return this.outlineStroke; 837 } 838 839 /** 840 * Sets the outline stroke. 841 * 842 * @param stroke the stroke ({@code null} not permitted). 843 * 844 * @see #getOutlineStroke() 845 */ 846 public void setOutlineStroke(Stroke stroke) { 847 Args.nullNotPermitted(stroke, "stroke"); 848 this.outlineStroke = stroke; 849 } 850 851 /** 852 * Returns a flag that indicates whether or not the line is visible. 853 * 854 * @return A boolean. 855 * 856 * @see #setLineVisible(boolean) 857 */ 858 public boolean isLineVisible() { 859 return this.lineVisible; 860 } 861 862 /** 863 * Sets the flag that controls whether or not the line shape is visible for 864 * this legend item. 865 * 866 * @param visible the new flag value. 867 * 868 * @see #isLineVisible() 869 */ 870 public void setLineVisible(boolean visible) { 871 this.lineVisible = visible; 872 } 873 874 /** 875 * Returns the line. 876 * 877 * @return The line (never {@code null}). 878 * 879 * @see #setLine(java.awt.Shape) 880 * @see #isLineVisible() 881 */ 882 public Shape getLine() { 883 return this.line; 884 } 885 886 /** 887 * Sets the line. 888 * 889 * @param line the line ({@code null} not permitted). 890 * 891 * @see #getLine() 892 */ 893 public void setLine(Shape line) { 894 Args.nullNotPermitted(line, "line"); 895 this.line = line; 896 } 897 898 /** 899 * Returns the transformer used when the fill paint is an instance of 900 * {@code GradientPaint}. 901 * 902 * @return The transformer (never {@code null}). 903 * 904 * @see #setFillPaintTransformer(GradientPaintTransformer) 905 */ 906 public GradientPaintTransformer getFillPaintTransformer() { 907 return this.fillPaintTransformer; 908 } 909 910 /** 911 * Sets the transformer used when the fill paint is an instance of 912 * {@code GradientPaint}. 913 * 914 * @param transformer the transformer ({@code null} not permitted). 915 * 916 * @see #getFillPaintTransformer() 917 */ 918 public void setFillPaintTransformer(GradientPaintTransformer transformer) { 919 Args.nullNotPermitted(transformer, "transformer"); 920 this.fillPaintTransformer = transformer; 921 } 922 923 /** 924 * Tests this item for equality with an arbitrary object. 925 * 926 * @param obj the object ({@code null} permitted). 927 * 928 * @return A boolean. 929 */ 930 @Override 931 public boolean equals(Object obj) { 932 if (obj == this) { 933 return true; 934 } 935 if (!(obj instanceof LegendItem)) { 936 return false; 937 } 938 LegendItem that = (LegendItem) obj; 939 940 if (!Objects.equals(this.dataset, that.dataset)) { 941 return false; 942 } 943 if (!Objects.equals(this.seriesKey, that.seriesKey)) { 944 return false; 945 } 946 if (this.datasetIndex != that.datasetIndex) { 947 return false; 948 } 949 if (this.series != that.series) { 950 return false; 951 } 952 if (!Objects.equals(this.label, that.label)) { 953 return false; 954 } 955 if (!Objects.equals(this.labelFont, that.labelFont)) { 956 return false; 957 } 958 if (!Objects.equals(this.description, that.description)) { 959 return false; 960 } 961 if (!Objects.equals(this.toolTipText, that.toolTipText)) { 962 return false; 963 } 964 if (!Objects.equals(this.urlText, that.urlText)) { 965 return false; 966 } 967 if (this.shapeVisible != that.shapeVisible) { 968 return false; 969 } 970 if (this.shapeFilled != that.shapeFilled) { 971 return false; 972 } 973 if (!Objects.equals(this.fillPaintTransformer, 974 that.fillPaintTransformer)) { 975 return false; 976 } 977 if (!ShapeUtils.equal(this.shape, that.shape)) { 978 return false; 979 } 980 if (!PaintUtils.equal(this.fillPaint, that.fillPaint)) { 981 return false; 982 } 983 if (!AttributedStringUtils.equal(this.attributedLabel, 984 that.attributedLabel)) { 985 return false; 986 } 987 if (this.shapeOutlineVisible != that.shapeOutlineVisible) { 988 return false; 989 } 990 if (!Objects.equals(this.outlineStroke, that.outlineStroke)) { 991 return false; 992 } 993 if (!PaintUtils.equal(this.outlinePaint, that.outlinePaint)) { 994 return false; 995 } 996 if (!this.lineVisible == that.lineVisible) { 997 return false; 998 } 999 if (!ShapeUtils.equal(this.line, that.line)) { 1000 return false; 1001 } 1002 if (!Objects.equals(this.lineStroke, that.lineStroke)) { 1003 return false; 1004 } 1005 if (!PaintUtils.equal(this.linePaint, that.linePaint)) { 1006 return false; 1007 } 1008 if (!Objects.equals(this.labelFont, that.labelFont)) { 1009 return false; 1010 } 1011 if (!PaintUtils.equal(this.labelPaint, that.labelPaint)) { 1012 return false; 1013 } 1014 return true; 1015 } 1016 1017 @Override 1018 public int hashCode() { 1019 int hash = 7; 1020 hash = 83 * hash + Objects.hashCode(this.dataset); 1021 hash = 83 * hash + Objects.hashCode(this.seriesKey); 1022 hash = 83 * hash + this.datasetIndex; 1023 hash = 83 * hash + this.series; 1024 hash = 83 * hash + Objects.hashCode(this.label); 1025 hash = 83 * hash + Objects.hashCode(this.labelFont); 1026 hash = 83 * hash + HashUtils.hashCodeForPaint(this.labelPaint); 1027 hash = 83 * hash + Objects.hashCode(this.attributedLabel); 1028 hash = 83 * hash + Objects.hashCode(this.description); 1029 hash = 83 * hash + Objects.hashCode(this.toolTipText); 1030 hash = 83 * hash + Objects.hashCode(this.urlText); 1031 hash = 83 * hash + (this.shapeVisible ? 1 : 0); 1032 hash = 83 * hash + Objects.hashCode(this.shape); 1033 hash = 83 * hash + (this.shapeFilled ? 1 : 0); 1034 hash = 83 * hash + HashUtils.hashCodeForPaint(this.fillPaint); 1035 hash = 83 * hash + Objects.hashCode(this.fillPaintTransformer); 1036 hash = 83 * hash + (this.shapeOutlineVisible ? 1 : 0); 1037 hash = 83 * hash + HashUtils.hashCodeForPaint(this.outlinePaint); 1038 hash = 83 * hash + Objects.hashCode(this.outlineStroke); 1039 hash = 83 * hash + (this.lineVisible ? 1 : 0); 1040 hash = 83 * hash + Objects.hashCode(this.line); 1041 hash = 83 * hash + Objects.hashCode(this.lineStroke); 1042 hash = 83 * hash + HashUtils.hashCodeForPaint(this.linePaint); 1043 return hash; 1044 } 1045 1046 /** 1047 * Returns an independent copy of this object (except that the clone will 1048 * still reference the same dataset as the original {@code LegendItem}). 1049 * 1050 * @return A clone. 1051 * 1052 * @throws CloneNotSupportedException if the legend item cannot be cloned. 1053 */ 1054 @Override 1055 public Object clone() throws CloneNotSupportedException { 1056 LegendItem clone = (LegendItem) super.clone(); 1057 if (this.seriesKey instanceof PublicCloneable) { 1058 PublicCloneable pc = (PublicCloneable) this.seriesKey; 1059 clone.seriesKey = (Comparable) pc.clone(); 1060 } 1061 // FIXME: Clone the attributed string if it is not null 1062 clone.shape = ShapeUtils.clone(this.shape); 1063 if (this.fillPaintTransformer instanceof PublicCloneable) { 1064 PublicCloneable pc = (PublicCloneable) this.fillPaintTransformer; 1065 clone.fillPaintTransformer = (GradientPaintTransformer) pc.clone(); 1066 1067 } 1068 clone.line = ShapeUtils.clone(this.line); 1069 return clone; 1070 } 1071 1072 /** 1073 * Provides serialization support. 1074 * 1075 * @param stream the output stream ({@code null} not permitted). 1076 * 1077 * @throws IOException if there is an I/O error. 1078 */ 1079 private void writeObject(ObjectOutputStream stream) throws IOException { 1080 stream.defaultWriteObject(); 1081 SerialUtils.writeAttributedString(this.attributedLabel, stream); 1082 SerialUtils.writeShape(this.shape, stream); 1083 SerialUtils.writePaint(this.fillPaint, stream); 1084 SerialUtils.writeStroke(this.outlineStroke, stream); 1085 SerialUtils.writePaint(this.outlinePaint, stream); 1086 SerialUtils.writeShape(this.line, stream); 1087 SerialUtils.writeStroke(this.lineStroke, stream); 1088 SerialUtils.writePaint(this.linePaint, stream); 1089 SerialUtils.writePaint(this.labelPaint, stream); 1090 } 1091 1092 /** 1093 * Provides serialization support. 1094 * 1095 * @param stream the input stream ({@code null} not permitted). 1096 * 1097 * @throws IOException if there is an I/O error. 1098 * @throws ClassNotFoundException if there is a classpath problem. 1099 */ 1100 private void readObject(ObjectInputStream stream) 1101 throws IOException, ClassNotFoundException { 1102 stream.defaultReadObject(); 1103 this.attributedLabel = SerialUtils.readAttributedString(stream); 1104 this.shape = SerialUtils.readShape(stream); 1105 this.fillPaint = SerialUtils.readPaint(stream); 1106 this.outlineStroke = SerialUtils.readStroke(stream); 1107 this.outlinePaint = SerialUtils.readPaint(stream); 1108 this.line = SerialUtils.readShape(stream); 1109 this.lineStroke = SerialUtils.readStroke(stream); 1110 this.linePaint = SerialUtils.readPaint(stream); 1111 this.labelPaint = SerialUtils.readPaint(stream); 1112 } 1113 1114}