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