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