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