001 /* =========================================================== 002 * JFreeChart : a free chart library for the Java(tm) platform 003 * =========================================================== 004 * 005 * (C) Copyright 2000-2007, 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 * AbstractRenderer.java 029 * --------------------- 030 * (C) Copyright 2002-2007, by Object Refinery Limited. 031 * 032 * Original Author: David Gilbert (for Object Refinery Limited); 033 * Contributor(s): Nicolas Brodu; 034 * 035 * $Id: AbstractRenderer.java,v 1.22.2.9 2007/03/22 16:27:46 mungady Exp $ 036 * 037 * Changes: 038 * -------- 039 * 22-Aug-2002 : Version 1, draws code out of AbstractXYItemRenderer to share 040 * with AbstractCategoryItemRenderer (DG); 041 * 01-Oct-2002 : Fixed errors reported by Checkstyle (DG); 042 * 06-Nov-2002 : Moved to the com.jrefinery.chart.renderer package (DG); 043 * 21-Nov-2002 : Added a paint table for the renderer to use (DG); 044 * 17-Jan-2003 : Moved plot classes into a separate package (DG); 045 * 25-Mar-2003 : Implemented Serializable (DG); 046 * 29-Apr-2003 : Added valueLabelFont and valueLabelPaint attributes, based on 047 * code from Arnaud Lelievre (DG); 048 * 29-Jul-2003 : Amended code that doesn't compile with JDK 1.2.2 (DG); 049 * 13-Aug-2003 : Implemented Cloneable (DG); 050 * 15-Sep-2003 : Fixed serialization (NB); 051 * 17-Sep-2003 : Changed ChartRenderingInfo --> PlotRenderingInfo (DG); 052 * 07-Oct-2003 : Moved PlotRenderingInfo into RendererState to allow for 053 * multiple threads using a single renderer (DG); 054 * 20-Oct-2003 : Added missing setOutlinePaint() method (DG); 055 * 23-Oct-2003 : Split item label attributes into 'positive' and 'negative' 056 * values (DG); 057 * 26-Nov-2003 : Added methods to get the positive and negative item label 058 * positions (DG); 059 * 01-Mar-2004 : Modified readObject() method to prevent null pointer exceptions 060 * after deserialization (DG); 061 * 19-Jul-2004 : Fixed bug in getItemLabelFont(int, int) method (DG); 062 * 04-Oct-2004 : Updated equals() method, eliminated use of NumberUtils, 063 * renamed BooleanUtils --> BooleanUtilities, ShapeUtils --> 064 * ShapeUtilities (DG); 065 * 15-Mar-2005 : Fixed serialization of baseFillPaint (DG); 066 * 16-May-2005 : Base outline stroke should never be null (DG); 067 * 01-Jun-2005 : Added hasListener() method for unit testing (DG); 068 * 08-Jun-2005 : Fixed equals() method to handle GradientPaint (DG); 069 * ------------- JFREECHART 1.0.x --------------------------------------------- 070 * 02-Feb-2007 : Minor API doc update (DG); 071 * 19-Feb-2007 : Fixes for clone() method (DG); 072 * 28-Feb-2007 : Use cached event to signal changes (DG); 073 * 074 */ 075 076 package org.jfree.chart.renderer; 077 078 import java.awt.BasicStroke; 079 import java.awt.Color; 080 import java.awt.Font; 081 import java.awt.Paint; 082 import java.awt.Shape; 083 import java.awt.Stroke; 084 import java.awt.geom.Point2D; 085 import java.awt.geom.Rectangle2D; 086 import java.io.IOException; 087 import java.io.ObjectInputStream; 088 import java.io.ObjectOutputStream; 089 import java.io.Serializable; 090 import java.util.Arrays; 091 import java.util.EventListener; 092 import java.util.List; 093 094 import javax.swing.event.EventListenerList; 095 096 import org.jfree.chart.event.RendererChangeEvent; 097 import org.jfree.chart.event.RendererChangeListener; 098 import org.jfree.chart.labels.ItemLabelAnchor; 099 import org.jfree.chart.labels.ItemLabelPosition; 100 import org.jfree.chart.plot.DrawingSupplier; 101 import org.jfree.chart.plot.PlotOrientation; 102 import org.jfree.io.SerialUtilities; 103 import org.jfree.ui.TextAnchor; 104 import org.jfree.util.BooleanList; 105 import org.jfree.util.BooleanUtilities; 106 import org.jfree.util.ObjectList; 107 import org.jfree.util.ObjectUtilities; 108 import org.jfree.util.PaintList; 109 import org.jfree.util.PaintUtilities; 110 import org.jfree.util.ShapeList; 111 import org.jfree.util.ShapeUtilities; 112 import org.jfree.util.StrokeList; 113 114 /** 115 * Base class providing common services for renderers. Most methods that update 116 * attributes of the renderer will fire a {@link RendererChangeEvent}, which 117 * normally means the plot that owns the renderer will receive notification that 118 * the renderer has been changed (the plot will, in turn, notify the chart). 119 */ 120 public abstract class AbstractRenderer implements Cloneable, Serializable { 121 122 /** For serialization. */ 123 private static final long serialVersionUID = -828267569428206075L; 124 125 /** Zero represented as a <code>Double</code>. */ 126 public static final Double ZERO = new Double(0.0); 127 128 /** The default paint. */ 129 public static final Paint DEFAULT_PAINT = Color.blue; 130 131 /** The default outline paint. */ 132 public static final Paint DEFAULT_OUTLINE_PAINT = Color.gray; 133 134 /** The default stroke. */ 135 public static final Stroke DEFAULT_STROKE = new BasicStroke(1.0f); 136 137 /** The default outline stroke. */ 138 public static final Stroke DEFAULT_OUTLINE_STROKE = new BasicStroke(1.0f); 139 140 /** The default shape. */ 141 public static final Shape DEFAULT_SHAPE 142 = new Rectangle2D.Double(-3.0, -3.0, 6.0, 6.0); 143 144 /** The default value label font. */ 145 public static final Font DEFAULT_VALUE_LABEL_FONT 146 = new Font("SansSerif", Font.PLAIN, 10); 147 148 /** The default value label paint. */ 149 public static final Paint DEFAULT_VALUE_LABEL_PAINT = Color.black; 150 151 /** A flag that controls the visibility of ALL series. */ 152 private Boolean seriesVisible; 153 154 /** A list of flags that controls whether or not each series is visible. */ 155 private BooleanList seriesVisibleList; 156 157 /** The default visibility for each series. */ 158 private boolean baseSeriesVisible; 159 160 /** A flag that controls the visibility of ALL series in the legend. */ 161 private Boolean seriesVisibleInLegend; 162 163 /** 164 * A list of flags that controls whether or not each series is visible in 165 * the legend. 166 */ 167 private BooleanList seriesVisibleInLegendList; 168 169 /** The default visibility for each series in the legend. */ 170 private boolean baseSeriesVisibleInLegend; 171 172 /** The paint for ALL series (optional). */ 173 private transient Paint paint; 174 175 /** The paint list. */ 176 private PaintList paintList; 177 178 /** The base paint. */ 179 private transient Paint basePaint; 180 181 /** The fill paint for ALL series (optional). */ 182 private transient Paint fillPaint; 183 184 /** The fill paint list. */ 185 private PaintList fillPaintList; 186 187 /** The base fill paint. */ 188 private transient Paint baseFillPaint; 189 190 /** The outline paint for ALL series (optional). */ 191 private transient Paint outlinePaint; 192 193 /** The outline paint list. */ 194 private PaintList outlinePaintList; 195 196 /** The base outline paint. */ 197 private transient Paint baseOutlinePaint; 198 199 /** The stroke for ALL series (optional). */ 200 private transient Stroke stroke; 201 202 /** The stroke list. */ 203 private StrokeList strokeList; 204 205 /** The base stroke. */ 206 private transient Stroke baseStroke; 207 208 /** The outline stroke for ALL series (optional). */ 209 private transient Stroke outlineStroke; 210 211 /** The outline stroke list. */ 212 private StrokeList outlineStrokeList; 213 214 /** The base outline stroke. */ 215 private transient Stroke baseOutlineStroke; 216 217 /** The shape for ALL series (optional). */ 218 private transient Shape shape; 219 220 /** A shape list. */ 221 private ShapeList shapeList; 222 223 /** The base shape. */ 224 private transient Shape baseShape; 225 226 /** Visibility of the item labels for ALL series (optional). */ 227 private Boolean itemLabelsVisible; 228 229 /** Visibility of the item labels PER series. */ 230 private BooleanList itemLabelsVisibleList; 231 232 /** The base item labels visible. */ 233 private Boolean baseItemLabelsVisible; 234 235 /** The item label font for ALL series (optional). */ 236 private Font itemLabelFont; 237 238 /** The item label font list (one font per series). */ 239 private ObjectList itemLabelFontList; 240 241 /** The base item label font. */ 242 private Font baseItemLabelFont; 243 244 /** The item label paint for ALL series. */ 245 private transient Paint itemLabelPaint; 246 247 /** The item label paint list (one paint per series). */ 248 private PaintList itemLabelPaintList; 249 250 /** The base item label paint. */ 251 private transient Paint baseItemLabelPaint; 252 253 /** The positive item label position for ALL series (optional). */ 254 private ItemLabelPosition positiveItemLabelPosition; 255 256 /** The positive item label position (per series). */ 257 private ObjectList positiveItemLabelPositionList; 258 259 /** The fallback positive item label position. */ 260 private ItemLabelPosition basePositiveItemLabelPosition; 261 262 /** The negative item label position for ALL series (optional). */ 263 private ItemLabelPosition negativeItemLabelPosition; 264 265 /** The negative item label position (per series). */ 266 private ObjectList negativeItemLabelPositionList; 267 268 /** The fallback negative item label position. */ 269 private ItemLabelPosition baseNegativeItemLabelPosition; 270 271 /** The item label anchor offset. */ 272 private double itemLabelAnchorOffset = 2.0; 273 274 /** 275 * A flag that controls whether or not entities are generated for 276 * ALL series (optional). 277 */ 278 private Boolean createEntities; 279 280 /** 281 * Flags that control whether or not entities are generated for each 282 * series. This will be overridden by 'createEntities'. 283 */ 284 private BooleanList createEntitiesList; 285 286 /** 287 * The default flag that controls whether or not entities are generated. 288 * This flag is used when both the above flags return null. 289 */ 290 private boolean baseCreateEntities; 291 292 /** Storage for registered change listeners. */ 293 private transient EventListenerList listenerList; 294 295 /** An event for re-use. */ 296 private transient RendererChangeEvent event; 297 298 /** 299 * Default constructor. 300 */ 301 public AbstractRenderer() { 302 303 this.seriesVisible = null; 304 this.seriesVisibleList = new BooleanList(); 305 this.baseSeriesVisible = true; 306 307 this.seriesVisibleInLegend = null; 308 this.seriesVisibleInLegendList = new BooleanList(); 309 this.baseSeriesVisibleInLegend = true; 310 311 this.paint = null; 312 this.paintList = new PaintList(); 313 this.basePaint = DEFAULT_PAINT; 314 315 this.fillPaint = null; 316 this.fillPaintList = new PaintList(); 317 this.baseFillPaint = Color.white; 318 319 this.outlinePaint = null; 320 this.outlinePaintList = new PaintList(); 321 this.baseOutlinePaint = DEFAULT_OUTLINE_PAINT; 322 323 this.stroke = null; 324 this.strokeList = new StrokeList(); 325 this.baseStroke = DEFAULT_STROKE; 326 327 this.outlineStroke = null; 328 this.outlineStrokeList = new StrokeList(); 329 this.baseOutlineStroke = DEFAULT_OUTLINE_STROKE; 330 331 this.shape = null; 332 this.shapeList = new ShapeList(); 333 this.baseShape = DEFAULT_SHAPE; 334 335 this.itemLabelsVisible = null; 336 this.itemLabelsVisibleList = new BooleanList(); 337 this.baseItemLabelsVisible = Boolean.FALSE; 338 339 this.itemLabelFont = null; 340 this.itemLabelFontList = new ObjectList(); 341 this.baseItemLabelFont = new Font("SansSerif", Font.PLAIN, 10); 342 343 this.itemLabelPaint = null; 344 this.itemLabelPaintList = new PaintList(); 345 this.baseItemLabelPaint = Color.black; 346 347 this.positiveItemLabelPosition = null; 348 this.positiveItemLabelPositionList = new ObjectList(); 349 this.basePositiveItemLabelPosition = new ItemLabelPosition( 350 ItemLabelAnchor.OUTSIDE12, TextAnchor.BOTTOM_CENTER); 351 352 this.negativeItemLabelPosition = null; 353 this.negativeItemLabelPositionList = new ObjectList(); 354 this.baseNegativeItemLabelPosition = new ItemLabelPosition( 355 ItemLabelAnchor.OUTSIDE6, TextAnchor.TOP_CENTER); 356 357 this.createEntities = null; 358 this.createEntitiesList = new BooleanList(); 359 this.baseCreateEntities = true; 360 361 this.listenerList = new EventListenerList(); 362 363 } 364 365 /** 366 * Returns the drawing supplier from the plot. 367 * 368 * @return The drawing supplier. 369 */ 370 public abstract DrawingSupplier getDrawingSupplier(); 371 372 // SERIES VISIBLE (not yet respected by all renderers) 373 374 /** 375 * Returns a boolean that indicates whether or not the specified item 376 * should be drawn (this is typically used to hide an entire series). 377 * 378 * @param series the series index. 379 * @param item the item index. 380 * 381 * @return A boolean. 382 */ 383 public boolean getItemVisible(int series, int item) { 384 return isSeriesVisible(series); 385 } 386 387 /** 388 * Returns a boolean that indicates whether or not the specified series 389 * should be drawn. 390 * 391 * @param series the series index. 392 * 393 * @return A boolean. 394 */ 395 public boolean isSeriesVisible(int series) { 396 boolean result = this.baseSeriesVisible; 397 if (this.seriesVisible != null) { 398 result = this.seriesVisible.booleanValue(); 399 } 400 else { 401 Boolean b = this.seriesVisibleList.getBoolean(series); 402 if (b != null) { 403 result = b.booleanValue(); 404 } 405 } 406 return result; 407 } 408 409 /** 410 * Returns the flag that controls the visibility of ALL series. This flag 411 * overrides the per series and default settings - you must set it to 412 * <code>null</code> if you want the other settings to apply. 413 * 414 * @return The flag (possibly <code>null</code>). 415 * 416 * @see #setSeriesVisible(Boolean) 417 */ 418 public Boolean getSeriesVisible() { 419 return this.seriesVisible; 420 } 421 422 /** 423 * Sets the flag that controls the visibility of ALL series and sends a 424 * {@link RendererChangeEvent} to all registered listeners. This flag 425 * overrides the per series and default settings - you must set it to 426 * <code>null</code> if you want the other settings to apply. 427 * 428 * @param visible the flag (<code>null</code> permitted). 429 * 430 * @see #getSeriesVisible() 431 */ 432 public void setSeriesVisible(Boolean visible) { 433 setSeriesVisible(visible, true); 434 } 435 436 /** 437 * Sets the flag that controls the visibility of ALL series and sends a 438 * {@link RendererChangeEvent} to all registered listeners. This flag 439 * overrides the per series and default settings - you must set it to 440 * <code>null</code> if you want the other settings to apply. 441 * 442 * @param visible the flag (<code>null</code> permitted). 443 * @param notify notify listeners? 444 * 445 * @see #getSeriesVisible() 446 */ 447 public void setSeriesVisible(Boolean visible, boolean notify) { 448 this.seriesVisible = visible; 449 if (notify) { 450 fireChangeEvent(); 451 } 452 } 453 454 /** 455 * Returns the flag that controls whether a series is visible. 456 * 457 * @param series the series index (zero-based). 458 * 459 * @return The flag (possibly <code>null</code>). 460 * 461 * @see #setSeriesVisible(int, Boolean) 462 */ 463 public Boolean getSeriesVisible(int series) { 464 return this.seriesVisibleList.getBoolean(series); 465 } 466 467 /** 468 * Sets the flag that controls whether a series is visible and sends a 469 * {@link RendererChangeEvent} to all registered listeners. 470 * 471 * @param series the series index (zero-based). 472 * @param visible the flag (<code>null</code> permitted). 473 * 474 * @see #getSeriesVisible(int) 475 */ 476 public void setSeriesVisible(int series, Boolean visible) { 477 setSeriesVisible(series, visible, true); 478 } 479 480 /** 481 * Sets the flag that controls whether a series is visible and, if 482 * requested, sends a {@link RendererChangeEvent} to all registered 483 * listeners. 484 * 485 * @param series the series index. 486 * @param visible the flag (<code>null</code> permitted). 487 * @param notify notify listeners? 488 * 489 * @see #getSeriesVisible(int) 490 */ 491 public void setSeriesVisible(int series, Boolean visible, boolean notify) { 492 this.seriesVisibleList.setBoolean(series, visible); 493 if (notify) { 494 fireChangeEvent(); 495 } 496 } 497 498 /** 499 * Returns the base visibility for all series. 500 * 501 * @return The base visibility. 502 * 503 * @see #setBaseSeriesVisible(boolean) 504 */ 505 public boolean getBaseSeriesVisible() { 506 return this.baseSeriesVisible; 507 } 508 509 /** 510 * Sets the base visibility and sends a {@link RendererChangeEvent} 511 * to all registered listeners. 512 * 513 * @param visible the flag. 514 * 515 * @see #getBaseSeriesVisible() 516 */ 517 public void setBaseSeriesVisible(boolean visible) { 518 // defer argument checking... 519 setBaseSeriesVisible(visible, true); 520 } 521 522 /** 523 * Sets the base visibility and, if requested, sends 524 * a {@link RendererChangeEvent} to all registered listeners. 525 * 526 * @param visible the visibility. 527 * @param notify notify listeners? 528 * 529 * @see #getBaseSeriesVisible() 530 */ 531 public void setBaseSeriesVisible(boolean visible, boolean notify) { 532 this.baseSeriesVisible = visible; 533 if (notify) { 534 fireChangeEvent(); 535 } 536 } 537 538 // SERIES VISIBLE IN LEGEND (not yet respected by all renderers) 539 540 /** 541 * Returns <code>true</code> if the series should be shown in the legend, 542 * and <code>false</code> otherwise. 543 * 544 * @param series the series index. 545 * 546 * @return A boolean. 547 */ 548 public boolean isSeriesVisibleInLegend(int series) { 549 boolean result = this.baseSeriesVisibleInLegend; 550 if (this.seriesVisibleInLegend != null) { 551 result = this.seriesVisibleInLegend.booleanValue(); 552 } 553 else { 554 Boolean b = this.seriesVisibleInLegendList.getBoolean(series); 555 if (b != null) { 556 result = b.booleanValue(); 557 } 558 } 559 return result; 560 } 561 562 /** 563 * Returns the flag that controls the visibility of ALL series in the 564 * legend. This flag overrides the per series and default settings - you 565 * must set it to <code>null</code> if you want the other settings to 566 * apply. 567 * 568 * @return The flag (possibly <code>null</code>). 569 * 570 * @see #setSeriesVisibleInLegend(Boolean) 571 */ 572 public Boolean getSeriesVisibleInLegend() { 573 return this.seriesVisibleInLegend; 574 } 575 576 /** 577 * Sets the flag that controls the visibility of ALL series in the legend 578 * and sends a {@link RendererChangeEvent} to all registered listeners. 579 * This flag overrides the per series and default settings - you must set 580 * it to <code>null</code> if you want the other settings to apply. 581 * 582 * @param visible the flag (<code>null</code> permitted). 583 * 584 * @see #getSeriesVisibleInLegend() 585 */ 586 public void setSeriesVisibleInLegend(Boolean visible) { 587 setSeriesVisibleInLegend(visible, true); 588 } 589 590 /** 591 * Sets the flag that controls the visibility of ALL series in the legend 592 * and sends a {@link RendererChangeEvent} to all registered listeners. 593 * This flag overrides the per series and default settings - you must set 594 * it to <code>null</code> if you want the other settings to apply. 595 * 596 * @param visible the flag (<code>null</code> permitted). 597 * @param notify notify listeners? 598 * 599 * @see #getSeriesVisibleInLegend() 600 */ 601 public void setSeriesVisibleInLegend(Boolean visible, boolean notify) { 602 this.seriesVisibleInLegend = visible; 603 if (notify) { 604 fireChangeEvent(); 605 } 606 } 607 608 /** 609 * Returns the flag that controls whether a series is visible in the 610 * legend. This method returns only the "per series" settings - to 611 * incorporate the override and base settings as well, you need to use the 612 * {@link #isSeriesVisibleInLegend(int)} method. 613 * 614 * @param series the series index (zero-based). 615 * 616 * @return The flag (possibly <code>null</code>). 617 * 618 * @see #setSeriesVisibleInLegend(int, Boolean) 619 */ 620 public Boolean getSeriesVisibleInLegend(int series) { 621 return this.seriesVisibleInLegendList.getBoolean(series); 622 } 623 624 /** 625 * Sets the flag that controls whether a series is visible in the legend 626 * and sends a {@link RendererChangeEvent} to all registered listeners. 627 * 628 * @param series the series index (zero-based). 629 * @param visible the flag (<code>null</code> permitted). 630 * 631 * @see #getSeriesVisibleInLegend(int) 632 */ 633 public void setSeriesVisibleInLegend(int series, Boolean visible) { 634 setSeriesVisibleInLegend(series, visible, true); 635 } 636 637 /** 638 * Sets the flag that controls whether a series is visible in the legend 639 * and, if requested, sends a {@link RendererChangeEvent} to all registered 640 * listeners. 641 * 642 * @param series the series index. 643 * @param visible the flag (<code>null</code> permitted). 644 * @param notify notify listeners? 645 * 646 * @see #getSeriesVisibleInLegend(int) 647 */ 648 public void setSeriesVisibleInLegend(int series, Boolean visible, 649 boolean notify) { 650 this.seriesVisibleInLegendList.setBoolean(series, visible); 651 if (notify) { 652 fireChangeEvent(); 653 } 654 } 655 656 /** 657 * Returns the base visibility in the legend for all series. 658 * 659 * @return The base visibility. 660 * 661 * @see #setBaseSeriesVisibleInLegend(boolean) 662 */ 663 public boolean getBaseSeriesVisibleInLegend() { 664 return this.baseSeriesVisibleInLegend; 665 } 666 667 /** 668 * Sets the base visibility in the legend and sends a 669 * {@link RendererChangeEvent} to all registered listeners. 670 * 671 * @param visible the flag. 672 * 673 * @see #getSeriesVisibleInLegend() 674 */ 675 public void setBaseSeriesVisibleInLegend(boolean visible) { 676 // defer argument checking... 677 setBaseSeriesVisibleInLegend(visible, true); 678 } 679 680 /** 681 * Sets the base visibility in the legend and, if requested, sends 682 * a {@link RendererChangeEvent} to all registered listeners. 683 * 684 * @param visible the visibility. 685 * @param notify notify listeners? 686 * 687 * @see #getSeriesVisibleInLegend() 688 */ 689 public void setBaseSeriesVisibleInLegend(boolean visible, boolean notify) { 690 this.baseSeriesVisibleInLegend = visible; 691 if (notify) { 692 fireChangeEvent(); 693 } 694 } 695 696 // PAINT 697 698 /** 699 * Returns the paint used to fill data items as they are drawn. 700 * <p> 701 * The default implementation passes control to the 702 * <code>getSeriesPaint</code> method. You can override this method if you 703 * require different behaviour. 704 * 705 * @param row the row (or series) index (zero-based). 706 * @param column the column (or category) index (zero-based). 707 * 708 * @return The paint (never <code>null</code>). 709 */ 710 public Paint getItemPaint(int row, int column) { 711 return getSeriesPaint(row); 712 } 713 714 /** 715 * Returns the paint used to fill an item drawn by the renderer. 716 * 717 * @param series the series index (zero-based). 718 * 719 * @return The paint (never <code>null</code>). 720 */ 721 public Paint getSeriesPaint(int series) { 722 723 // return the override, if there is one... 724 if (this.paint != null) { 725 return this.paint; 726 } 727 728 // otherwise look up the paint list 729 Paint seriesPaint = this.paintList.getPaint(series); 730 if (seriesPaint == null) { 731 DrawingSupplier supplier = getDrawingSupplier(); 732 if (supplier != null) { 733 seriesPaint = supplier.getNextPaint(); 734 this.paintList.setPaint(series, seriesPaint); 735 } 736 else { 737 seriesPaint = this.basePaint; 738 } 739 } 740 return seriesPaint; 741 742 } 743 744 /** 745 * Sets the paint to be used for ALL series, and sends a 746 * {@link RendererChangeEvent} to all registered listeners. If this is 747 * <code>null</code>, the renderer will use the paint for the series. 748 * 749 * @param paint the paint (<code>null</code> permitted). 750 */ 751 public void setPaint(Paint paint) { 752 setPaint(paint, true); 753 } 754 755 /** 756 * Sets the paint to be used for all series and, if requested, sends a 757 * {@link RendererChangeEvent} to all registered listeners. 758 * 759 * @param paint the paint (<code>null</code> permitted). 760 * @param notify notify listeners? 761 */ 762 public void setPaint(Paint paint, boolean notify) { 763 this.paint = paint; 764 if (notify) { 765 fireChangeEvent(); 766 } 767 } 768 769 /** 770 * Sets the paint used for a series and sends a {@link RendererChangeEvent} 771 * to all registered listeners. 772 * 773 * @param series the series index (zero-based). 774 * @param paint the paint (<code>null</code> permitted). 775 */ 776 public void setSeriesPaint(int series, Paint paint) { 777 setSeriesPaint(series, paint, true); 778 } 779 780 /** 781 * Sets the paint used for a series and, if requested, sends a 782 * {@link RendererChangeEvent} to all registered listeners. 783 * 784 * @param series the series index. 785 * @param paint the paint (<code>null</code> permitted). 786 * @param notify notify listeners? 787 */ 788 public void setSeriesPaint(int series, Paint paint, boolean notify) { 789 this.paintList.setPaint(series, paint); 790 if (notify) { 791 fireChangeEvent(); 792 } 793 } 794 795 /** 796 * Returns the base paint. 797 * 798 * @return The base paint (never <code>null</code>). 799 */ 800 public Paint getBasePaint() { 801 return this.basePaint; 802 } 803 804 /** 805 * Sets the base paint and sends a {@link RendererChangeEvent} to all 806 * registered listeners. 807 * 808 * @param paint the paint (<code>null</code> not permitted). 809 */ 810 public void setBasePaint(Paint paint) { 811 // defer argument checking... 812 setBasePaint(paint, true); 813 } 814 815 /** 816 * Sets the base paint and, if requested, sends a 817 * {@link RendererChangeEvent} to all registered listeners. 818 * 819 * @param paint the paint (<code>null</code> not permitted). 820 * @param notify notify listeners? 821 */ 822 public void setBasePaint(Paint paint, boolean notify) { 823 this.basePaint = paint; 824 if (notify) { 825 fireChangeEvent(); 826 } 827 } 828 829 //// FILL PAINT ////////////////////////////////////////////////////////// 830 831 /** 832 * Returns the paint used to fill data items as they are drawn. The 833 * default implementation passes control to the 834 * {@link #getSeriesFillPaint(int)} method - you can override this method 835 * if you require different behaviour. 836 * 837 * @param row the row (or series) index (zero-based). 838 * @param column the column (or category) index (zero-based). 839 * 840 * @return The paint (never <code>null</code>). 841 */ 842 public Paint getItemFillPaint(int row, int column) { 843 return getSeriesFillPaint(row); 844 } 845 846 /** 847 * Returns the paint used to fill an item drawn by the renderer. 848 * 849 * @param series the series (zero-based index). 850 * 851 * @return The paint (never <code>null</code>). 852 */ 853 public Paint getSeriesFillPaint(int series) { 854 855 // return the override, if there is one... 856 if (this.fillPaint != null) { 857 return this.fillPaint; 858 } 859 860 // otherwise look up the paint table 861 Paint seriesFillPaint = this.fillPaintList.getPaint(series); 862 if (seriesFillPaint == null) { 863 seriesFillPaint = this.baseFillPaint; 864 } 865 return seriesFillPaint; 866 867 } 868 869 /** 870 * Sets the paint used for a series fill and sends a 871 * {@link RendererChangeEvent} to all registered listeners. 872 * 873 * @param series the series index (zero-based). 874 * @param paint the paint (<code>null</code> permitted). 875 */ 876 public void setSeriesFillPaint(int series, Paint paint) { 877 setSeriesFillPaint(series, paint, true); 878 } 879 880 /** 881 * Sets the paint used to fill a series and, if requested, 882 * sends a {@link RendererChangeEvent} to all registered listeners. 883 * 884 * @param series the series index (zero-based). 885 * @param paint the paint (<code>null</code> permitted). 886 * @param notify notify listeners? 887 */ 888 public void setSeriesFillPaint(int series, Paint paint, boolean notify) { 889 this.fillPaintList.setPaint(series, paint); 890 if (notify) { 891 fireChangeEvent(); 892 } 893 } 894 895 /** 896 * Sets the fill paint for ALL series (optional). 897 * 898 * @param paint the paint (<code>null</code> permitted). 899 */ 900 public void setFillPaint(Paint paint) { 901 setFillPaint(paint, true); 902 } 903 904 /** 905 * Sets the fill paint for ALL series and, if requested, sends a 906 * {@link RendererChangeEvent} to all registered listeners. 907 * 908 * @param paint the paint (<code>null</code> permitted). 909 * @param notify notify listeners? 910 */ 911 public void setFillPaint(Paint paint, boolean notify) { 912 this.fillPaint = paint; 913 if (notify) { 914 fireChangeEvent(); 915 } 916 } 917 918 /** 919 * Returns the base fill paint. 920 * 921 * @return The paint (never <code>null</code>). 922 */ 923 public Paint getBaseFillPaint() { 924 return this.baseFillPaint; 925 } 926 927 /** 928 * Sets the base fill paint and sends a {@link RendererChangeEvent} to 929 * all registered listeners. 930 * 931 * @param paint the paint (<code>null</code> not permitted). 932 */ 933 public void setBaseFillPaint(Paint paint) { 934 // defer argument checking... 935 setBaseFillPaint(paint, true); 936 } 937 938 /** 939 * Sets the base fill paint and, if requested, sends a 940 * {@link RendererChangeEvent} to all registered listeners. 941 * 942 * @param paint the paint (<code>null</code> not permitted). 943 * @param notify notify listeners? 944 */ 945 public void setBaseFillPaint(Paint paint, boolean notify) { 946 if (paint == null) { 947 throw new IllegalArgumentException("Null 'paint' argument."); 948 } 949 this.baseFillPaint = paint; 950 if (notify) { 951 fireChangeEvent(); 952 } 953 } 954 955 // OUTLINE PAINT ////////////////////////////////////////////////////////// 956 957 /** 958 * Returns the paint used to outline data items as they are drawn. 959 * <p> 960 * The default implementation passes control to the getSeriesOutlinePaint 961 * method. You can override this method if you require different behaviour. 962 * 963 * @param row the row (or series) index (zero-based). 964 * @param column the column (or category) index (zero-based). 965 * 966 * @return The paint (never <code>null</code>). 967 */ 968 public Paint getItemOutlinePaint(int row, int column) { 969 return getSeriesOutlinePaint(row); 970 } 971 972 /** 973 * Returns the paint used to outline an item drawn by the renderer. 974 * 975 * @param series the series (zero-based index). 976 * 977 * @return The paint (never <code>null</code>). 978 */ 979 public Paint getSeriesOutlinePaint(int series) { 980 981 // return the override, if there is one... 982 if (this.outlinePaint != null) { 983 return this.outlinePaint; 984 } 985 986 // otherwise look up the paint table 987 Paint seriesOutlinePaint = this.outlinePaintList.getPaint(series); 988 if (seriesOutlinePaint == null) { 989 DrawingSupplier supplier = getDrawingSupplier(); 990 if (supplier != null) { 991 seriesOutlinePaint = supplier.getNextOutlinePaint(); 992 this.outlinePaintList.setPaint(series, seriesOutlinePaint); 993 } 994 else { 995 seriesOutlinePaint = this.baseOutlinePaint; 996 } 997 } 998 return seriesOutlinePaint; 999 1000 } 1001 1002 /** 1003 * Sets the paint used for a series outline and sends a 1004 * {@link RendererChangeEvent} to all registered listeners. 1005 * 1006 * @param series the series index (zero-based). 1007 * @param paint the paint (<code>null</code> permitted). 1008 */ 1009 public void setSeriesOutlinePaint(int series, Paint paint) { 1010 setSeriesOutlinePaint(series, paint, true); 1011 } 1012 1013 /** 1014 * Sets the paint used to draw the outline for a series and, if requested, 1015 * sends a {@link RendererChangeEvent} to all registered listeners. 1016 * 1017 * @param series the series index (zero-based). 1018 * @param paint the paint (<code>null</code> permitted). 1019 * @param notify notify listeners? 1020 */ 1021 public void setSeriesOutlinePaint(int series, Paint paint, boolean notify) { 1022 this.outlinePaintList.setPaint(series, paint); 1023 if (notify) { 1024 fireChangeEvent(); 1025 } 1026 } 1027 1028 /** 1029 * Sets the outline paint for ALL series (optional). 1030 * 1031 * @param paint the paint (<code>null</code> permitted). 1032 */ 1033 public void setOutlinePaint(Paint paint) { 1034 setOutlinePaint(paint, true); 1035 } 1036 1037 /** 1038 * Sets the outline paint for ALL series and, if requested, sends a 1039 * {@link RendererChangeEvent} to all registered listeners. 1040 * 1041 * @param paint the paint (<code>null</code> permitted). 1042 * @param notify notify listeners? 1043 */ 1044 public void setOutlinePaint(Paint paint, boolean notify) { 1045 this.outlinePaint = paint; 1046 if (notify) { 1047 fireChangeEvent(); 1048 } 1049 } 1050 1051 /** 1052 * Returns the base outline paint. 1053 * 1054 * @return The paint (never <code>null</code>). 1055 */ 1056 public Paint getBaseOutlinePaint() { 1057 return this.baseOutlinePaint; 1058 } 1059 1060 /** 1061 * Sets the base outline paint and sends a {@link RendererChangeEvent} to 1062 * all registered listeners. 1063 * 1064 * @param paint the paint (<code>null</code> not permitted). 1065 */ 1066 public void setBaseOutlinePaint(Paint paint) { 1067 // defer argument checking... 1068 setBaseOutlinePaint(paint, true); 1069 } 1070 1071 /** 1072 * Sets the base outline paint and, if requested, sends a 1073 * {@link RendererChangeEvent} to all registered listeners. 1074 * 1075 * @param paint the paint (<code>null</code> not permitted). 1076 * @param notify notify listeners? 1077 */ 1078 public void setBaseOutlinePaint(Paint paint, boolean notify) { 1079 if (paint == null) { 1080 throw new IllegalArgumentException("Null 'paint' argument."); 1081 } 1082 this.baseOutlinePaint = paint; 1083 if (notify) { 1084 fireChangeEvent(); 1085 } 1086 } 1087 1088 // STROKE 1089 1090 /** 1091 * Returns the stroke used to draw data items. 1092 * <p> 1093 * The default implementation passes control to the getSeriesStroke method. 1094 * You can override this method if you require different behaviour. 1095 * 1096 * @param row the row (or series) index (zero-based). 1097 * @param column the column (or category) index (zero-based). 1098 * 1099 * @return The stroke (never <code>null</code>). 1100 */ 1101 public Stroke getItemStroke(int row, int column) { 1102 return getSeriesStroke(row); 1103 } 1104 1105 /** 1106 * Returns the stroke used to draw the items in a series. 1107 * 1108 * @param series the series (zero-based index). 1109 * 1110 * @return The stroke (never <code>null</code>). 1111 */ 1112 public Stroke getSeriesStroke(int series) { 1113 1114 // return the override, if there is one... 1115 if (this.stroke != null) { 1116 return this.stroke; 1117 } 1118 1119 // otherwise look up the paint table 1120 Stroke result = this.strokeList.getStroke(series); 1121 if (result == null) { 1122 DrawingSupplier supplier = getDrawingSupplier(); 1123 if (supplier != null) { 1124 result = supplier.getNextStroke(); 1125 this.strokeList.setStroke(series, result); 1126 } 1127 else { 1128 result = this.baseStroke; 1129 } 1130 } 1131 return result; 1132 1133 } 1134 1135 /** 1136 * Sets the stroke for ALL series and sends a {@link RendererChangeEvent} 1137 * to all registered listeners. 1138 * 1139 * @param stroke the stroke (<code>null</code> permitted). 1140 */ 1141 public void setStroke(Stroke stroke) { 1142 setStroke(stroke, true); 1143 } 1144 1145 /** 1146 * Sets the stroke for ALL series and, if requested, sends a 1147 * {@link RendererChangeEvent} to all registered listeners. 1148 * 1149 * @param stroke the stroke (<code>null</code> permitted). 1150 * @param notify notify listeners? 1151 */ 1152 public void setStroke(Stroke stroke, boolean notify) { 1153 this.stroke = stroke; 1154 if (notify) { 1155 fireChangeEvent(); 1156 } 1157 } 1158 1159 /** 1160 * Sets the stroke used for a series and sends a {@link RendererChangeEvent} 1161 * to all registered listeners. 1162 * 1163 * @param series the series index (zero-based). 1164 * @param stroke the stroke (<code>null</code> permitted). 1165 */ 1166 public void setSeriesStroke(int series, Stroke stroke) { 1167 setSeriesStroke(series, stroke, true); 1168 } 1169 1170 /** 1171 * Sets the stroke for a series and, if requested, sends a 1172 * {@link RendererChangeEvent} to all registered listeners. 1173 * 1174 * @param series the series index (zero-based). 1175 * @param stroke the stroke (<code>null</code> permitted). 1176 * @param notify notify listeners? 1177 */ 1178 public void setSeriesStroke(int series, Stroke stroke, boolean notify) { 1179 this.strokeList.setStroke(series, stroke); 1180 if (notify) { 1181 fireChangeEvent(); 1182 } 1183 } 1184 1185 /** 1186 * Returns the base stroke. 1187 * 1188 * @return The base stroke (never <code>null</code>). 1189 */ 1190 public Stroke getBaseStroke() { 1191 return this.baseStroke; 1192 } 1193 1194 /** 1195 * Sets the base stroke. 1196 * 1197 * @param stroke the stroke (<code>null</code> not permitted). 1198 */ 1199 public void setBaseStroke(Stroke stroke) { 1200 // defer argument checking... 1201 setBaseStroke(stroke, true); 1202 } 1203 1204 /** 1205 * Sets the base stroke and, if requested, sends a 1206 * {@link RendererChangeEvent} to all registered listeners. 1207 * 1208 * @param stroke the stroke (<code>null</code> not permitted). 1209 * @param notify notify listeners? 1210 */ 1211 public void setBaseStroke(Stroke stroke, boolean notify) { 1212 if (stroke == null) { 1213 throw new IllegalArgumentException("Null 'stroke' argument."); 1214 } 1215 this.baseStroke = stroke; 1216 if (notify) { 1217 fireChangeEvent(); 1218 } 1219 } 1220 1221 // OUTLINE STROKE 1222 1223 /** 1224 * Returns the stroke used to outline data items. The default 1225 * implementation passes control to the {@link #getSeriesOutlineStroke(int)} 1226 * method. You can override this method if you require different behaviour. 1227 * 1228 * @param row the row (or series) index (zero-based). 1229 * @param column the column (or category) index (zero-based). 1230 * 1231 * @return The stroke (never <code>null</code>). 1232 */ 1233 public Stroke getItemOutlineStroke(int row, int column) { 1234 return getSeriesOutlineStroke(row); 1235 } 1236 1237 /** 1238 * Returns the stroke used to outline the items in a series. 1239 * 1240 * @param series the series (zero-based index). 1241 * 1242 * @return The stroke (never <code>null</code>). 1243 */ 1244 public Stroke getSeriesOutlineStroke(int series) { 1245 1246 // return the override, if there is one... 1247 if (this.outlineStroke != null) { 1248 return this.outlineStroke; 1249 } 1250 1251 // otherwise look up the stroke table 1252 Stroke result = this.outlineStrokeList.getStroke(series); 1253 if (result == null) { 1254 DrawingSupplier supplier = getDrawingSupplier(); 1255 if (supplier != null) { 1256 result = supplier.getNextOutlineStroke(); 1257 this.outlineStrokeList.setStroke(series, result); 1258 } 1259 else { 1260 result = this.baseOutlineStroke; 1261 } 1262 } 1263 return result; 1264 1265 } 1266 1267 /** 1268 * Sets the outline stroke for ALL series and sends a 1269 * {@link RendererChangeEvent} to all registered listeners. 1270 * 1271 * @param stroke the stroke (<code>null</code> permitted). 1272 */ 1273 public void setOutlineStroke(Stroke stroke) { 1274 setOutlineStroke(stroke, true); 1275 } 1276 1277 /** 1278 * Sets the outline stroke for ALL series and, if requested, sends a 1279 * {@link RendererChangeEvent} to all registered listeners. 1280 * 1281 * @param stroke the stroke (<code>null</code> permitted). 1282 * @param notify notify listeners? 1283 */ 1284 public void setOutlineStroke(Stroke stroke, boolean notify) { 1285 this.outlineStroke = stroke; 1286 if (notify) { 1287 fireChangeEvent(); 1288 } 1289 } 1290 1291 /** 1292 * Sets the outline stroke used for a series and sends a 1293 * {@link RendererChangeEvent} to all registered listeners. 1294 * 1295 * @param series the series index (zero-based). 1296 * @param stroke the stroke (<code>null</code> permitted). 1297 */ 1298 public void setSeriesOutlineStroke(int series, Stroke stroke) { 1299 setSeriesOutlineStroke(series, stroke, true); 1300 } 1301 1302 /** 1303 * Sets the outline stroke for a series and, if requested, sends a 1304 * {@link RendererChangeEvent} to all registered listeners. 1305 * 1306 * @param series the series index. 1307 * @param stroke the stroke (<code>null</code> permitted). 1308 * @param notify notify listeners? 1309 */ 1310 public void setSeriesOutlineStroke(int series, Stroke stroke, 1311 boolean notify) { 1312 this.outlineStrokeList.setStroke(series, stroke); 1313 if (notify) { 1314 fireChangeEvent(); 1315 } 1316 } 1317 1318 /** 1319 * Returns the base outline stroke. 1320 * 1321 * @return The stroke (never <code>null</code>). 1322 */ 1323 public Stroke getBaseOutlineStroke() { 1324 return this.baseOutlineStroke; 1325 } 1326 1327 /** 1328 * Sets the base outline stroke and sends a {@link RendererChangeEvent} to 1329 * all registered listeners. 1330 * 1331 * @param stroke the stroke (<code>null</code> not permitted). 1332 */ 1333 public void setBaseOutlineStroke(Stroke stroke) { 1334 setBaseOutlineStroke(stroke, true); 1335 } 1336 1337 /** 1338 * Sets the base outline stroke and, if requested, sends a 1339 * {@link RendererChangeEvent} to all registered listeners. 1340 * 1341 * @param stroke the stroke (<code>null</code> not permitted). 1342 * @param notify a flag that controls whether or not listeners are 1343 * notified. 1344 */ 1345 public void setBaseOutlineStroke(Stroke stroke, boolean notify) { 1346 if (stroke == null) { 1347 throw new IllegalArgumentException("Null 'stroke' argument."); 1348 } 1349 this.baseOutlineStroke = stroke; 1350 if (notify) { 1351 fireChangeEvent(); 1352 } 1353 } 1354 1355 // SHAPE 1356 1357 /** 1358 * Returns a shape used to represent a data item. 1359 * <p> 1360 * The default implementation passes control to the getSeriesShape method. 1361 * You can override this method if you require different behaviour. 1362 * 1363 * @param row the row (or series) index (zero-based). 1364 * @param column the column (or category) index (zero-based). 1365 * 1366 * @return The shape (never <code>null</code>). 1367 */ 1368 public Shape getItemShape(int row, int column) { 1369 return getSeriesShape(row); 1370 } 1371 1372 /** 1373 * Returns a shape used to represent the items in a series. 1374 * 1375 * @param series the series (zero-based index). 1376 * 1377 * @return The shape (never <code>null</code>). 1378 */ 1379 public Shape getSeriesShape(int series) { 1380 1381 // return the override, if there is one... 1382 if (this.shape != null) { 1383 return this.shape; 1384 } 1385 1386 // otherwise look up the shape list 1387 Shape result = this.shapeList.getShape(series); 1388 if (result == null) { 1389 DrawingSupplier supplier = getDrawingSupplier(); 1390 if (supplier != null) { 1391 result = supplier.getNextShape(); 1392 this.shapeList.setShape(series, result); 1393 } 1394 else { 1395 result = this.baseShape; 1396 } 1397 } 1398 return result; 1399 1400 } 1401 1402 /** 1403 * Sets the shape for ALL series (optional) and sends a 1404 * {@link RendererChangeEvent} to all registered listeners. 1405 * 1406 * @param shape the shape (<code>null</code> permitted). 1407 */ 1408 public void setShape(Shape shape) { 1409 setShape(shape, true); 1410 } 1411 1412 /** 1413 * Sets the shape for ALL series and, if requested, sends a 1414 * {@link RendererChangeEvent} to all registered listeners. 1415 * 1416 * @param shape the shape (<code>null</code> permitted). 1417 * @param notify notify listeners? 1418 */ 1419 public void setShape(Shape shape, boolean notify) { 1420 this.shape = shape; 1421 if (notify) { 1422 fireChangeEvent(); 1423 } 1424 } 1425 1426 /** 1427 * Sets the shape used for a series and sends a {@link RendererChangeEvent} 1428 * to all registered listeners. 1429 * 1430 * @param series the series index (zero-based). 1431 * @param shape the shape (<code>null</code> permitted). 1432 */ 1433 public void setSeriesShape(int series, Shape shape) { 1434 setSeriesShape(series, shape, true); 1435 } 1436 1437 /** 1438 * Sets the shape for a series and, if requested, sends a 1439 * {@link RendererChangeEvent} to all registered listeners. 1440 * 1441 * @param series the series index (zero based). 1442 * @param shape the shape (<code>null</code> permitted). 1443 * @param notify notify listeners? 1444 */ 1445 public void setSeriesShape(int series, Shape shape, boolean notify) { 1446 this.shapeList.setShape(series, shape); 1447 if (notify) { 1448 fireChangeEvent(); 1449 } 1450 } 1451 1452 /** 1453 * Returns the base shape. 1454 * 1455 * @return The shape (never <code>null</code>). 1456 */ 1457 public Shape getBaseShape() { 1458 return this.baseShape; 1459 } 1460 1461 /** 1462 * Sets the base shape and sends a {@link RendererChangeEvent} to all 1463 * registered listeners. 1464 * 1465 * @param shape the shape (<code>null</code> not permitted). 1466 */ 1467 public void setBaseShape(Shape shape) { 1468 // defer argument checking... 1469 setBaseShape(shape, true); 1470 } 1471 1472 /** 1473 * Sets the base shape and, if requested, sends a 1474 * {@link RendererChangeEvent} to all registered listeners. 1475 * 1476 * @param shape the shape (<code>null</code> not permitted). 1477 * @param notify notify listeners? 1478 */ 1479 public void setBaseShape(Shape shape, boolean notify) { 1480 if (shape == null) { 1481 throw new IllegalArgumentException("Null 'shape' argument."); 1482 } 1483 this.baseShape = shape; 1484 if (notify) { 1485 fireChangeEvent(); 1486 } 1487 } 1488 1489 // ITEM LABEL VISIBILITY... 1490 1491 /** 1492 * Returns <code>true</code> if an item label is visible, and 1493 * <code>false</code> otherwise. 1494 * 1495 * @param row the row index (zero-based). 1496 * @param column the column index (zero-based). 1497 * 1498 * @return A boolean. 1499 */ 1500 public boolean isItemLabelVisible(int row, int column) { 1501 return isSeriesItemLabelsVisible(row); 1502 } 1503 1504 /** 1505 * Returns <code>true</code> if the item labels for a series are visible, 1506 * and <code>false</code> otherwise. 1507 * 1508 * @param series the series index (zero-based). 1509 * 1510 * @return A boolean. 1511 */ 1512 public boolean isSeriesItemLabelsVisible(int series) { 1513 1514 // return the override, if there is one... 1515 if (this.itemLabelsVisible != null) { 1516 return this.itemLabelsVisible.booleanValue(); 1517 } 1518 1519 // otherwise look up the boolean table 1520 Boolean b = this.itemLabelsVisibleList.getBoolean(series); 1521 if (b == null) { 1522 b = this.baseItemLabelsVisible; 1523 } 1524 if (b == null) { 1525 b = Boolean.FALSE; 1526 } 1527 return b.booleanValue(); 1528 1529 } 1530 1531 /** 1532 * Sets the visibility of the item labels for ALL series. 1533 * 1534 * @param visible the flag. 1535 */ 1536 public void setItemLabelsVisible(boolean visible) { 1537 setItemLabelsVisible(BooleanUtilities.valueOf(visible)); 1538 // The following alternative is only supported in JDK 1.4 - we support 1539 // JDK 1.2.2 1540 // setItemLabelsVisible(Boolean.valueOf(visible)); 1541 } 1542 1543 /** 1544 * Sets the visibility of the item labels for ALL series (optional). 1545 * 1546 * @param visible the flag (<code>null</code> permitted). 1547 */ 1548 public void setItemLabelsVisible(Boolean visible) { 1549 setItemLabelsVisible(visible, true); 1550 } 1551 1552 /** 1553 * Sets the visibility of item labels for ALL series and, if requested, 1554 * sends a {@link RendererChangeEvent} to all registered listeners. 1555 * 1556 * @param visible a flag that controls whether or not the item labels are 1557 * visible (<code>null</code> permitted). 1558 * @param notify a flag that controls whether or not listeners are 1559 * notified. 1560 */ 1561 public void setItemLabelsVisible(Boolean visible, boolean notify) { 1562 this.itemLabelsVisible = visible; 1563 if (notify) { 1564 fireChangeEvent(); 1565 } 1566 } 1567 1568 /** 1569 * Sets a flag that controls the visibility of the item labels for a series. 1570 * 1571 * @param series the series index (zero-based). 1572 * @param visible the flag. 1573 */ 1574 public void setSeriesItemLabelsVisible(int series, boolean visible) { 1575 setSeriesItemLabelsVisible(series, BooleanUtilities.valueOf(visible)); 1576 } 1577 1578 /** 1579 * Sets the visibility of the item labels for a series. 1580 * 1581 * @param series the series index (zero-based). 1582 * @param visible the flag (<code>null</code> permitted). 1583 */ 1584 public void setSeriesItemLabelsVisible(int series, Boolean visible) { 1585 setSeriesItemLabelsVisible(series, visible, true); 1586 } 1587 1588 /** 1589 * Sets the visibility of item labels for a series and, if requested, sends 1590 * a {@link RendererChangeEvent} to all registered listeners. 1591 * 1592 * @param series the series index (zero-based). 1593 * @param visible the visible flag. 1594 * @param notify a flag that controls whether or not listeners are 1595 * notified. 1596 */ 1597 public void setSeriesItemLabelsVisible(int series, Boolean visible, 1598 boolean notify) { 1599 this.itemLabelsVisibleList.setBoolean(series, visible); 1600 if (notify) { 1601 fireChangeEvent(); 1602 } 1603 } 1604 1605 /** 1606 * Returns the base setting for item label visibility. A <code>null</code> 1607 * result should be interpreted as equivalent to <code>Boolean.FALSE</code>. 1608 * 1609 * @return A flag (possibly <code>null</code>). 1610 */ 1611 public Boolean getBaseItemLabelsVisible() { 1612 // this should have been defined as a boolean primitive, because 1613 // allowing null values is a nuisance...but it is part of the final 1614 // API now, so we'll have to support it. 1615 return this.baseItemLabelsVisible; 1616 } 1617 1618 /** 1619 * Sets the base flag that controls whether or not item labels are visible. 1620 * 1621 * @param visible the flag. 1622 */ 1623 public void setBaseItemLabelsVisible(boolean visible) { 1624 setBaseItemLabelsVisible(BooleanUtilities.valueOf(visible)); 1625 } 1626 1627 /** 1628 * Sets the base setting for item label visibility. 1629 * 1630 * @param visible the flag (<code>null</code> is permitted, and viewed 1631 * as equivalent to <code>Boolean.FALSE</code>). 1632 */ 1633 public void setBaseItemLabelsVisible(Boolean visible) { 1634 setBaseItemLabelsVisible(visible, true); 1635 } 1636 1637 /** 1638 * Sets the base visibility for item labels and, if requested, sends a 1639 * {@link RendererChangeEvent} to all registered listeners. 1640 * 1641 * @param visible the flag (<code>null</code> is permitted, and viewed 1642 * as equivalent to <code>Boolean.FALSE</code>). 1643 * @param notify a flag that controls whether or not listeners are 1644 * notified. 1645 */ 1646 public void setBaseItemLabelsVisible(Boolean visible, boolean notify) { 1647 this.baseItemLabelsVisible = visible; 1648 if (notify) { 1649 fireChangeEvent(); 1650 } 1651 } 1652 1653 //// ITEM LABEL FONT ////////////////////////////////////////////////////// 1654 1655 /** 1656 * Returns the font for an item label. 1657 * 1658 * @param row the row index (zero-based). 1659 * @param column the column index (zero-based). 1660 * 1661 * @return The font (never <code>null</code>). 1662 */ 1663 public Font getItemLabelFont(int row, int column) { 1664 Font result = this.itemLabelFont; 1665 if (result == null) { 1666 result = getSeriesItemLabelFont(row); 1667 if (result == null) { 1668 result = this.baseItemLabelFont; 1669 } 1670 } 1671 return result; 1672 } 1673 1674 /** 1675 * Returns the font used for all item labels. This may be 1676 * <code>null</code>, in which case the per series font settings will apply. 1677 * 1678 * @return The font (possibly <code>null</code>). 1679 */ 1680 public Font getItemLabelFont() { 1681 return this.itemLabelFont; 1682 } 1683 1684 /** 1685 * Sets the item label font for ALL series and sends a 1686 * {@link RendererChangeEvent} to all registered listeners. You can set 1687 * this to <code>null</code> if you prefer to set the font on a per series 1688 * basis. 1689 * 1690 * @param font the font (<code>null</code> permitted). 1691 */ 1692 public void setItemLabelFont(Font font) { 1693 setItemLabelFont(font, true); 1694 } 1695 1696 /** 1697 * Sets the item label font for ALL series and, if requested, sends a 1698 * {@link RendererChangeEvent} to all registered listeners. 1699 * 1700 * @param font the font (<code>null</code> permitted). 1701 * @param notify a flag that controls whether or not listeners are 1702 * notified. 1703 */ 1704 public void setItemLabelFont(Font font, boolean notify) { 1705 this.itemLabelFont = font; 1706 if (notify) { 1707 fireChangeEvent(); 1708 } 1709 } 1710 1711 /** 1712 * Returns the font for all the item labels in a series. 1713 * 1714 * @param series the series index (zero-based). 1715 * 1716 * @return The font (possibly <code>null</code>). 1717 */ 1718 public Font getSeriesItemLabelFont(int series) { 1719 return (Font) this.itemLabelFontList.get(series); 1720 } 1721 1722 /** 1723 * Sets the item label font for a series and sends a 1724 * {@link RendererChangeEvent} to all registered listeners. 1725 * 1726 * @param series the series index (zero-based). 1727 * @param font the font (<code>null</code> permitted). 1728 */ 1729 public void setSeriesItemLabelFont(int series, Font font) { 1730 setSeriesItemLabelFont(series, font, true); 1731 } 1732 1733 /** 1734 * Sets the item label font for a series and, if requested, sends a 1735 * {@link RendererChangeEvent} to all registered listeners. 1736 * 1737 * @param series the series index (zero based). 1738 * @param font the font (<code>null</code> permitted). 1739 * @param notify a flag that controls whether or not listeners are 1740 * notified. 1741 */ 1742 public void setSeriesItemLabelFont(int series, Font font, boolean notify) { 1743 this.itemLabelFontList.set(series, font); 1744 if (notify) { 1745 fireChangeEvent(); 1746 } 1747 } 1748 1749 /** 1750 * Returns the base item label font (this is used when no other font 1751 * setting is available). 1752 * 1753 * @return The font (<code>never</code> null). 1754 */ 1755 public Font getBaseItemLabelFont() { 1756 return this.baseItemLabelFont; 1757 } 1758 1759 /** 1760 * Sets the base item label font and sends a {@link RendererChangeEvent} to 1761 * all registered listeners. 1762 * 1763 * @param font the font (<code>null</code> not permitted). 1764 */ 1765 public void setBaseItemLabelFont(Font font) { 1766 if (font == null) { 1767 throw new IllegalArgumentException("Null 'font' argument."); 1768 } 1769 setBaseItemLabelFont(font, true); 1770 } 1771 1772 /** 1773 * Sets the base item label font and, if requested, sends a 1774 * {@link RendererChangeEvent} to all registered listeners. 1775 * 1776 * @param font the font (<code>null</code> not permitted). 1777 * @param notify a flag that controls whether or not listeners are 1778 * notified. 1779 */ 1780 public void setBaseItemLabelFont(Font font, boolean notify) { 1781 this.baseItemLabelFont = font; 1782 if (notify) { 1783 fireChangeEvent(); 1784 } 1785 } 1786 1787 //// ITEM LABEL PAINT //////////////////////////////////////////////////// 1788 1789 /** 1790 * Returns the paint used to draw an item label. 1791 * 1792 * @param row the row index (zero based). 1793 * @param column the column index (zero based). 1794 * 1795 * @return The paint (never <code>null</code>). 1796 */ 1797 public Paint getItemLabelPaint(int row, int column) { 1798 Paint result = this.itemLabelPaint; 1799 if (result == null) { 1800 result = getSeriesItemLabelPaint(row); 1801 if (result == null) { 1802 result = this.baseItemLabelPaint; 1803 } 1804 } 1805 return result; 1806 } 1807 1808 /** 1809 * Returns the paint used for all item labels. This may be 1810 * <code>null</code>, in which case the per series paint settings will 1811 * apply. 1812 * 1813 * @return The paint (possibly <code>null</code>). 1814 */ 1815 public Paint getItemLabelPaint() { 1816 return this.itemLabelPaint; 1817 } 1818 1819 /** 1820 * Sets the item label paint for ALL series and sends a 1821 * {@link RendererChangeEvent} to all registered listeners. 1822 * 1823 * @param paint the paint (<code>null</code> permitted). 1824 */ 1825 public void setItemLabelPaint(Paint paint) { 1826 setItemLabelPaint(paint, true); 1827 } 1828 1829 /** 1830 * Sets the item label paint for ALL series and, if requested, sends a 1831 * {@link RendererChangeEvent} to all registered listeners. 1832 * 1833 * @param paint the paint. 1834 * @param notify a flag that controls whether or not listeners are 1835 * notified. 1836 */ 1837 public void setItemLabelPaint(Paint paint, boolean notify) { 1838 this.itemLabelPaint = paint; 1839 if (notify) { 1840 fireChangeEvent(); 1841 } 1842 } 1843 1844 /** 1845 * Returns the paint used to draw the item labels for a series. 1846 * 1847 * @param series the series index (zero based). 1848 * 1849 * @return The paint (possibly <code>null<code>). 1850 */ 1851 public Paint getSeriesItemLabelPaint(int series) { 1852 return this.itemLabelPaintList.getPaint(series); 1853 } 1854 1855 /** 1856 * Sets the item label paint for a series and sends a 1857 * {@link RendererChangeEvent} to all registered listeners. 1858 * 1859 * @param series the series (zero based index). 1860 * @param paint the paint (<code>null</code> permitted). 1861 */ 1862 public void setSeriesItemLabelPaint(int series, Paint paint) { 1863 setSeriesItemLabelPaint(series, paint, true); 1864 } 1865 1866 /** 1867 * Sets the item label paint for a series and, if requested, sends a 1868 * {@link RendererChangeEvent} to all registered listeners. 1869 * 1870 * @param series the series index (zero based). 1871 * @param paint the paint (<code>null</code> permitted). 1872 * @param notify a flag that controls whether or not listeners are 1873 * notified. 1874 */ 1875 public void setSeriesItemLabelPaint(int series, Paint paint, 1876 boolean notify) { 1877 this.itemLabelPaintList.setPaint(series, paint); 1878 if (notify) { 1879 fireChangeEvent(); 1880 } 1881 } 1882 1883 /** 1884 * Returns the base item label paint. 1885 * 1886 * @return The paint (never <code>null<code>). 1887 */ 1888 public Paint getBaseItemLabelPaint() { 1889 return this.baseItemLabelPaint; 1890 } 1891 1892 /** 1893 * Sets the base item label paint and sends a {@link RendererChangeEvent} 1894 * to all registered listeners. 1895 * 1896 * @param paint the paint (<code>null</code> not permitted). 1897 */ 1898 public void setBaseItemLabelPaint(Paint paint) { 1899 // defer argument checking... 1900 setBaseItemLabelPaint(paint, true); 1901 } 1902 1903 /** 1904 * Sets the base item label paint and, if requested, sends a 1905 * {@link RendererChangeEvent} to all registered listeners.. 1906 * 1907 * @param paint the paint (<code>null</code> not permitted). 1908 * @param notify a flag that controls whether or not listeners are 1909 * notified. 1910 */ 1911 public void setBaseItemLabelPaint(Paint paint, boolean notify) { 1912 if (paint == null) { 1913 throw new IllegalArgumentException("Null 'paint' argument."); 1914 } 1915 this.baseItemLabelPaint = paint; 1916 if (notify) { 1917 fireChangeEvent(); 1918 } 1919 } 1920 1921 // POSITIVE ITEM LABEL POSITION... 1922 1923 /** 1924 * Returns the item label position for positive values. 1925 * 1926 * @param row the row index (zero-based). 1927 * @param column the column index (zero-based). 1928 * 1929 * @return The item label position (never <code>null</code>). 1930 * 1931 * @see #getNegativeItemLabelPosition(int, int) 1932 */ 1933 public ItemLabelPosition getPositiveItemLabelPosition(int row, int column) { 1934 return getSeriesPositiveItemLabelPosition(row); 1935 } 1936 1937 /** 1938 * Returns the item label position for positive values in ALL series. 1939 * 1940 * @return The item label position (possibly <code>null</code>). 1941 * 1942 * @see #setPositiveItemLabelPosition(ItemLabelPosition) 1943 */ 1944 public ItemLabelPosition getPositiveItemLabelPosition() { 1945 return this.positiveItemLabelPosition; 1946 } 1947 1948 /** 1949 * Sets the item label position for positive values in ALL series, and 1950 * sends a {@link RendererChangeEvent} to all registered listeners. You 1951 * need to set this to <code>null</code> to expose the settings for 1952 * individual series. 1953 * 1954 * @param position the position (<code>null</code> permitted). 1955 * 1956 * @see #getPositiveItemLabelPosition() 1957 */ 1958 public void setPositiveItemLabelPosition(ItemLabelPosition position) { 1959 setPositiveItemLabelPosition(position, true); 1960 } 1961 1962 /** 1963 * Sets the positive item label position for ALL series and (if requested) 1964 * sends a {@link RendererChangeEvent} to all registered listeners. 1965 * 1966 * @param position the position (<code>null</code> permitted). 1967 * @param notify notify registered listeners? 1968 * 1969 * @see #getPositiveItemLabelPosition() 1970 */ 1971 public void setPositiveItemLabelPosition(ItemLabelPosition position, 1972 boolean notify) { 1973 this.positiveItemLabelPosition = position; 1974 if (notify) { 1975 fireChangeEvent(); 1976 } 1977 } 1978 1979 /** 1980 * Returns the item label position for all positive values in a series. 1981 * 1982 * @param series the series index (zero-based). 1983 * 1984 * @return The item label position (never <code>null</code>). 1985 * 1986 * @see #setSeriesPositiveItemLabelPosition(int, ItemLabelPosition) 1987 */ 1988 public ItemLabelPosition getSeriesPositiveItemLabelPosition(int series) { 1989 1990 // return the override, if there is one... 1991 if (this.positiveItemLabelPosition != null) { 1992 return this.positiveItemLabelPosition; 1993 } 1994 1995 // otherwise look up the position table 1996 ItemLabelPosition position = (ItemLabelPosition) 1997 this.positiveItemLabelPositionList.get(series); 1998 if (position == null) { 1999 position = this.basePositiveItemLabelPosition; 2000 } 2001 return position; 2002 2003 } 2004 2005 /** 2006 * Sets the item label position for all positive values in a series and 2007 * sends a {@link RendererChangeEvent} to all registered listeners. 2008 * 2009 * @param series the series index (zero-based). 2010 * @param position the position (<code>null</code> permitted). 2011 * 2012 * @see #getSeriesPositiveItemLabelPosition(int) 2013 */ 2014 public void setSeriesPositiveItemLabelPosition(int series, 2015 ItemLabelPosition position) { 2016 setSeriesPositiveItemLabelPosition(series, position, true); 2017 } 2018 2019 /** 2020 * Sets the item label position for all positive values in a series and (if 2021 * requested) sends a {@link RendererChangeEvent} to all registered 2022 * listeners. 2023 * 2024 * @param series the series index (zero-based). 2025 * @param position the position (<code>null</code> permitted). 2026 * @param notify notify registered listeners? 2027 * 2028 * @see #getSeriesPositiveItemLabelPosition(int) 2029 */ 2030 public void setSeriesPositiveItemLabelPosition(int series, 2031 ItemLabelPosition position, 2032 boolean notify) { 2033 this.positiveItemLabelPositionList.set(series, position); 2034 if (notify) { 2035 fireChangeEvent(); 2036 } 2037 } 2038 2039 /** 2040 * Returns the base positive item label position. 2041 * 2042 * @return The position (never <code>null</code>). 2043 * 2044 * @see #setBasePositiveItemLabelPosition(ItemLabelPosition) 2045 */ 2046 public ItemLabelPosition getBasePositiveItemLabelPosition() { 2047 return this.basePositiveItemLabelPosition; 2048 } 2049 2050 /** 2051 * Sets the base positive item label position. 2052 * 2053 * @param position the position (<code>null</code> not permitted). 2054 * 2055 * @see #getBasePositiveItemLabelPosition() 2056 */ 2057 public void setBasePositiveItemLabelPosition(ItemLabelPosition position) { 2058 // defer argument checking... 2059 setBasePositiveItemLabelPosition(position, true); 2060 } 2061 2062 /** 2063 * Sets the base positive item label position and, if requested, sends a 2064 * {@link RendererChangeEvent} to all registered listeners. 2065 * 2066 * @param position the position (<code>null</code> not permitted). 2067 * @param notify notify registered listeners? 2068 * 2069 * @see #getBasePositiveItemLabelPosition() 2070 */ 2071 public void setBasePositiveItemLabelPosition(ItemLabelPosition position, 2072 boolean notify) { 2073 if (position == null) { 2074 throw new IllegalArgumentException("Null 'position' argument."); 2075 } 2076 this.basePositiveItemLabelPosition = position; 2077 if (notify) { 2078 fireChangeEvent(); 2079 } 2080 } 2081 2082 // NEGATIVE ITEM LABEL POSITION... 2083 2084 /** 2085 * Returns the item label position for negative values. This method can be 2086 * overridden to provide customisation of the item label position for 2087 * individual data items. 2088 * 2089 * @param row the row index (zero-based). 2090 * @param column the column (zero-based). 2091 * 2092 * @return The item label position (never <code>null</code>). 2093 * 2094 * @see #getPositiveItemLabelPosition(int, int) 2095 */ 2096 public ItemLabelPosition getNegativeItemLabelPosition(int row, int column) { 2097 return getSeriesNegativeItemLabelPosition(row); 2098 } 2099 2100 /** 2101 * Returns the item label position for negative values in ALL series. 2102 * 2103 * @return The item label position (possibly <code>null</code>). 2104 * 2105 * @see #setNegativeItemLabelPosition(ItemLabelPosition) 2106 */ 2107 public ItemLabelPosition getNegativeItemLabelPosition() { 2108 return this.negativeItemLabelPosition; 2109 } 2110 2111 /** 2112 * Sets the item label position for negative values in ALL series, and 2113 * sends a {@link RendererChangeEvent} to all registered listeners. You 2114 * need to set this to <code>null</code> to expose the settings for 2115 * individual series. 2116 * 2117 * @param position the position (<code>null</code> permitted). 2118 * 2119 * @see #getNegativeItemLabelPosition() 2120 */ 2121 public void setNegativeItemLabelPosition(ItemLabelPosition position) { 2122 setNegativeItemLabelPosition(position, true); 2123 } 2124 2125 /** 2126 * Sets the item label position for negative values in ALL series and (if 2127 * requested) sends a {@link RendererChangeEvent} to all registered 2128 * listeners. 2129 * 2130 * @param position the position (<code>null</code> permitted). 2131 * @param notify notify registered listeners? 2132 * 2133 * @see #getNegativeItemLabelPosition() 2134 */ 2135 public void setNegativeItemLabelPosition(ItemLabelPosition position, 2136 boolean notify) { 2137 this.negativeItemLabelPosition = position; 2138 if (notify) { 2139 fireChangeEvent(); 2140 } 2141 } 2142 2143 /** 2144 * Returns the item label position for all negative values in a series. 2145 * 2146 * @param series the series index (zero-based). 2147 * 2148 * @return The item label position (never <code>null</code>). 2149 * 2150 * @see #setSeriesNegativeItemLabelPosition(int, ItemLabelPosition) 2151 */ 2152 public ItemLabelPosition getSeriesNegativeItemLabelPosition(int series) { 2153 2154 // return the override, if there is one... 2155 if (this.negativeItemLabelPosition != null) { 2156 return this.negativeItemLabelPosition; 2157 } 2158 2159 // otherwise look up the position list 2160 ItemLabelPosition position = (ItemLabelPosition) 2161 this.negativeItemLabelPositionList.get(series); 2162 if (position == null) { 2163 position = this.baseNegativeItemLabelPosition; 2164 } 2165 return position; 2166 2167 } 2168 2169 /** 2170 * Sets the item label position for negative values in a series and sends a 2171 * {@link RendererChangeEvent} to all registered listeners. 2172 * 2173 * @param series the series index (zero-based). 2174 * @param position the position (<code>null</code> permitted). 2175 * 2176 * @see #getSeriesNegativeItemLabelPosition(int) 2177 */ 2178 public void setSeriesNegativeItemLabelPosition(int series, 2179 ItemLabelPosition position) { 2180 setSeriesNegativeItemLabelPosition(series, position, true); 2181 } 2182 2183 /** 2184 * Sets the item label position for negative values in a series and (if 2185 * requested) sends a {@link RendererChangeEvent} to all registered 2186 * listeners. 2187 * 2188 * @param series the series index (zero-based). 2189 * @param position the position (<code>null</code> permitted). 2190 * @param notify notify registered listeners? 2191 * 2192 * @see #getSeriesNegativeItemLabelPosition(int) 2193 */ 2194 public void setSeriesNegativeItemLabelPosition(int series, 2195 ItemLabelPosition position, 2196 boolean notify) { 2197 this.negativeItemLabelPositionList.set(series, position); 2198 if (notify) { 2199 fireChangeEvent(); 2200 } 2201 } 2202 2203 /** 2204 * Returns the base item label position for negative values. 2205 * 2206 * @return The position (never <code>null</code>). 2207 * 2208 * @see #setBaseNegativeItemLabelPosition(ItemLabelPosition) 2209 */ 2210 public ItemLabelPosition getBaseNegativeItemLabelPosition() { 2211 return this.baseNegativeItemLabelPosition; 2212 } 2213 2214 /** 2215 * Sets the base item label position for negative values and sends a 2216 * {@link RendererChangeEvent} to all registered listeners. 2217 * 2218 * @param position the position (<code>null</code> not permitted). 2219 * 2220 * @see #getBaseNegativeItemLabelPosition() 2221 */ 2222 public void setBaseNegativeItemLabelPosition(ItemLabelPosition position) { 2223 setBaseNegativeItemLabelPosition(position, true); 2224 } 2225 2226 /** 2227 * Sets the base negative item label position and, if requested, sends a 2228 * {@link RendererChangeEvent} to all registered listeners. 2229 * 2230 * @param position the position (<code>null</code> not permitted). 2231 * @param notify notify registered listeners? 2232 * 2233 * @see #getBaseNegativeItemLabelPosition() 2234 */ 2235 public void setBaseNegativeItemLabelPosition(ItemLabelPosition position, 2236 boolean notify) { 2237 if (position == null) { 2238 throw new IllegalArgumentException("Null 'position' argument."); 2239 } 2240 this.baseNegativeItemLabelPosition = position; 2241 if (notify) { 2242 fireChangeEvent(); 2243 } 2244 } 2245 2246 /** 2247 * Returns the item label anchor offset. 2248 * 2249 * @return The offset. 2250 * 2251 * @see #setItemLabelAnchorOffset(double) 2252 */ 2253 public double getItemLabelAnchorOffset() { 2254 return this.itemLabelAnchorOffset; 2255 } 2256 2257 /** 2258 * Sets the item label anchor offset. 2259 * 2260 * @param offset the offset. 2261 * 2262 * @see #getItemLabelAnchorOffset() 2263 */ 2264 public void setItemLabelAnchorOffset(double offset) { 2265 this.itemLabelAnchorOffset = offset; 2266 fireChangeEvent(); 2267 } 2268 2269 /** 2270 * Returns a boolean that indicates whether or not the specified item 2271 * should have a chart entity created for it. 2272 * 2273 * @param series the series index. 2274 * @param item the item index. 2275 * 2276 * @return A boolean. 2277 */ 2278 public boolean getItemCreateEntity(int series, int item) { 2279 if (this.createEntities != null) { 2280 return this.createEntities.booleanValue(); 2281 } 2282 else { 2283 Boolean b = getSeriesCreateEntities(series); 2284 if (b != null) { 2285 return b.booleanValue(); 2286 } 2287 else { 2288 return this.baseCreateEntities; 2289 } 2290 } 2291 } 2292 2293 /** 2294 * Returns the flag that controls whether or not chart entities are created 2295 * for the items in ALL series. This flag overrides the per series and 2296 * default settings - you must set it to <code>null</code> if you want the 2297 * other settings to apply. 2298 * 2299 * @return The flag (possibly <code>null</code>). 2300 */ 2301 public Boolean getCreateEntities() { 2302 return this.createEntities; 2303 } 2304 2305 /** 2306 * Sets the flag that controls whether or not chart entities are created 2307 * for the items in ALL series, and sends a {@link RendererChangeEvent} to 2308 * all registered listeners. This flag overrides the per series and 2309 * default settings - you must set it to <code>null</code> if you want the 2310 * other settings to apply. 2311 * 2312 * @param create the flag (<code>null</code> permitted). 2313 */ 2314 public void setCreateEntities(Boolean create) { 2315 setCreateEntities(create, true); 2316 } 2317 2318 /** 2319 * Sets the flag that controls whether or not chart entities are created 2320 * for the items in ALL series, and sends a {@link RendererChangeEvent} to 2321 * all registered listeners. This flag overrides the per series and 2322 * default settings - you must set it to <code>null</code> if you want the 2323 * other settings to apply. 2324 * 2325 * @param create the flag (<code>null</code> permitted). 2326 * @param notify notify listeners? 2327 */ 2328 public void setCreateEntities(Boolean create, boolean notify) { 2329 this.createEntities = create; 2330 if (notify) { 2331 fireChangeEvent(); 2332 } 2333 } 2334 2335 /** 2336 * Returns the flag that controls whether entities are created for a 2337 * series. 2338 * 2339 * @param series the series index (zero-based). 2340 * 2341 * @return The flag (possibly <code>null</code>). 2342 */ 2343 public Boolean getSeriesCreateEntities(int series) { 2344 return this.createEntitiesList.getBoolean(series); 2345 } 2346 2347 /** 2348 * Sets the flag that controls whether entities are created for a series, 2349 * and sends a {@link RendererChangeEvent} to all registered listeners. 2350 * 2351 * @param series the series index (zero-based). 2352 * @param create the flag (<code>null</code> permitted). 2353 */ 2354 public void setSeriesCreateEntities(int series, Boolean create) { 2355 setSeriesCreateEntities(series, create, true); 2356 } 2357 2358 /** 2359 * Sets the flag that controls whether entities are created for a series 2360 * and, if requested, sends a {@link RendererChangeEvent} to all registered 2361 * listeners. 2362 * 2363 * @param series the series index. 2364 * @param create the flag (<code>null</code> permitted). 2365 * @param notify notify listeners? 2366 */ 2367 public void setSeriesCreateEntities(int series, Boolean create, 2368 boolean notify) { 2369 this.createEntitiesList.setBoolean(series, create); 2370 if (notify) { 2371 fireChangeEvent(); 2372 } 2373 } 2374 2375 /** 2376 * Returns the base visibility for all series. 2377 * 2378 * @return The base visibility. 2379 */ 2380 public boolean getBaseCreateEntities() { 2381 return this.baseCreateEntities; 2382 } 2383 2384 /** 2385 * Sets the base flag that controls whether entities are created 2386 * for a series, and sends a {@link RendererChangeEvent} 2387 * to all registered listeners. 2388 * 2389 * @param create the flag. 2390 */ 2391 public void setBaseCreateEntities(boolean create) { 2392 // defer argument checking... 2393 setBaseCreateEntities(create, true); 2394 } 2395 2396 /** 2397 * Sets the base flag that controls whether entities are created and, 2398 * if requested, sends a {@link RendererChangeEvent} to all registered 2399 * listeners. 2400 * 2401 * @param create the visibility. 2402 * @param notify notify listeners? 2403 */ 2404 public void setBaseCreateEntities(boolean create, boolean notify) { 2405 this.baseCreateEntities = create; 2406 if (notify) { 2407 fireChangeEvent(); 2408 } 2409 } 2410 2411 /** The adjacent offset. */ 2412 private static final double ADJ = Math.cos(Math.PI / 6.0); 2413 2414 /** The opposite offset. */ 2415 private static final double OPP = Math.sin(Math.PI / 6.0); 2416 2417 /** 2418 * Calculates the item label anchor point. 2419 * 2420 * @param anchor the anchor. 2421 * @param x the x coordinate. 2422 * @param y the y coordinate. 2423 * @param orientation the plot orientation. 2424 * 2425 * @return The anchor point (never <code>null</code>). 2426 */ 2427 protected Point2D calculateLabelAnchorPoint(ItemLabelAnchor anchor, 2428 double x, double y, PlotOrientation orientation) { 2429 Point2D result = null; 2430 if (anchor == ItemLabelAnchor.CENTER) { 2431 result = new Point2D.Double(x, y); 2432 } 2433 else if (anchor == ItemLabelAnchor.INSIDE1) { 2434 result = new Point2D.Double(x + OPP * this.itemLabelAnchorOffset, 2435 y - ADJ * this.itemLabelAnchorOffset); 2436 } 2437 else if (anchor == ItemLabelAnchor.INSIDE2) { 2438 result = new Point2D.Double(x + ADJ * this.itemLabelAnchorOffset, 2439 y - OPP * this.itemLabelAnchorOffset); 2440 } 2441 else if (anchor == ItemLabelAnchor.INSIDE3) { 2442 result = new Point2D.Double(x + this.itemLabelAnchorOffset, y); 2443 } 2444 else if (anchor == ItemLabelAnchor.INSIDE4) { 2445 result = new Point2D.Double(x + ADJ * this.itemLabelAnchorOffset, 2446 y + OPP * this.itemLabelAnchorOffset); 2447 } 2448 else if (anchor == ItemLabelAnchor.INSIDE5) { 2449 result = new Point2D.Double(x + OPP * this.itemLabelAnchorOffset, 2450 y + ADJ * this.itemLabelAnchorOffset); 2451 } 2452 else if (anchor == ItemLabelAnchor.INSIDE6) { 2453 result = new Point2D.Double(x, y + this.itemLabelAnchorOffset); 2454 } 2455 else if (anchor == ItemLabelAnchor.INSIDE7) { 2456 result = new Point2D.Double(x - OPP * this.itemLabelAnchorOffset, 2457 y + ADJ * this.itemLabelAnchorOffset); 2458 } 2459 else if (anchor == ItemLabelAnchor.INSIDE8) { 2460 result = new Point2D.Double(x - ADJ * this.itemLabelAnchorOffset, 2461 y + OPP * this.itemLabelAnchorOffset); 2462 } 2463 else if (anchor == ItemLabelAnchor.INSIDE9) { 2464 result = new Point2D.Double(x - this.itemLabelAnchorOffset, y); 2465 } 2466 else if (anchor == ItemLabelAnchor.INSIDE10) { 2467 result = new Point2D.Double(x - ADJ * this.itemLabelAnchorOffset, 2468 y - OPP * this.itemLabelAnchorOffset); 2469 } 2470 else if (anchor == ItemLabelAnchor.INSIDE11) { 2471 result = new Point2D.Double(x - OPP * this.itemLabelAnchorOffset, 2472 y - ADJ * this.itemLabelAnchorOffset); 2473 } 2474 else if (anchor == ItemLabelAnchor.INSIDE12) { 2475 result = new Point2D.Double(x, y - this.itemLabelAnchorOffset); 2476 } 2477 else if (anchor == ItemLabelAnchor.OUTSIDE1) { 2478 result = new Point2D.Double( 2479 x + 2.0 * OPP * this.itemLabelAnchorOffset, 2480 y - 2.0 * ADJ * this.itemLabelAnchorOffset); 2481 } 2482 else if (anchor == ItemLabelAnchor.OUTSIDE2) { 2483 result = new Point2D.Double( 2484 x + 2.0 * ADJ * this.itemLabelAnchorOffset, 2485 y - 2.0 * OPP * this.itemLabelAnchorOffset); 2486 } 2487 else if (anchor == ItemLabelAnchor.OUTSIDE3) { 2488 result = new Point2D.Double(x + 2.0 * this.itemLabelAnchorOffset, 2489 y); 2490 } 2491 else if (anchor == ItemLabelAnchor.OUTSIDE4) { 2492 result = new Point2D.Double( 2493 x + 2.0 * ADJ * this.itemLabelAnchorOffset, 2494 y + 2.0 * OPP * this.itemLabelAnchorOffset); 2495 } 2496 else if (anchor == ItemLabelAnchor.OUTSIDE5) { 2497 result = new Point2D.Double( 2498 x + 2.0 * OPP * this.itemLabelAnchorOffset, 2499 y + 2.0 * ADJ * this.itemLabelAnchorOffset); 2500 } 2501 else if (anchor == ItemLabelAnchor.OUTSIDE6) { 2502 result = new Point2D.Double(x, 2503 y + 2.0 * this.itemLabelAnchorOffset); 2504 } 2505 else if (anchor == ItemLabelAnchor.OUTSIDE7) { 2506 result = new Point2D.Double( 2507 x - 2.0 * OPP * this.itemLabelAnchorOffset, 2508 y + 2.0 * ADJ * this.itemLabelAnchorOffset); 2509 } 2510 else if (anchor == ItemLabelAnchor.OUTSIDE8) { 2511 result = new Point2D.Double( 2512 x - 2.0 * ADJ * this.itemLabelAnchorOffset, 2513 y + 2.0 * OPP * this.itemLabelAnchorOffset); 2514 } 2515 else if (anchor == ItemLabelAnchor.OUTSIDE9) { 2516 result = new Point2D.Double(x - 2.0 * this.itemLabelAnchorOffset, 2517 y); 2518 } 2519 else if (anchor == ItemLabelAnchor.OUTSIDE10) { 2520 result = new Point2D.Double( 2521 x - 2.0 * ADJ * this.itemLabelAnchorOffset, 2522 y - 2.0 * OPP * this.itemLabelAnchorOffset); 2523 } 2524 else if (anchor == ItemLabelAnchor.OUTSIDE11) { 2525 result = new Point2D.Double( 2526 x - 2.0 * OPP * this.itemLabelAnchorOffset, 2527 y - 2.0 * ADJ * this.itemLabelAnchorOffset); 2528 } 2529 else if (anchor == ItemLabelAnchor.OUTSIDE12) { 2530 result = new Point2D.Double(x, 2531 y - 2.0 * this.itemLabelAnchorOffset); 2532 } 2533 return result; 2534 } 2535 2536 /** 2537 * Registers an object to receive notification of changes to the renderer. 2538 * 2539 * @param listener the listener (<code>null</code> not permitted). 2540 */ 2541 public void addChangeListener(RendererChangeListener listener) { 2542 if (listener == null) { 2543 throw new IllegalArgumentException("Null 'listener' argument."); 2544 } 2545 this.listenerList.add(RendererChangeListener.class, listener); 2546 } 2547 2548 /** 2549 * Deregisters an object so that it no longer receives 2550 * notification of changes to the renderer. 2551 * 2552 * @param listener the object (<code>null</code> not permitted). 2553 */ 2554 public void removeChangeListener(RendererChangeListener listener) { 2555 if (listener == null) { 2556 throw new IllegalArgumentException("Null 'listener' argument."); 2557 } 2558 this.listenerList.remove(RendererChangeListener.class, listener); 2559 } 2560 2561 /** 2562 * Returns <code>true</code> if the specified object is registered with 2563 * the dataset as a listener. Most applications won't need to call this 2564 * method, it exists mainly for use by unit testing code. 2565 * 2566 * @param listener the listener. 2567 * 2568 * @return A boolean. 2569 */ 2570 public boolean hasListener(EventListener listener) { 2571 List list = Arrays.asList(this.listenerList.getListenerList()); 2572 return list.contains(listener); 2573 } 2574 2575 /** 2576 * Sends a {@link RendererChangeEvent} to all registered listeners. 2577 * 2578 * @since 1.0.5 2579 */ 2580 protected void fireChangeEvent() { 2581 2582 // the commented out code would be better, but only if 2583 // RendererChangeEvent is immutable, which it isn't. See if there is 2584 // a way to fix this... 2585 2586 //if (this.event == null) { 2587 // this.event = new RendererChangeEvent(this); 2588 //} 2589 //notifyListeners(this.event); 2590 2591 notifyListeners(new RendererChangeEvent(this)); 2592 } 2593 2594 /** 2595 * Notifies all registered listeners that the renderer has been modified. 2596 * 2597 * @param event information about the change event. 2598 */ 2599 public void notifyListeners(RendererChangeEvent event) { 2600 Object[] ls = this.listenerList.getListenerList(); 2601 for (int i = ls.length - 2; i >= 0; i -= 2) { 2602 if (ls[i] == RendererChangeListener.class) { 2603 ((RendererChangeListener) ls[i + 1]).rendererChanged(event); 2604 } 2605 } 2606 } 2607 2608 /** 2609 * Tests this renderer for equality with another object. 2610 * 2611 * @param obj the object (<code>null</code> permitted). 2612 * 2613 * @return <code>true</code> or <code>false</code>. 2614 */ 2615 public boolean equals(Object obj) { 2616 if (obj == this) { 2617 return true; 2618 } 2619 if (!(obj instanceof AbstractRenderer)) { 2620 return false; 2621 } 2622 AbstractRenderer that = (AbstractRenderer) obj; 2623 if (!ObjectUtilities.equal(this.seriesVisible, that.seriesVisible)) { 2624 return false; 2625 } 2626 if (!this.seriesVisibleList.equals(that.seriesVisibleList)) { 2627 return false; 2628 } 2629 if (this.baseSeriesVisible != that.baseSeriesVisible) { 2630 return false; 2631 } 2632 if (!ObjectUtilities.equal(this.seriesVisibleInLegend, 2633 that.seriesVisibleInLegend)) { 2634 return false; 2635 } 2636 if (!this.seriesVisibleInLegendList.equals( 2637 that.seriesVisibleInLegendList)) { 2638 return false; 2639 } 2640 if (this.baseSeriesVisibleInLegend != that.baseSeriesVisibleInLegend) { 2641 return false; 2642 } 2643 if (!PaintUtilities.equal(this.paint, that.paint)) { 2644 return false; 2645 } 2646 if (!ObjectUtilities.equal(this.paintList, that.paintList)) { 2647 return false; 2648 } 2649 if (!PaintUtilities.equal(this.basePaint, that.basePaint)) { 2650 return false; 2651 } 2652 if (!PaintUtilities.equal(this.fillPaint, that.fillPaint)) { 2653 return false; 2654 } 2655 if (!ObjectUtilities.equal(this.fillPaintList, that.fillPaintList)) { 2656 return false; 2657 } 2658 if (!PaintUtilities.equal(this.baseFillPaint, that.baseFillPaint)) { 2659 return false; 2660 } 2661 if (!PaintUtilities.equal(this.outlinePaint, that.outlinePaint)) { 2662 return false; 2663 } 2664 if (!ObjectUtilities.equal(this.outlinePaintList, 2665 that.outlinePaintList)) { 2666 return false; 2667 } 2668 if (!PaintUtilities.equal(this.baseOutlinePaint, 2669 that.baseOutlinePaint)) { 2670 return false; 2671 } 2672 if (!ObjectUtilities.equal(this.stroke, that.stroke)) { 2673 return false; 2674 } 2675 if (!ObjectUtilities.equal(this.strokeList, that.strokeList)) { 2676 return false; 2677 } 2678 if (!ObjectUtilities.equal(this.baseStroke, that.baseStroke)) { 2679 return false; 2680 } 2681 if (!ObjectUtilities.equal(this.outlineStroke, that.outlineStroke)) { 2682 return false; 2683 } 2684 if (!ObjectUtilities.equal(this.outlineStrokeList, 2685 that.outlineStrokeList)) { 2686 return false; 2687 } 2688 if (!ObjectUtilities.equal( 2689 this.baseOutlineStroke, that.baseOutlineStroke) 2690 ) { 2691 return false; 2692 } 2693 if (!ObjectUtilities.equal(this.shape, that.shape)) { 2694 return false; 2695 } 2696 if (!ObjectUtilities.equal(this.shapeList, that.shapeList)) { 2697 return false; 2698 } 2699 if (!ObjectUtilities.equal(this.baseShape, that.baseShape)) { 2700 return false; 2701 } 2702 if (!ObjectUtilities.equal(this.itemLabelsVisible, 2703 that.itemLabelsVisible)) { 2704 return false; 2705 } 2706 if (!ObjectUtilities.equal(this.itemLabelsVisibleList, 2707 that.itemLabelsVisibleList)) { 2708 return false; 2709 } 2710 if (!ObjectUtilities.equal(this.baseItemLabelsVisible, 2711 that.baseItemLabelsVisible)) { 2712 return false; 2713 } 2714 if (!ObjectUtilities.equal(this.itemLabelFont, that.itemLabelFont)) { 2715 return false; 2716 } 2717 if (!ObjectUtilities.equal(this.itemLabelFontList, 2718 that.itemLabelFontList)) { 2719 return false; 2720 } 2721 if (!ObjectUtilities.equal(this.baseItemLabelFont, 2722 that.baseItemLabelFont)) { 2723 return false; 2724 } 2725 2726 if (!PaintUtilities.equal(this.itemLabelPaint, that.itemLabelPaint)) { 2727 return false; 2728 } 2729 if (!ObjectUtilities.equal(this.itemLabelPaintList, 2730 that.itemLabelPaintList)) { 2731 return false; 2732 } 2733 if (!PaintUtilities.equal(this.baseItemLabelPaint, 2734 that.baseItemLabelPaint)) { 2735 return false; 2736 } 2737 2738 if (!ObjectUtilities.equal(this.positiveItemLabelPosition, 2739 that.positiveItemLabelPosition)) { 2740 return false; 2741 } 2742 if (!ObjectUtilities.equal(this.positiveItemLabelPositionList, 2743 that.positiveItemLabelPositionList)) { 2744 return false; 2745 } 2746 if (!ObjectUtilities.equal(this.basePositiveItemLabelPosition, 2747 that.basePositiveItemLabelPosition)) { 2748 return false; 2749 } 2750 2751 if (!ObjectUtilities.equal(this.negativeItemLabelPosition, 2752 that.negativeItemLabelPosition)) { 2753 return false; 2754 } 2755 if (!ObjectUtilities.equal(this.negativeItemLabelPositionList, 2756 that.negativeItemLabelPositionList)) { 2757 return false; 2758 } 2759 if (!ObjectUtilities.equal(this.baseNegativeItemLabelPosition, 2760 that.baseNegativeItemLabelPosition)) { 2761 return false; 2762 } 2763 if (this.itemLabelAnchorOffset != that.itemLabelAnchorOffset) { 2764 return false; 2765 } 2766 if (!ObjectUtilities.equal(this.createEntities, that.createEntities)) { 2767 return false; 2768 } 2769 if (!ObjectUtilities.equal(this.createEntitiesList, 2770 that.createEntitiesList)) { 2771 return false; 2772 } 2773 if (this.baseCreateEntities != that.baseCreateEntities) { 2774 return false; 2775 } 2776 return true; 2777 } 2778 2779 /** 2780 * Returns a hashcode for the renderer. 2781 * 2782 * @return The hashcode. 2783 */ 2784 public int hashCode() { 2785 int result = 193; 2786 result = 37 * result + ObjectUtilities.hashCode(this.stroke); 2787 result = 37 * result + ObjectUtilities.hashCode(this.baseStroke); 2788 result = 37 * result + ObjectUtilities.hashCode(this.outlineStroke); 2789 result = 37 * result + ObjectUtilities.hashCode(this.baseOutlineStroke); 2790 return result; 2791 } 2792 2793 /** 2794 * Returns an independent copy of the renderer. 2795 * 2796 * @return A clone. 2797 * 2798 * @throws CloneNotSupportedException if some component of the renderer 2799 * does not support cloning. 2800 */ 2801 protected Object clone() throws CloneNotSupportedException { 2802 AbstractRenderer clone = (AbstractRenderer) super.clone(); 2803 2804 if (this.seriesVisibleList != null) { 2805 clone.seriesVisibleList 2806 = (BooleanList) this.seriesVisibleList.clone(); 2807 } 2808 2809 if (this.seriesVisibleInLegendList != null) { 2810 clone.seriesVisibleInLegendList 2811 = (BooleanList) this.seriesVisibleInLegendList.clone(); 2812 } 2813 2814 // 'paint' : immutable, no need to clone reference 2815 if (this.paintList != null) { 2816 clone.paintList = (PaintList) this.paintList.clone(); 2817 } 2818 // 'basePaint' : immutable, no need to clone reference 2819 2820 if (this.fillPaintList != null) { 2821 clone.fillPaintList = (PaintList) this.fillPaintList.clone(); 2822 } 2823 // 'outlinePaint' : immutable, no need to clone reference 2824 if (this.outlinePaintList != null) { 2825 clone.outlinePaintList = (PaintList) this.outlinePaintList.clone(); 2826 } 2827 // 'baseOutlinePaint' : immutable, no need to clone reference 2828 2829 // 'stroke' : immutable, no need to clone reference 2830 if (this.strokeList != null) { 2831 clone.strokeList = (StrokeList) this.strokeList.clone(); 2832 } 2833 // 'baseStroke' : immutable, no need to clone reference 2834 2835 // 'outlineStroke' : immutable, no need to clone reference 2836 if (this.outlineStrokeList != null) { 2837 clone.outlineStrokeList 2838 = (StrokeList) this.outlineStrokeList.clone(); 2839 } 2840 // 'baseOutlineStroke' : immutable, no need to clone reference 2841 2842 if (this.shape != null) { 2843 clone.shape = ShapeUtilities.clone(this.shape); 2844 } 2845 if (this.shapeList != null) { 2846 clone.shapeList = (ShapeList) this.shapeList.clone(); 2847 } 2848 if (this.baseShape != null) { 2849 clone.baseShape = ShapeUtilities.clone(this.baseShape); 2850 } 2851 2852 // 'itemLabelsVisible' : immutable, no need to clone reference 2853 if (this.itemLabelsVisibleList != null) { 2854 clone.itemLabelsVisibleList 2855 = (BooleanList) this.itemLabelsVisibleList.clone(); 2856 } 2857 // 'basePaint' : immutable, no need to clone reference 2858 2859 // 'itemLabelFont' : immutable, no need to clone reference 2860 if (this.itemLabelFontList != null) { 2861 clone.itemLabelFontList 2862 = (ObjectList) this.itemLabelFontList.clone(); 2863 } 2864 // 'baseItemLabelFont' : immutable, no need to clone reference 2865 2866 // 'itemLabelPaint' : immutable, no need to clone reference 2867 if (this.itemLabelPaintList != null) { 2868 clone.itemLabelPaintList 2869 = (PaintList) this.itemLabelPaintList.clone(); 2870 } 2871 // 'baseItemLabelPaint' : immutable, no need to clone reference 2872 2873 // 'postiveItemLabelAnchor' : immutable, no need to clone reference 2874 if (this.positiveItemLabelPositionList != null) { 2875 clone.positiveItemLabelPositionList 2876 = (ObjectList) this.positiveItemLabelPositionList.clone(); 2877 } 2878 // 'baseItemLabelAnchor' : immutable, no need to clone reference 2879 2880 // 'negativeItemLabelAnchor' : immutable, no need to clone reference 2881 if (this.negativeItemLabelPositionList != null) { 2882 clone.negativeItemLabelPositionList 2883 = (ObjectList) this.negativeItemLabelPositionList.clone(); 2884 } 2885 // 'baseNegativeItemLabelAnchor' : immutable, no need to clone reference 2886 2887 if (this.createEntitiesList != null) { 2888 clone.createEntitiesList 2889 = (BooleanList) this.createEntitiesList.clone(); 2890 } 2891 clone.listenerList = new EventListenerList(); 2892 clone.event = null; 2893 return clone; 2894 } 2895 2896 /** 2897 * Provides serialization support. 2898 * 2899 * @param stream the output stream. 2900 * 2901 * @throws IOException if there is an I/O error. 2902 */ 2903 private void writeObject(ObjectOutputStream stream) throws IOException { 2904 2905 stream.defaultWriteObject(); 2906 SerialUtilities.writePaint(this.paint, stream); 2907 SerialUtilities.writePaint(this.basePaint, stream); 2908 SerialUtilities.writePaint(this.fillPaint, stream); 2909 SerialUtilities.writePaint(this.baseFillPaint, stream); 2910 SerialUtilities.writePaint(this.outlinePaint, stream); 2911 SerialUtilities.writePaint(this.baseOutlinePaint, stream); 2912 SerialUtilities.writeStroke(this.stroke, stream); 2913 SerialUtilities.writeStroke(this.baseStroke, stream); 2914 SerialUtilities.writeStroke(this.outlineStroke, stream); 2915 SerialUtilities.writeStroke(this.baseOutlineStroke, stream); 2916 SerialUtilities.writeShape(this.shape, stream); 2917 SerialUtilities.writeShape(this.baseShape, stream); 2918 SerialUtilities.writePaint(this.itemLabelPaint, stream); 2919 SerialUtilities.writePaint(this.baseItemLabelPaint, stream); 2920 2921 } 2922 2923 /** 2924 * Provides serialization support. 2925 * 2926 * @param stream the input stream. 2927 * 2928 * @throws IOException if there is an I/O error. 2929 * @throws ClassNotFoundException if there is a classpath problem. 2930 */ 2931 private void readObject(ObjectInputStream stream) 2932 throws IOException, ClassNotFoundException { 2933 2934 stream.defaultReadObject(); 2935 this.paint = SerialUtilities.readPaint(stream); 2936 this.basePaint = SerialUtilities.readPaint(stream); 2937 this.fillPaint = SerialUtilities.readPaint(stream); 2938 this.baseFillPaint = SerialUtilities.readPaint(stream); 2939 this.outlinePaint = SerialUtilities.readPaint(stream); 2940 this.baseOutlinePaint = SerialUtilities.readPaint(stream); 2941 this.stroke = SerialUtilities.readStroke(stream); 2942 this.baseStroke = SerialUtilities.readStroke(stream); 2943 this.outlineStroke = SerialUtilities.readStroke(stream); 2944 this.baseOutlineStroke = SerialUtilities.readStroke(stream); 2945 this.shape = SerialUtilities.readShape(stream); 2946 this.baseShape = SerialUtilities.readShape(stream); 2947 this.itemLabelPaint = SerialUtilities.readPaint(stream); 2948 this.baseItemLabelPaint = SerialUtilities.readPaint(stream); 2949 2950 // listeners are not restored automatically, but storage must be 2951 // provided... 2952 this.listenerList = new EventListenerList(); 2953 2954 } 2955 2956 }