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