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