1 /* ===========================================================
2  * JFreeChart : a free chart library for the Java(tm) platform
3  * ===========================================================
4  *
5  * (C) Copyright 2000-2013, by Object Refinery Limited and Contributors.
6  *
7  * Project Info:  http://www.jfree.org/jfreechart/index.html
8  *
9  * This library is free software; you can redistribute it and/or modify it
10  * under the terms of the GNU Lesser General Public License as published by
11  * the Free Software Foundation; either version 2.1 of the License, or
12  * (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17  * License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
22  * USA.
23  *
24  * [Oracle and Java are registered trademarks of Oracle and/or its affiliates.
25  * Other names may be trademarks of their respective owners.]
26  *
27  * -----------------------
28  * StandardChartTheme.java
29  * -----------------------
30  * (C) Copyright 2008-2013, by Object Refinery Limited.
31  *
32  * Original Author:  David Gilbert (for Object Refinery Limited);
33  * Contributor(s):   -;
34  *
35  * Changes
36  * -------
37  * 14-Aug-2008 : Version 1 (DG);
38  * 10-Apr-2009 : Added getter/setter for smallFont (DG);
39  * 10-Jul-2009 : Added shadowGenerator field (DG);
40  * 29-Oct-2011 : Fixed Eclipse warnings (DG);
41  * 02-Jul-2013 : Use ParamChecks class (DG);
42  *
43  */
44 
45 package org.jfree.chart;
46 
47 import java.awt.BasicStroke;
48 import java.awt.Color;
49 import java.awt.Font;
50 import java.awt.Paint;
51 import java.awt.Stroke;
52 import java.io.IOException;
53 import java.io.ObjectInputStream;
54 import java.io.ObjectOutputStream;
55 import java.io.Serializable;
56 import java.util.Iterator;
57 import java.util.List;
58 
59 import org.jfree.chart.annotations.XYAnnotation;
60 import org.jfree.chart.annotations.XYTextAnnotation;
61 import org.jfree.chart.axis.CategoryAxis;
62 import org.jfree.chart.axis.PeriodAxis;
63 import org.jfree.chart.axis.PeriodAxisLabelInfo;
64 import org.jfree.chart.axis.SubCategoryAxis;
65 import org.jfree.chart.axis.SymbolAxis;
66 import org.jfree.chart.axis.ValueAxis;
67 import org.jfree.chart.block.Block;
68 import org.jfree.chart.block.BlockContainer;
69 import org.jfree.chart.block.LabelBlock;
70 import org.jfree.chart.plot.CategoryPlot;
71 import org.jfree.chart.plot.CombinedDomainCategoryPlot;
72 import org.jfree.chart.plot.CombinedDomainXYPlot;
73 import org.jfree.chart.plot.CombinedRangeCategoryPlot;
74 import org.jfree.chart.plot.CombinedRangeXYPlot;
75 import org.jfree.chart.plot.DefaultDrawingSupplier;
76 import org.jfree.chart.plot.DrawingSupplier;
77 import org.jfree.chart.plot.FastScatterPlot;
78 import org.jfree.chart.plot.MeterPlot;
79 import org.jfree.chart.plot.MultiplePiePlot;
80 import org.jfree.chart.plot.PieLabelLinkStyle;
81 import org.jfree.chart.plot.PiePlot;
82 import org.jfree.chart.plot.Plot;
83 import org.jfree.chart.plot.PolarPlot;
84 import org.jfree.chart.plot.SpiderWebPlot;
85 import org.jfree.chart.plot.ThermometerPlot;
86 import org.jfree.chart.plot.XYPlot;
87 import org.jfree.chart.renderer.AbstractRenderer;
88 import org.jfree.chart.renderer.category.BarPainter;
89 import org.jfree.chart.renderer.category.BarRenderer;
90 import org.jfree.chart.renderer.category.BarRenderer3D;
91 import org.jfree.chart.renderer.category.CategoryItemRenderer;
92 import org.jfree.chart.renderer.category.GradientBarPainter;
93 import org.jfree.chart.renderer.category.LineRenderer3D;
94 import org.jfree.chart.renderer.category.MinMaxCategoryRenderer;
95 import org.jfree.chart.renderer.category.StatisticalBarRenderer;
96 import org.jfree.chart.renderer.xy.GradientXYBarPainter;
97 import org.jfree.chart.renderer.xy.XYBarPainter;
98 import org.jfree.chart.renderer.xy.XYBarRenderer;
99 import org.jfree.chart.renderer.xy.XYItemRenderer;
100 import org.jfree.chart.title.CompositeTitle;
101 import org.jfree.chart.title.LegendTitle;
102 import org.jfree.chart.title.PaintScaleLegend;
103 import org.jfree.chart.title.TextTitle;
104 import org.jfree.chart.title.Title;
105 import org.jfree.chart.util.DefaultShadowGenerator;
106 import org.jfree.chart.util.ParamChecks;
107 import org.jfree.chart.util.ShadowGenerator;
108 import org.jfree.io.SerialUtilities;
109 import org.jfree.ui.RectangleInsets;
110 import org.jfree.util.PaintUtilities;
111 import org.jfree.util.PublicCloneable;
112 
113 /**
114  * A default implementation of the {@link ChartTheme} interface.  This
115  * implementation just collects a whole bunch of chart attributes and mimics
116  * the manual process of applying each attribute to the right sub-object
117  * within the JFreeChart instance.  It's not elegant code, but it works.
118  *
119  * @since 1.0.11
120  */
121 public class StandardChartTheme implements ChartTheme, Cloneable,
122         PublicCloneable, Serializable {
123 
124     /** The name of this theme. */
125     private String name;
126 
127     /**
128      * The largest font size.  Use for the main chart title.
129      */
130     private Font extraLargeFont;
131 
132     /**
133      * A large font.  Used for subtitles.
134      */
135     private Font largeFont;
136 
137     /**
138      * The regular font size.  Used for axis tick labels, legend items etc.
139      */
140     private Font regularFont;
141 
142     /**
143      * The small font size.
144      */
145     private Font smallFont;
146 
147     /** The paint used to display the main chart title. */
148     private transient Paint titlePaint;
149 
150     /** The paint used to display subtitles. */
151     private transient Paint subtitlePaint;
152 
153     /** The background paint for the chart. */
154     private transient Paint chartBackgroundPaint;
155 
156     /** The legend background paint. */
157     private transient Paint legendBackgroundPaint;
158 
159     /** The legend item paint. */
160     private transient Paint legendItemPaint;
161 
162     /** The drawing supplier. */
163     private DrawingSupplier drawingSupplier;
164 
165     /** The background paint for the plot. */
166     private transient Paint plotBackgroundPaint;
167 
168     /** The plot outline paint. */
169     private transient Paint plotOutlinePaint;
170 
171     /** The label link style for pie charts. */
172     private PieLabelLinkStyle labelLinkStyle;
173 
174     /** The label link paint for pie charts. */
175     private transient Paint labelLinkPaint;
176 
177     /** The domain grid line paint. */
178     private transient Paint domainGridlinePaint;
179 
180     /** The range grid line paint. */
181     private transient Paint rangeGridlinePaint;
182 
183     /**
184      * The baseline paint (used for domain and range zero baselines)
185      *
186      * @since 1.0.13
187      */
188     private transient Paint baselinePaint;
189 
190     /** The crosshair paint. */
191     private transient Paint crosshairPaint;
192 
193     /** The axis offsets. */
194     private RectangleInsets axisOffset;
195 
196     /** The axis label paint. */
197     private transient Paint axisLabelPaint;
198 
199     /** The tick label paint. */
200     private transient Paint tickLabelPaint;
201 
202     /** The item label paint. */
203     private transient Paint itemLabelPaint;
204 
205     /**
206      * A flag that controls whether or not shadows are visible (for example,
207      * in a bar renderer).
208      */
209     private boolean shadowVisible;
210 
211     /** The shadow paint. */
212     private transient Paint shadowPaint;
213 
214     /** The bar painter. */
215     private BarPainter barPainter;
216 
217     /** The XY bar painter. */
218     private XYBarPainter xyBarPainter;
219 
220     /** The thermometer paint. */
221     private transient Paint thermometerPaint;
222 
223     /**
224      * The paint used to fill the interior of the 'walls' in the background
225      * of a plot with a 3D effect.  Applied to BarRenderer3D.
226      */
227     private transient Paint wallPaint;
228 
229     /** The error indicator paint for the {@link StatisticalBarRenderer}. */
230     private transient Paint errorIndicatorPaint;
231 
232     /** The grid band paint for a {@link SymbolAxis}. */
233     private transient Paint gridBandPaint = SymbolAxis.DEFAULT_GRID_BAND_PAINT;
234 
235     /** The grid band alternate paint for a {@link SymbolAxis}. */
236     private transient Paint gridBandAlternatePaint
237             = SymbolAxis.DEFAULT_GRID_BAND_ALTERNATE_PAINT;
238 
239     /**
240      * The shadow generator (can be null).
241      *
242      * @since 1.0.14
243      */
244     private ShadowGenerator shadowGenerator;
245 
246     /**
247      * Creates and returns the default 'JFree' chart theme.
248      *
249      * @return A chart theme.
250      */
createJFreeTheme()251     public static ChartTheme createJFreeTheme() {
252         return new StandardChartTheme("JFree");
253     }
254 
255     /**
256      * Creates and returns a theme called "Darkness".  In this theme, the
257      * charts have a black background.
258      *
259      * @return The "Darkness" theme.
260      */
createDarknessTheme()261     public static ChartTheme createDarknessTheme() {
262         StandardChartTheme theme = new StandardChartTheme("Darkness");
263         theme.titlePaint = Color.white;
264         theme.subtitlePaint = Color.white;
265         theme.legendBackgroundPaint = Color.black;
266         theme.legendItemPaint = Color.white;
267         theme.chartBackgroundPaint = Color.black;
268         theme.plotBackgroundPaint = Color.black;
269         theme.plotOutlinePaint = Color.yellow;
270         theme.baselinePaint = Color.white;
271         theme.crosshairPaint = Color.red;
272         theme.labelLinkPaint = Color.lightGray;
273         theme.tickLabelPaint = Color.white;
274         theme.axisLabelPaint = Color.white;
275         theme.shadowPaint = Color.darkGray;
276         theme.itemLabelPaint = Color.white;
277         theme.drawingSupplier = new DefaultDrawingSupplier(
278                 new Paint[] {Color.decode("0xFFFF00"),
279                         Color.decode("0x0036CC"), Color.decode("0xFF0000"),
280                         Color.decode("0xFFFF7F"), Color.decode("0x6681CC"),
281                         Color.decode("0xFF7F7F"), Color.decode("0xFFFFBF"),
282                         Color.decode("0x99A6CC"), Color.decode("0xFFBFBF"),
283                         Color.decode("0xA9A938"), Color.decode("0x2D4587")},
284                 new Paint[] {Color.decode("0xFFFF00"),
285                         Color.decode("0x0036CC")},
286                 new Stroke[] {new BasicStroke(2.0f)},
287                 new Stroke[] {new BasicStroke(0.5f)},
288                 DefaultDrawingSupplier.DEFAULT_SHAPE_SEQUENCE);
289         theme.wallPaint = Color.darkGray;
290         theme.errorIndicatorPaint = Color.lightGray;
291         theme.gridBandPaint = new Color(255, 255, 255, 20);
292         theme.gridBandAlternatePaint = new Color(255, 255, 255, 40);
293         theme.shadowGenerator = null;
294         return theme;
295     }
296 
297     /**
298      * Creates and returns a {@link ChartTheme} that doesn't apply any changes
299      * to the JFreeChart defaults.  This produces the "legacy" look for
300      * JFreeChart.
301      *
302      * @return A legacy theme.
303      */
createLegacyTheme()304     public static ChartTheme createLegacyTheme() {
305         StandardChartTheme theme = new StandardChartTheme("Legacy") {
306             @Override
307             public void apply(JFreeChart chart) {
308                 // do nothing at all
309             }
310         };
311         return theme;
312     }
313 
314     /**
315      * Creates a new default instance.
316      *
317      * @param name  the name of the theme (<code>null</code> not permitted).
318      */
StandardChartTheme(String name)319     public StandardChartTheme(String name) {
320         this(name, false);
321     }
322 
323     /**
324      * Creates a new default instance.
325      *
326      * @param name  the name of the theme (<code>null</code> not permitted).
327      * @param shadow  a flag that controls whether a shadow generator is
328      *                included.
329      *
330      * @since 1.0.14
331      */
StandardChartTheme(String name, boolean shadow)332     public StandardChartTheme(String name, boolean shadow) {
333         ParamChecks.nullNotPermitted(name, "name");
334         this.name = name;
335         this.extraLargeFont = new Font("Tahoma", Font.BOLD, 20);
336         this.largeFont = new Font("Tahoma", Font.BOLD, 14);
337         this.regularFont = new Font("Tahoma", Font.PLAIN, 12);
338         this.smallFont = new Font("Tahoma", Font.PLAIN, 10);
339         this.titlePaint = Color.black;
340         this.subtitlePaint = Color.black;
341         this.legendBackgroundPaint = Color.white;
342         this.legendItemPaint = Color.darkGray;
343         this.chartBackgroundPaint = Color.white;
344         this.drawingSupplier = new DefaultDrawingSupplier();
345         this.plotBackgroundPaint = Color.lightGray;
346         this.plotOutlinePaint = Color.black;
347         this.labelLinkPaint = Color.black;
348         this.labelLinkStyle = PieLabelLinkStyle.CUBIC_CURVE;
349         this.axisOffset = new RectangleInsets(4, 4, 4, 4);
350         this.domainGridlinePaint = Color.white;
351         this.rangeGridlinePaint = Color.white;
352         this.baselinePaint = Color.black;
353         this.crosshairPaint = Color.blue;
354         this.axisLabelPaint = Color.darkGray;
355         this.tickLabelPaint = Color.darkGray;
356         this.barPainter = new GradientBarPainter();
357         this.xyBarPainter = new GradientXYBarPainter();
358         this.shadowVisible = false;
359         this.shadowPaint = Color.gray;
360         this.itemLabelPaint = Color.black;
361         this.thermometerPaint = Color.white;
362         this.wallPaint = BarRenderer3D.DEFAULT_WALL_PAINT;
363         this.errorIndicatorPaint = Color.black;
364         this.shadowGenerator = shadow ? new DefaultShadowGenerator() : null;
365     }
366 
367     /**
368      * Returns the largest font for this theme.
369      *
370      * @return The largest font for this theme.
371      *
372      * @see #setExtraLargeFont(Font)
373      */
getExtraLargeFont()374     public Font getExtraLargeFont() {
375         return this.extraLargeFont;
376     }
377 
378     /**
379      * Sets the largest font for this theme.
380      *
381      * @param font  the font (<code>null</code> not permitted).
382      *
383      * @see #getExtraLargeFont()
384      */
setExtraLargeFont(Font font)385     public void setExtraLargeFont(Font font) {
386         ParamChecks.nullNotPermitted(font, "font");
387         this.extraLargeFont = font;
388     }
389 
390     /**
391      * Returns the large font for this theme.
392      *
393      * @return The large font (never <code>null</code>).
394      *
395      * @see #setLargeFont(Font)
396      */
getLargeFont()397     public Font getLargeFont() {
398         return this.largeFont;
399     }
400 
401     /**
402      * Sets the large font for this theme.
403      *
404      * @param font  the font (<code>null</code> not permitted).
405      *
406      * @see #getLargeFont()
407      */
setLargeFont(Font font)408     public void setLargeFont(Font font) {
409         ParamChecks.nullNotPermitted(font, "font");
410         this.largeFont = font;
411     }
412 
413     /**
414      * Returns the regular font.
415      *
416      * @return The regular font (never <code>null</code>).
417      *
418      * @see #setRegularFont(Font)
419      */
getRegularFont()420     public Font getRegularFont() {
421         return this.regularFont;
422     }
423 
424     /**
425      * Sets the regular font for this theme.
426      *
427      * @param font  the font (<code>null</code> not permitted).
428      *
429      * @see #getRegularFont()
430      */
setRegularFont(Font font)431     public void setRegularFont(Font font) {
432         ParamChecks.nullNotPermitted(font, "font");
433         this.regularFont = font;
434     }
435 
436     /**
437      * Returns the small font.
438      *
439      * @return The small font (never <code>null</code>).
440      *
441      * @see #setSmallFont(Font)
442      *
443      * @since 1.0.13
444      */
getSmallFont()445     public Font getSmallFont() {
446         return this.smallFont;
447     }
448 
449     /**
450      * Sets the small font for this theme.
451      *
452      * @param font  the font (<code>null</code> not permitted).
453      *
454      * @see #getSmallFont()
455      *
456      * @since 1.0.13
457      */
setSmallFont(Font font)458     public void setSmallFont(Font font) {
459         ParamChecks.nullNotPermitted(font, "font");
460         this.smallFont = font;
461     }
462 
463     /**
464      * Returns the title paint.
465      *
466      * @return The title paint (never <code>null</code>).
467      *
468      * @see #setTitlePaint(Paint)
469      */
getTitlePaint()470     public Paint getTitlePaint() {
471         return this.titlePaint;
472     }
473 
474     /**
475      * Sets the title paint.
476      *
477      * @param paint  the paint (<code>null</code> not permitted).
478      *
479      * @see #getTitlePaint()
480      */
setTitlePaint(Paint paint)481     public void setTitlePaint(Paint paint) {
482         ParamChecks.nullNotPermitted(paint, "paint");
483         this.titlePaint = paint;
484     }
485 
486     /**
487      * Returns the subtitle paint.
488      *
489      * @return The subtitle paint (never <code>null</code>).
490      *
491      * @see #setSubtitlePaint(Paint)
492      */
getSubtitlePaint()493     public Paint getSubtitlePaint() {
494         return this.subtitlePaint;
495     }
496 
497     /**
498      * Sets the subtitle paint.
499      *
500      * @param paint  the paint (<code>null</code> not permitted).
501      *
502      * @see #getSubtitlePaint()
503      */
setSubtitlePaint(Paint paint)504     public void setSubtitlePaint(Paint paint) {
505         ParamChecks.nullNotPermitted(paint, "paint");
506         this.subtitlePaint = paint;
507     }
508 
509     /**
510      * Returns the chart background paint.
511      *
512      * @return The chart background paint (never <code>null</code>).
513      *
514      * @see #setChartBackgroundPaint(Paint)
515      */
getChartBackgroundPaint()516     public Paint getChartBackgroundPaint() {
517         return this.chartBackgroundPaint;
518     }
519 
520     /**
521      * Sets the chart background paint.
522      *
523      * @param paint  the paint (<code>null</code> not permitted).
524      *
525      * @see #getChartBackgroundPaint()
526      */
setChartBackgroundPaint(Paint paint)527     public void setChartBackgroundPaint(Paint paint) {
528         ParamChecks.nullNotPermitted(paint, "paint");
529         this.chartBackgroundPaint = paint;
530     }
531 
532     /**
533      * Returns the legend background paint.
534      *
535      * @return The legend background paint (never <code>null</code>).
536      *
537      * @see #setLegendBackgroundPaint(Paint)
538      */
getLegendBackgroundPaint()539     public Paint getLegendBackgroundPaint() {
540         return this.legendBackgroundPaint;
541     }
542 
543     /**
544      * Sets the legend background paint.
545      *
546      * @param paint  the paint (<code>null</code> not permitted).
547      *
548      * @see #getLegendBackgroundPaint()
549      */
setLegendBackgroundPaint(Paint paint)550     public void setLegendBackgroundPaint(Paint paint) {
551         ParamChecks.nullNotPermitted(paint, "paint");
552         this.legendBackgroundPaint = paint;
553     }
554 
555     /**
556      * Returns the legend item paint.
557      *
558      * @return The legend item paint (never <code>null</code>).
559      *
560      * @see #setLegendItemPaint(Paint)
561      */
getLegendItemPaint()562     public Paint getLegendItemPaint() {
563         return this.legendItemPaint;
564     }
565 
566     /**
567      * Sets the legend item paint.
568      *
569      * @param paint  the paint (<code>null</code> not permitted).
570      *
571      * @see #getLegendItemPaint()
572      */
setLegendItemPaint(Paint paint)573     public void setLegendItemPaint(Paint paint) {
574         ParamChecks.nullNotPermitted(paint, "paint");
575         this.legendItemPaint = paint;
576     }
577 
578     /**
579      * Returns the plot background paint.
580      *
581      * @return The plot background paint (never <code>null</code>).
582      *
583      * @see #setPlotBackgroundPaint(Paint)
584      */
getPlotBackgroundPaint()585     public Paint getPlotBackgroundPaint() {
586         return this.plotBackgroundPaint;
587     }
588 
589     /**
590      * Sets the plot background paint.
591      *
592      * @param paint  the paint (<code>null</code> not permitted).
593      *
594      * @see #getPlotBackgroundPaint()
595      */
setPlotBackgroundPaint(Paint paint)596     public void setPlotBackgroundPaint(Paint paint) {
597         ParamChecks.nullNotPermitted(paint, "paint");
598         this.plotBackgroundPaint = paint;
599     }
600 
601     /**
602      * Returns the plot outline paint.
603      *
604      * @return The plot outline paint (never <code>null</code>).
605      *
606      * @see #setPlotOutlinePaint(Paint)
607      */
getPlotOutlinePaint()608     public Paint getPlotOutlinePaint() {
609         return this.plotOutlinePaint;
610     }
611 
612     /**
613      * Sets the plot outline paint.
614      *
615      * @param paint  the paint (<code>null</code> not permitted).
616      *
617      * @see #getPlotOutlinePaint()
618      */
setPlotOutlinePaint(Paint paint)619     public void setPlotOutlinePaint(Paint paint) {
620         ParamChecks.nullNotPermitted(paint, "paint");
621         this.plotOutlinePaint = paint;
622     }
623 
624     /**
625      * Returns the label link style for pie charts.
626      *
627      * @return The label link style (never <code>null</code>).
628      *
629      * @see #setLabelLinkStyle(PieLabelLinkStyle)
630      */
getLabelLinkStyle()631     public PieLabelLinkStyle getLabelLinkStyle() {
632         return this.labelLinkStyle;
633     }
634 
635     /**
636      * Sets the label link style for pie charts.
637      *
638      * @param style  the style (<code>null</code> not permitted).
639      *
640      * @see #getLabelLinkStyle()
641      */
setLabelLinkStyle(PieLabelLinkStyle style)642     public void setLabelLinkStyle(PieLabelLinkStyle style) {
643         ParamChecks.nullNotPermitted(style, "style");
644         this.labelLinkStyle = style;
645     }
646 
647     /**
648      * Returns the label link paint for pie charts.
649      *
650      * @return The label link paint (never <code>null</code>).
651      *
652      * @see #setLabelLinkPaint(Paint)
653      */
getLabelLinkPaint()654     public Paint getLabelLinkPaint() {
655         return this.labelLinkPaint;
656     }
657 
658     /**
659      * Sets the label link paint for pie charts.
660      *
661      * @param paint  the paint (<code>null</code> not permitted).
662      *
663      * @see #getLabelLinkPaint()
664      */
setLabelLinkPaint(Paint paint)665     public void setLabelLinkPaint(Paint paint) {
666         ParamChecks.nullNotPermitted(paint, "paint");
667         this.labelLinkPaint = paint;
668     }
669 
670     /**
671      * Returns the domain grid line paint.
672      *
673      * @return The domain grid line paint (never <code>null</code>).
674      *
675      * @see #setDomainGridlinePaint(Paint)
676      */
getDomainGridlinePaint()677     public Paint getDomainGridlinePaint() {
678         return this.domainGridlinePaint;
679     }
680 
681     /**
682      * Sets the domain grid line paint.
683      *
684      * @param paint  the paint (<code>null</code> not permitted).
685      *
686      * @see #getDomainGridlinePaint()
687      */
setDomainGridlinePaint(Paint paint)688     public void setDomainGridlinePaint(Paint paint) {
689         ParamChecks.nullNotPermitted(paint, "paint");
690         this.domainGridlinePaint = paint;
691     }
692 
693     /**
694      * Returns the range grid line paint.
695      *
696      * @return The range grid line paint (never <code>null</code>).
697      *
698      * @see #setRangeGridlinePaint(Paint)
699      */
getRangeGridlinePaint()700     public Paint getRangeGridlinePaint() {
701         return this.rangeGridlinePaint;
702     }
703 
704     /**
705      * Sets the range grid line paint.
706      *
707      * @param paint  the paint (<code>null</code> not permitted).
708      *
709      * @see #getRangeGridlinePaint()
710      */
setRangeGridlinePaint(Paint paint)711     public void setRangeGridlinePaint(Paint paint) {
712         ParamChecks.nullNotPermitted(paint, "paint");
713         this.rangeGridlinePaint = paint;
714     }
715 
716     /**
717      * Returns the baseline paint.
718      *
719      * @return The baseline paint.
720      *
721      * @since 1.0.13
722      */
getBaselinePaint()723     public Paint getBaselinePaint() {
724         return this.baselinePaint;
725     }
726 
727     /**
728      * Sets the baseline paint.
729      *
730      * @param paint  the paint (<code>null</code> not permitted).
731      *
732      * @since 1.0.13
733      */
setBaselinePaint(Paint paint)734     public void setBaselinePaint(Paint paint) {
735         ParamChecks.nullNotPermitted(paint, "paint");
736         this.baselinePaint = paint;
737     }
738 
739     /**
740      * Returns the crosshair paint.
741      *
742      * @return The crosshair paint.
743      */
getCrosshairPaint()744     public Paint getCrosshairPaint() {
745         return this.crosshairPaint;
746     }
747 
748     /**
749      * Sets the crosshair paint.
750      *
751      * @param paint  the paint (<code>null</code> not permitted).
752      */
setCrosshairPaint(Paint paint)753     public void setCrosshairPaint(Paint paint) {
754         ParamChecks.nullNotPermitted(paint, "paint");
755         this.crosshairPaint = paint;
756     }
757 
758     /**
759      * Returns the axis offsets.
760      *
761      * @return The axis offsets (never <code>null</code>).
762      *
763      * @see #setAxisOffset(RectangleInsets)
764      */
getAxisOffset()765     public RectangleInsets getAxisOffset() {
766         return this.axisOffset;
767     }
768 
769     /**
770      * Sets the axis offset.
771      *
772      * @param offset  the offset (<code>null</code> not permitted).
773      *
774      * @see #getAxisOffset()
775      */
setAxisOffset(RectangleInsets offset)776     public void setAxisOffset(RectangleInsets offset) {
777         ParamChecks.nullNotPermitted(offset, "offset");
778         this.axisOffset = offset;
779     }
780 
781     /**
782      * Returns the axis label paint.
783      *
784      * @return The axis label paint (never <code>null</code>).
785      *
786      * @see #setAxisLabelPaint(Paint)
787      */
getAxisLabelPaint()788     public Paint getAxisLabelPaint() {
789         return this.axisLabelPaint;
790     }
791 
792     /**
793      * Sets the axis label paint.
794      *
795      * @param paint  the paint (<code>null</code> not permitted).
796      *
797      * @see #getAxisLabelPaint()
798      */
setAxisLabelPaint(Paint paint)799     public void setAxisLabelPaint(Paint paint) {
800         ParamChecks.nullNotPermitted(paint, "paint");
801         this.axisLabelPaint = paint;
802     }
803 
804     /**
805      * Returns the tick label paint.
806      *
807      * @return The tick label paint (never <code>null</code>).
808      *
809      * @see #setTickLabelPaint(Paint)
810      */
getTickLabelPaint()811     public Paint getTickLabelPaint() {
812         return this.tickLabelPaint;
813     }
814 
815     /**
816      * Sets the tick label paint.
817      *
818      * @param paint  the paint (<code>null</code> not permitted).
819      *
820      * @see #getTickLabelPaint()
821      */
setTickLabelPaint(Paint paint)822     public void setTickLabelPaint(Paint paint) {
823         ParamChecks.nullNotPermitted(paint, "paint");
824         this.tickLabelPaint = paint;
825     }
826 
827     /**
828      * Returns the item label paint.
829      *
830      * @return The item label paint (never <code>null</code>).
831      *
832      * @see #setItemLabelPaint(Paint)
833      */
getItemLabelPaint()834     public Paint getItemLabelPaint() {
835         return this.itemLabelPaint;
836     }
837 
838     /**
839      * Sets the item label paint.
840      *
841      * @param paint  the paint (<code>null</code> not permitted).
842      *
843      * @see #getItemLabelPaint()
844      */
setItemLabelPaint(Paint paint)845     public void setItemLabelPaint(Paint paint) {
846         ParamChecks.nullNotPermitted(paint, "paint");
847         this.itemLabelPaint = paint;
848     }
849 
850     /**
851      * Returns the shadow visibility flag.
852      *
853      * @return The shadow visibility flag.
854      *
855      * @see #setShadowVisible(boolean)
856      */
isShadowVisible()857     public boolean isShadowVisible() {
858         return this.shadowVisible;
859     }
860 
861     /**
862      * Sets the shadow visibility flag.
863      *
864      * @param visible  the flag.
865      *
866      * @see #isShadowVisible()
867      */
setShadowVisible(boolean visible)868     public void setShadowVisible(boolean visible) {
869         this.shadowVisible = visible;
870     }
871 
872     /**
873      * Returns the shadow paint.
874      *
875      * @return The shadow paint (never <code>null</code>).
876      *
877      * @see #setShadowPaint(Paint)
878      */
getShadowPaint()879     public Paint getShadowPaint() {
880         return this.shadowPaint;
881     }
882 
883     /**
884      * Sets the shadow paint.
885      *
886      * @param paint  the paint (<code>null</code> not permitted).
887      *
888      * @see #getShadowPaint()
889      */
setShadowPaint(Paint paint)890     public void setShadowPaint(Paint paint) {
891         ParamChecks.nullNotPermitted(paint, "paint");
892         this.shadowPaint = paint;
893     }
894 
895     /**
896      * Returns the bar painter.
897      *
898      * @return The bar painter (never <code>null</code>).
899      *
900      * @see #setBarPainter(BarPainter)
901      */
getBarPainter()902     public BarPainter getBarPainter() {
903         return this.barPainter;
904     }
905 
906     /**
907      * Sets the bar painter.
908      *
909      * @param painter  the painter (<code>null</code> not permitted).
910      *
911      * @see #getBarPainter()
912      */
setBarPainter(BarPainter painter)913     public void setBarPainter(BarPainter painter) {
914         ParamChecks.nullNotPermitted(painter, "painter");
915         this.barPainter = painter;
916     }
917 
918     /**
919      * Returns the XY bar painter.
920      *
921      * @return The XY bar painter (never <code>null</code>).
922      *
923      * @see #setXYBarPainter(XYBarPainter)
924      */
getXYBarPainter()925     public XYBarPainter getXYBarPainter() {
926         return this.xyBarPainter;
927     }
928 
929     /**
930      * Sets the XY bar painter.
931      *
932      * @param painter  the painter (<code>null</code> not permitted).
933      *
934      * @see #getXYBarPainter()
935      */
setXYBarPainter(XYBarPainter painter)936     public void setXYBarPainter(XYBarPainter painter) {
937         ParamChecks.nullNotPermitted(painter, "painter");
938         this.xyBarPainter = painter;
939     }
940 
941     /**
942      * Returns the thermometer paint.
943      *
944      * @return The thermometer paint (never <code>null</code>).
945      *
946      * @see #setThermometerPaint(Paint)
947      */
getThermometerPaint()948     public Paint getThermometerPaint() {
949         return this.thermometerPaint;
950     }
951 
952     /**
953      * Sets the thermometer paint.
954      *
955      * @param paint  the paint (<code>null</code> not permitted).
956      *
957      * @see #getThermometerPaint()
958      */
setThermometerPaint(Paint paint)959     public void setThermometerPaint(Paint paint) {
960         ParamChecks.nullNotPermitted(paint, "paint");
961         this.thermometerPaint = paint;
962     }
963 
964     /**
965      * Returns the wall paint for charts with a 3D effect.
966      *
967      * @return The wall paint (never <code>null</code>).
968      *
969      * @see #setWallPaint(Paint)
970      */
getWallPaint()971     public Paint getWallPaint() {
972         return this.wallPaint;
973     }
974 
975     /**
976      * Sets the wall paint for charts with a 3D effect.
977      *
978      * @param paint  the paint (<code>null</code> not permitted).
979      *
980      * @see #getWallPaint()
981      */
setWallPaint(Paint paint)982     public void setWallPaint(Paint paint) {
983         ParamChecks.nullNotPermitted(paint, "paint");
984         this.wallPaint = paint;
985     }
986 
987     /**
988      * Returns the error indicator paint.
989      *
990      * @return The error indicator paint (never <code>null</code>).
991      *
992      * @see #setErrorIndicatorPaint(Paint)
993      */
getErrorIndicatorPaint()994     public Paint getErrorIndicatorPaint() {
995         return this.errorIndicatorPaint;
996     }
997 
998     /**
999      * Sets the error indicator paint.
1000      *
1001      * @param paint  the paint (<code>null</code> not permitted).
1002      *
1003      * @see #getErrorIndicatorPaint()
1004      */
setErrorIndicatorPaint(Paint paint)1005     public void setErrorIndicatorPaint(Paint paint) {
1006         ParamChecks.nullNotPermitted(paint, "paint");
1007         this.errorIndicatorPaint = paint;
1008     }
1009 
1010     /**
1011      * Returns the grid band paint.
1012      *
1013      * @return The grid band paint (never <code>null</code>).
1014      *
1015      * @see #setGridBandPaint(Paint)
1016      */
getGridBandPaint()1017     public Paint getGridBandPaint() {
1018         return this.gridBandPaint;
1019     }
1020 
1021     /**
1022      * Sets the grid band paint.
1023      *
1024      * @param paint  the paint (<code>null</code> not permitted).
1025      *
1026      * @see #getGridBandPaint()
1027      */
setGridBandPaint(Paint paint)1028     public void setGridBandPaint(Paint paint) {
1029         ParamChecks.nullNotPermitted(paint, "paint");
1030         this.gridBandPaint = paint;
1031     }
1032 
1033     /**
1034      * Returns the grid band alternate paint (used for a {@link SymbolAxis}).
1035      *
1036      * @return The paint (never <code>null</code>).
1037      *
1038      * @see #setGridBandAlternatePaint(Paint)
1039      */
getGridBandAlternatePaint()1040     public Paint getGridBandAlternatePaint() {
1041         return this.gridBandAlternatePaint;
1042     }
1043 
1044     /**
1045      * Sets the grid band alternate paint (used for a {@link SymbolAxis}).
1046      *
1047      * @param paint  the paint (<code>null</code> not permitted).
1048      *
1049      * @see #getGridBandAlternatePaint()
1050      */
setGridBandAlternatePaint(Paint paint)1051     public void setGridBandAlternatePaint(Paint paint) {
1052         ParamChecks.nullNotPermitted(paint, "paint");
1053         this.gridBandAlternatePaint = paint;
1054     }
1055 
1056     /**
1057      * Returns the name of this theme.
1058      *
1059      * @return The name of this theme.
1060      */
getName()1061     public String getName() {
1062         return this.name;
1063     }
1064 
1065     /**
1066      * Returns a clone of the drawing supplier for this theme.
1067      *
1068      * @return A clone of the drawing supplier.
1069      */
getDrawingSupplier()1070     public DrawingSupplier getDrawingSupplier() {
1071         DrawingSupplier result = null;
1072         if (this.drawingSupplier instanceof PublicCloneable) {
1073             PublicCloneable pc = (PublicCloneable) this.drawingSupplier;
1074               try {
1075                 result = (DrawingSupplier) pc.clone();
1076             }
1077             catch (CloneNotSupportedException e) {
1078                 throw new RuntimeException(e);
1079             }
1080         }
1081         return result;
1082     }
1083 
1084     /**
1085      * Sets the drawing supplier for this theme.
1086      *
1087      * @param supplier  the supplier (<code>null</code> not permitted).
1088      *
1089      * @see #getDrawingSupplier()
1090      */
setDrawingSupplier(DrawingSupplier supplier)1091     public void setDrawingSupplier(DrawingSupplier supplier) {
1092         ParamChecks.nullNotPermitted(supplier, "supplier");
1093         this.drawingSupplier = supplier;
1094     }
1095 
1096     /**
1097      * Applies this theme to the supplied chart.
1098      *
1099      * @param chart  the chart (<code>null</code> not permitted).
1100      */
1101     @Override
apply(JFreeChart chart)1102     public void apply(JFreeChart chart) {
1103         ParamChecks.nullNotPermitted(chart, "chart");
1104         TextTitle title = chart.getTitle();
1105         if (title != null) {
1106             title.setFont(this.extraLargeFont);
1107             title.setPaint(this.titlePaint);
1108         }
1109 
1110         int subtitleCount = chart.getSubtitleCount();
1111         for (int i = 0; i < subtitleCount; i++) {
1112             applyToTitle(chart.getSubtitle(i));
1113         }
1114 
1115         chart.setBackgroundPaint(this.chartBackgroundPaint);
1116 
1117         // now process the plot if there is one
1118         Plot plot = chart.getPlot();
1119         if (plot != null) {
1120             applyToPlot(plot);
1121         }
1122     }
1123 
1124     /**
1125      * Applies the attributes of this theme to the specified title.
1126      *
1127      * @param title  the title.
1128      */
applyToTitle(Title title)1129     protected void applyToTitle(Title title) {
1130         if (title instanceof TextTitle) {
1131             TextTitle tt = (TextTitle) title;
1132             tt.setFont(this.largeFont);
1133             tt.setPaint(this.subtitlePaint);
1134         }
1135         else if (title instanceof LegendTitle) {
1136             LegendTitle lt = (LegendTitle) title;
1137             if (lt.getBackgroundPaint() != null) {
1138                 lt.setBackgroundPaint(this.legendBackgroundPaint);
1139             }
1140             lt.setItemFont(this.regularFont);
1141             lt.setItemPaint(this.legendItemPaint);
1142             if (lt.getWrapper() != null) {
1143                 applyToBlockContainer(lt.getWrapper());
1144             }
1145         }
1146         else if (title instanceof PaintScaleLegend) {
1147             PaintScaleLegend psl = (PaintScaleLegend) title;
1148             psl.setBackgroundPaint(this.legendBackgroundPaint);
1149             ValueAxis axis = psl.getAxis();
1150             if (axis != null) {
1151                 applyToValueAxis(axis);
1152             }
1153         }
1154         else if (title instanceof CompositeTitle) {
1155             CompositeTitle ct = (CompositeTitle) title;
1156             BlockContainer bc = ct.getContainer();
1157             List blocks = bc.getBlocks();
1158             Iterator iterator = blocks.iterator();
1159             while (iterator.hasNext()) {
1160                 Block b = (Block) iterator.next();
1161                 if (b instanceof Title) {
1162                     applyToTitle((Title) b);
1163                 }
1164             }
1165         }
1166     }
1167 
1168     /**
1169      * Applies the attributes of this theme to the specified container.
1170      *
1171      * @param bc  a block container (<code>null</code> not permitted).
1172      */
applyToBlockContainer(BlockContainer bc)1173     protected void applyToBlockContainer(BlockContainer bc) {
1174         Iterator iterator = bc.getBlocks().iterator();
1175         while (iterator.hasNext()) {
1176             Block b = (Block) iterator.next();
1177             applyToBlock(b);
1178         }
1179     }
1180 
1181     /**
1182      * Applies the attributes of this theme to the specified block.
1183      *
1184      * @param b  the block.
1185      */
applyToBlock(Block b)1186     protected void applyToBlock(Block b) {
1187         if (b instanceof Title) {
1188             applyToTitle((Title) b);
1189         }
1190         else if (b instanceof LabelBlock) {
1191             LabelBlock lb = (LabelBlock) b;
1192             lb.setFont(this.regularFont);
1193             lb.setPaint(this.legendItemPaint);
1194         }
1195     }
1196 
1197     /**
1198      * Applies the attributes of this theme to a plot.
1199      *
1200      * @param plot  the plot (<code>null</code>).
1201      */
applyToPlot(Plot plot)1202     protected void applyToPlot(Plot plot) {
1203         ParamChecks.nullNotPermitted(plot, "plot");
1204         if (plot.getDrawingSupplier() != null) {
1205             plot.setDrawingSupplier(getDrawingSupplier());
1206         }
1207         if (plot.getBackgroundPaint() != null) {
1208             plot.setBackgroundPaint(this.plotBackgroundPaint);
1209         }
1210         plot.setOutlinePaint(this.plotOutlinePaint);
1211 
1212         // now handle specific plot types (and yes, I know this is some
1213         // really ugly code that has to be manually updated any time a new
1214         // plot type is added - I should have written something much cooler,
1215         // but I didn't and neither did anyone else).
1216         if (plot instanceof PiePlot) {
1217             applyToPiePlot((PiePlot) plot);
1218         }
1219         else if (plot instanceof MultiplePiePlot) {
1220             applyToMultiplePiePlot((MultiplePiePlot) plot);
1221         }
1222         else if (plot instanceof CategoryPlot) {
1223             applyToCategoryPlot((CategoryPlot) plot);
1224         }
1225         else if (plot instanceof XYPlot) {
1226             applyToXYPlot((XYPlot) plot);
1227         }
1228         else if (plot instanceof FastScatterPlot) {
1229             applyToFastScatterPlot((FastScatterPlot) plot);
1230         }
1231         else if (plot instanceof MeterPlot) {
1232             applyToMeterPlot((MeterPlot) plot);
1233         }
1234         else if (plot instanceof ThermometerPlot) {
1235             applyToThermometerPlot((ThermometerPlot) plot);
1236         }
1237         else if (plot instanceof SpiderWebPlot) {
1238             applyToSpiderWebPlot((SpiderWebPlot) plot);
1239         }
1240         else if (plot instanceof PolarPlot) {
1241             applyToPolarPlot((PolarPlot) plot);
1242         }
1243     }
1244 
1245     /**
1246      * Applies the attributes of this theme to a {@link PiePlot} instance.
1247      * This method also clears any set values for the section paint, outline
1248      * etc, so that the theme's {@link DrawingSupplier} will be used.
1249      *
1250      * @param plot  the plot (<code>null</code> not permitted).
1251      */
applyToPiePlot(PiePlot plot)1252     protected void applyToPiePlot(PiePlot plot) {
1253         plot.setLabelLinkPaint(this.labelLinkPaint);
1254         plot.setLabelLinkStyle(this.labelLinkStyle);
1255         plot.setLabelFont(this.regularFont);
1256         plot.setShadowGenerator(this.shadowGenerator);
1257 
1258         // clear the section attributes so that the theme's DrawingSupplier
1259         // will be used
1260         if (plot.getAutoPopulateSectionPaint()) {
1261             plot.clearSectionPaints(false);
1262         }
1263         if (plot.getAutoPopulateSectionOutlinePaint()) {
1264             plot.clearSectionOutlinePaints(false);
1265         }
1266         if (plot.getAutoPopulateSectionOutlineStroke()) {
1267             plot.clearSectionOutlineStrokes(false);
1268         }
1269     }
1270 
1271     /**
1272      * Applies the attributes of this theme to a {@link MultiplePiePlot}.
1273      *
1274      * @param plot  the plot (<code>null</code> not permitted).
1275      */
applyToMultiplePiePlot(MultiplePiePlot plot)1276     protected void applyToMultiplePiePlot(MultiplePiePlot plot) {
1277         apply(plot.getPieChart());
1278     }
1279 
1280     /**
1281      * Applies the attributes of this theme to a {@link CategoryPlot}.
1282      *
1283      * @param plot  the plot (<code>null</code> not permitted).
1284      */
applyToCategoryPlot(CategoryPlot plot)1285     protected void applyToCategoryPlot(CategoryPlot plot) {
1286         plot.setAxisOffset(this.axisOffset);
1287         plot.setDomainGridlinePaint(this.domainGridlinePaint);
1288         plot.setRangeGridlinePaint(this.rangeGridlinePaint);
1289         plot.setRangeZeroBaselinePaint(this.baselinePaint);
1290         plot.setShadowGenerator(this.shadowGenerator);
1291 
1292         // process all domain axes
1293         int domainAxisCount = plot.getDomainAxisCount();
1294         for (int i = 0; i < domainAxisCount; i++) {
1295             CategoryAxis axis = plot.getDomainAxis(i);
1296             if (axis != null) {
1297                 applyToCategoryAxis(axis);
1298             }
1299         }
1300 
1301         // process all range axes
1302         int rangeAxisCount = plot.getRangeAxisCount();
1303         for (int i = 0; i < rangeAxisCount; i++) {
1304             ValueAxis axis = plot.getRangeAxis(i);
1305             if (axis != null) {
1306                 applyToValueAxis(axis);
1307             }
1308         }
1309 
1310         // process all renderers
1311         int rendererCount = plot.getRendererCount();
1312         for (int i = 0; i < rendererCount; i++) {
1313             CategoryItemRenderer r = plot.getRenderer(i);
1314             if (r != null) {
1315                 applyToCategoryItemRenderer(r);
1316             }
1317         }
1318 
1319         if (plot instanceof CombinedDomainCategoryPlot) {
1320             CombinedDomainCategoryPlot cp = (CombinedDomainCategoryPlot) plot;
1321             Iterator iterator = cp.getSubplots().iterator();
1322             while (iterator.hasNext()) {
1323                 CategoryPlot subplot = (CategoryPlot) iterator.next();
1324                 if (subplot != null) {
1325                     applyToPlot(subplot);
1326                 }
1327             }
1328         }
1329         if (plot instanceof CombinedRangeCategoryPlot) {
1330             CombinedRangeCategoryPlot cp = (CombinedRangeCategoryPlot) plot;
1331             Iterator iterator = cp.getSubplots().iterator();
1332             while (iterator.hasNext()) {
1333                 CategoryPlot subplot = (CategoryPlot) iterator.next();
1334                 if (subplot != null) {
1335                     applyToPlot(subplot);
1336                 }
1337             }
1338         }
1339     }
1340 
1341     /**
1342      * Applies the attributes of this theme to a {@link XYPlot}.
1343      *
1344      * @param plot  the plot (<code>null</code> not permitted).
1345      */
applyToXYPlot(XYPlot plot)1346     protected void applyToXYPlot(XYPlot plot) {
1347         plot.setAxisOffset(this.axisOffset);
1348         plot.setDomainZeroBaselinePaint(this.baselinePaint);
1349         plot.setRangeZeroBaselinePaint(this.baselinePaint);
1350         plot.setDomainGridlinePaint(this.domainGridlinePaint);
1351         plot.setRangeGridlinePaint(this.rangeGridlinePaint);
1352         plot.setDomainCrosshairPaint(this.crosshairPaint);
1353         plot.setRangeCrosshairPaint(this.crosshairPaint);
1354         plot.setShadowGenerator(this.shadowGenerator);
1355 
1356         // process all domain axes
1357         int domainAxisCount = plot.getDomainAxisCount();
1358         for (int i = 0; i < domainAxisCount; i++) {
1359             ValueAxis axis = plot.getDomainAxis(i);
1360             if (axis != null) {
1361                 applyToValueAxis(axis);
1362             }
1363         }
1364 
1365         // process all range axes
1366         int rangeAxisCount = plot.getRangeAxisCount();
1367         for (int i = 0; i < rangeAxisCount; i++) {
1368             ValueAxis axis = plot.getRangeAxis(i);
1369             if (axis != null) {
1370                 applyToValueAxis(axis);
1371             }
1372         }
1373 
1374         // process all renderers
1375         int rendererCount = plot.getRendererCount();
1376         for (int i = 0; i < rendererCount; i++) {
1377             XYItemRenderer r = plot.getRenderer(i);
1378             if (r != null) {
1379                 applyToXYItemRenderer(r);
1380             }
1381         }
1382 
1383         // process all annotations
1384         Iterator iter = plot.getAnnotations().iterator();
1385         while (iter.hasNext()) {
1386             XYAnnotation a = (XYAnnotation) iter.next();
1387             applyToXYAnnotation(a);
1388         }
1389 
1390         if (plot instanceof CombinedDomainXYPlot) {
1391             CombinedDomainXYPlot cp = (CombinedDomainXYPlot) plot;
1392             Iterator iterator = cp.getSubplots().iterator();
1393             while (iterator.hasNext()) {
1394                 XYPlot subplot = (XYPlot) iterator.next();
1395                 if (subplot != null) {
1396                     applyToPlot(subplot);
1397                 }
1398             }
1399         }
1400         if (plot instanceof CombinedRangeXYPlot) {
1401             CombinedRangeXYPlot cp = (CombinedRangeXYPlot) plot;
1402             Iterator iterator = cp.getSubplots().iterator();
1403             while (iterator.hasNext()) {
1404                 XYPlot subplot = (XYPlot) iterator.next();
1405                 if (subplot != null) {
1406                     applyToPlot(subplot);
1407                 }
1408             }
1409         }
1410     }
1411 
1412     /**
1413      * Applies the attributes of this theme to a {@link FastScatterPlot}.
1414      * @param plot
1415      */
applyToFastScatterPlot(FastScatterPlot plot)1416     protected void applyToFastScatterPlot(FastScatterPlot plot) {
1417         plot.setDomainGridlinePaint(this.domainGridlinePaint);
1418         plot.setRangeGridlinePaint(this.rangeGridlinePaint);
1419         ValueAxis xAxis = plot.getDomainAxis();
1420         if (xAxis != null) {
1421             applyToValueAxis(xAxis);
1422         }
1423         ValueAxis yAxis = plot.getRangeAxis();
1424         if (yAxis != null) {
1425             applyToValueAxis(yAxis);
1426         }
1427 
1428     }
1429 
1430     /**
1431      * Applies the attributes of this theme to a {@link PolarPlot}.  This
1432      * method is called from the {@link #applyToPlot(Plot)} method.
1433      *
1434      * @param plot  the plot (<code>null</code> not permitted).
1435      */
applyToPolarPlot(PolarPlot plot)1436     protected void applyToPolarPlot(PolarPlot plot) {
1437         plot.setAngleLabelFont(this.regularFont);
1438         plot.setAngleLabelPaint(this.tickLabelPaint);
1439         plot.setAngleGridlinePaint(this.domainGridlinePaint);
1440         plot.setRadiusGridlinePaint(this.rangeGridlinePaint);
1441         ValueAxis axis = plot.getAxis();
1442         if (axis != null) {
1443             applyToValueAxis(axis);
1444         }
1445     }
1446 
1447     /**
1448      * Applies the attributes of this theme to a {@link SpiderWebPlot}.
1449      *
1450      * @param plot  the plot (<code>null</code> not permitted).
1451      */
applyToSpiderWebPlot(SpiderWebPlot plot)1452     protected void applyToSpiderWebPlot(SpiderWebPlot plot) {
1453         plot.setLabelFont(this.regularFont);
1454         plot.setLabelPaint(this.axisLabelPaint);
1455         plot.setAxisLinePaint(this.axisLabelPaint);
1456     }
1457 
1458     /**
1459      * Applies the attributes of this theme to a {@link MeterPlot}.
1460      *
1461      * @param plot  the plot (<code>null</code> not permitted).
1462      */
applyToMeterPlot(MeterPlot plot)1463     protected void applyToMeterPlot(MeterPlot plot) {
1464         plot.setDialBackgroundPaint(this.plotBackgroundPaint);
1465         plot.setValueFont(this.largeFont);
1466         plot.setValuePaint(this.axisLabelPaint);
1467         plot.setDialOutlinePaint(this.plotOutlinePaint);
1468         plot.setNeedlePaint(this.thermometerPaint);
1469         plot.setTickLabelFont(this.regularFont);
1470         plot.setTickLabelPaint(this.tickLabelPaint);
1471     }
1472 
1473     /**
1474      * Applies the attributes for this theme to a {@link ThermometerPlot}.
1475      * This method is called from the {@link #applyToPlot(Plot)} method.
1476      *
1477      * @param plot  the plot.
1478      */
applyToThermometerPlot(ThermometerPlot plot)1479     protected void applyToThermometerPlot(ThermometerPlot plot) {
1480         plot.setValueFont(this.largeFont);
1481         plot.setThermometerPaint(this.thermometerPaint);
1482         ValueAxis axis = plot.getRangeAxis();
1483         if (axis != null) {
1484             applyToValueAxis(axis);
1485         }
1486     }
1487 
1488     /**
1489      * Applies the attributes for this theme to a {@link CategoryAxis}.
1490      *
1491      * @param axis  the axis (<code>null</code> not permitted).
1492      */
applyToCategoryAxis(CategoryAxis axis)1493     protected void applyToCategoryAxis(CategoryAxis axis) {
1494         axis.setLabelFont(this.largeFont);
1495         axis.setLabelPaint(this.axisLabelPaint);
1496         axis.setTickLabelFont(this.regularFont);
1497         axis.setTickLabelPaint(this.tickLabelPaint);
1498         if (axis instanceof SubCategoryAxis) {
1499             SubCategoryAxis sca = (SubCategoryAxis) axis;
1500             sca.setSubLabelFont(this.regularFont);
1501             sca.setSubLabelPaint(this.tickLabelPaint);
1502         }
1503     }
1504 
1505     /**
1506      * Applies the attributes for this theme to a {@link ValueAxis}.
1507      *
1508      * @param axis  the axis (<code>null</code> not permitted).
1509      */
applyToValueAxis(ValueAxis axis)1510     protected void applyToValueAxis(ValueAxis axis) {
1511         axis.setLabelFont(this.largeFont);
1512         axis.setLabelPaint(this.axisLabelPaint);
1513         axis.setTickLabelFont(this.regularFont);
1514         axis.setTickLabelPaint(this.tickLabelPaint);
1515         if (axis instanceof SymbolAxis) {
1516             applyToSymbolAxis((SymbolAxis) axis);
1517         }
1518         if (axis instanceof PeriodAxis) {
1519             applyToPeriodAxis((PeriodAxis) axis);
1520         }
1521     }
1522 
1523     /**
1524      * Applies the attributes for this theme to a {@link SymbolAxis}.
1525      *
1526      * @param axis  the axis (<code>null</code> not permitted).
1527      */
applyToSymbolAxis(SymbolAxis axis)1528     protected void applyToSymbolAxis(SymbolAxis axis) {
1529         axis.setGridBandPaint(this.gridBandPaint);
1530         axis.setGridBandAlternatePaint(this.gridBandAlternatePaint);
1531     }
1532 
1533     /**
1534      * Applies the attributes for this theme to a {@link PeriodAxis}.
1535      *
1536      * @param axis  the axis (<code>null</code> not permitted).
1537      */
applyToPeriodAxis(PeriodAxis axis)1538     protected void applyToPeriodAxis(PeriodAxis axis) {
1539         PeriodAxisLabelInfo[] info = axis.getLabelInfo();
1540         for (int i = 0; i < info.length; i++) {
1541             PeriodAxisLabelInfo e = info[i];
1542             PeriodAxisLabelInfo n = new PeriodAxisLabelInfo(e.getPeriodClass(),
1543                     e.getDateFormat(), e.getPadding(), this.regularFont,
1544                     this.tickLabelPaint, e.getDrawDividers(),
1545                     e.getDividerStroke(), e.getDividerPaint());
1546             info[i] = n;
1547         }
1548         axis.setLabelInfo(info);
1549     }
1550 
1551     /**
1552      * Applies the attributes for this theme to an {@link AbstractRenderer}.
1553      *
1554      * @param renderer  the renderer (<code>null</code> not permitted).
1555      */
applyToAbstractRenderer(AbstractRenderer renderer)1556     protected void applyToAbstractRenderer(AbstractRenderer renderer) {
1557         if (renderer.getAutoPopulateSeriesPaint()) {
1558             renderer.clearSeriesPaints(false);
1559         }
1560         if (renderer.getAutoPopulateSeriesStroke()) {
1561             renderer.clearSeriesStrokes(false);
1562         }
1563     }
1564 
1565     /**
1566      * Applies the settings of this theme to the specified renderer.
1567      *
1568      * @param renderer  the renderer (<code>null</code> not permitted).
1569      */
applyToCategoryItemRenderer(CategoryItemRenderer renderer)1570     protected void applyToCategoryItemRenderer(CategoryItemRenderer renderer) {
1571         ParamChecks.nullNotPermitted(renderer, "renderer");
1572 
1573         if (renderer instanceof AbstractRenderer) {
1574             applyToAbstractRenderer((AbstractRenderer) renderer);
1575         }
1576 
1577         renderer.setBaseItemLabelFont(this.regularFont);
1578         renderer.setBaseItemLabelPaint(this.itemLabelPaint);
1579 
1580         // now we handle some special cases - yes, UGLY code alert!
1581 
1582         // BarRenderer
1583         if (renderer instanceof BarRenderer) {
1584             BarRenderer br = (BarRenderer) renderer;
1585             br.setBarPainter(this.barPainter);
1586             br.setShadowVisible(this.shadowVisible);
1587             br.setShadowPaint(this.shadowPaint);
1588         }
1589 
1590         // BarRenderer3D
1591         if (renderer instanceof BarRenderer3D) {
1592             BarRenderer3D br3d = (BarRenderer3D) renderer;
1593             br3d.setWallPaint(this.wallPaint);
1594         }
1595 
1596         // LineRenderer3D
1597         if (renderer instanceof LineRenderer3D) {
1598             LineRenderer3D lr3d = (LineRenderer3D) renderer;
1599             lr3d.setWallPaint(this.wallPaint);
1600         }
1601 
1602         //  StatisticalBarRenderer
1603         if (renderer instanceof StatisticalBarRenderer) {
1604             StatisticalBarRenderer sbr = (StatisticalBarRenderer) renderer;
1605             sbr.setErrorIndicatorPaint(this.errorIndicatorPaint);
1606         }
1607 
1608         // MinMaxCategoryRenderer
1609         if (renderer instanceof MinMaxCategoryRenderer) {
1610             MinMaxCategoryRenderer mmcr = (MinMaxCategoryRenderer) renderer;
1611             mmcr.setGroupPaint(this.errorIndicatorPaint);
1612         }
1613     }
1614 
1615     /**
1616      * Applies the settings of this theme to the specified renderer.
1617      *
1618      * @param renderer  the renderer (<code>null</code> not permitted).
1619      */
applyToXYItemRenderer(XYItemRenderer renderer)1620     protected void applyToXYItemRenderer(XYItemRenderer renderer) {
1621         ParamChecks.nullNotPermitted(renderer, "renderer");
1622         if (renderer instanceof AbstractRenderer) {
1623             applyToAbstractRenderer((AbstractRenderer) renderer);
1624         }
1625         renderer.setBaseItemLabelFont(this.regularFont);
1626         renderer.setBaseItemLabelPaint(this.itemLabelPaint);
1627         if (renderer instanceof XYBarRenderer) {
1628             XYBarRenderer br = (XYBarRenderer) renderer;
1629             br.setBarPainter(this.xyBarPainter);
1630             br.setShadowVisible(this.shadowVisible);
1631         }
1632     }
1633 
1634     /**
1635      * Applies the settings of this theme to the specified annotation.
1636      *
1637      * @param annotation  the annotation.
1638      */
applyToXYAnnotation(XYAnnotation annotation)1639     protected void applyToXYAnnotation(XYAnnotation annotation) {
1640         ParamChecks.nullNotPermitted(annotation, "annotation");
1641         if (annotation instanceof XYTextAnnotation) {
1642             XYTextAnnotation xyta = (XYTextAnnotation) annotation;
1643             xyta.setFont(this.smallFont);
1644             xyta.setPaint(this.itemLabelPaint);
1645         }
1646     }
1647 
1648     /**
1649      * Tests this theme for equality with an arbitrary object.
1650      *
1651      * @param obj  the object (<code>null</code> permitted).
1652      *
1653      * @return A boolean.
1654      */
1655     @Override
equals(Object obj)1656     public boolean equals(Object obj) {
1657         if (obj == this) {
1658             return true;
1659         }
1660         if (!(obj instanceof StandardChartTheme)) {
1661             return false;
1662         }
1663         StandardChartTheme that = (StandardChartTheme) obj;
1664         if (!this.name.equals(that.name)) {
1665             return false;
1666         }
1667         if (!this.extraLargeFont.equals(that.extraLargeFont)) {
1668             return false;
1669         }
1670         if (!this.largeFont.equals(that.largeFont)) {
1671             return false;
1672         }
1673         if (!this.regularFont.equals(that.regularFont)) {
1674             return false;
1675         }
1676         if (!this.smallFont.equals(that.smallFont)) {
1677             return false;
1678         }
1679         if (!PaintUtilities.equal(this.titlePaint, that.titlePaint)) {
1680             return false;
1681         }
1682         if (!PaintUtilities.equal(this.subtitlePaint, that.subtitlePaint)) {
1683             return false;
1684         }
1685         if (!PaintUtilities.equal(this.chartBackgroundPaint,
1686                 that.chartBackgroundPaint)) {
1687             return false;
1688         }
1689         if (!PaintUtilities.equal(this.legendBackgroundPaint,
1690                 that.legendBackgroundPaint)) {
1691             return false;
1692         }
1693         if (!PaintUtilities.equal(this.legendItemPaint, that.legendItemPaint)) {
1694             return false;
1695         }
1696         if (!this.drawingSupplier.equals(that.drawingSupplier)) {
1697             return false;
1698         }
1699         if (!PaintUtilities.equal(this.plotBackgroundPaint,
1700                 that.plotBackgroundPaint)) {
1701             return false;
1702         }
1703         if (!PaintUtilities.equal(this.plotOutlinePaint,
1704                 that.plotOutlinePaint)) {
1705             return false;
1706         }
1707         if (!this.labelLinkStyle.equals(that.labelLinkStyle)) {
1708             return false;
1709         }
1710         if (!PaintUtilities.equal(this.labelLinkPaint, that.labelLinkPaint)) {
1711             return false;
1712         }
1713         if (!PaintUtilities.equal(this.domainGridlinePaint,
1714                 that.domainGridlinePaint)) {
1715             return false;
1716         }
1717         if (!PaintUtilities.equal(this.rangeGridlinePaint,
1718                 that.rangeGridlinePaint)) {
1719             return false;
1720         }
1721         if (!PaintUtilities.equal(this.crosshairPaint, that.crosshairPaint)) {
1722             return false;
1723         }
1724         if (!this.axisOffset.equals(that.axisOffset)) {
1725             return false;
1726         }
1727         if (!PaintUtilities.equal(this.axisLabelPaint, that.axisLabelPaint)) {
1728             return false;
1729         }
1730         if (!PaintUtilities.equal(this.tickLabelPaint, that.tickLabelPaint)) {
1731             return false;
1732         }
1733         if (!PaintUtilities.equal(this.itemLabelPaint, that.itemLabelPaint)) {
1734             return false;
1735         }
1736         if (this.shadowVisible != that.shadowVisible) {
1737             return false;
1738         }
1739         if (!PaintUtilities.equal(this.shadowPaint, that.shadowPaint)) {
1740             return false;
1741         }
1742         if (!this.barPainter.equals(that.barPainter)) {
1743             return false;
1744         }
1745         if (!this.xyBarPainter.equals(that.xyBarPainter)) {
1746             return false;
1747         }
1748         if (!PaintUtilities.equal(this.thermometerPaint,
1749                 that.thermometerPaint)) {
1750             return false;
1751         }
1752         if (!PaintUtilities.equal(this.wallPaint, that.wallPaint)) {
1753             return false;
1754         }
1755         if (!PaintUtilities.equal(this.errorIndicatorPaint,
1756                 that.errorIndicatorPaint)) {
1757             return false;
1758         }
1759         if (!PaintUtilities.equal(this.gridBandPaint, that.gridBandPaint)) {
1760             return false;
1761         }
1762         if (!PaintUtilities.equal(this.gridBandAlternatePaint,
1763                 that.gridBandAlternatePaint)) {
1764             return false;
1765         }
1766         return true;
1767     }
1768 
1769     /**
1770      * Returns a clone of this theme.
1771      *
1772      * @return A clone.
1773      *
1774      * @throws CloneNotSupportedException if the theme cannot be cloned.
1775      */
1776     @Override
clone()1777     public Object clone() throws CloneNotSupportedException {
1778         return super.clone();
1779     }
1780 
1781     /**
1782      * Provides serialization support.
1783      *
1784      * @param stream  the output stream (<code>null</code> not permitted).
1785      *
1786      * @throws IOException  if there is an I/O error.
1787      */
writeObject(ObjectOutputStream stream)1788     private void writeObject(ObjectOutputStream stream) throws IOException {
1789         stream.defaultWriteObject();
1790         SerialUtilities.writePaint(this.titlePaint, stream);
1791         SerialUtilities.writePaint(this.subtitlePaint, stream);
1792         SerialUtilities.writePaint(this.chartBackgroundPaint, stream);
1793         SerialUtilities.writePaint(this.legendBackgroundPaint, stream);
1794         SerialUtilities.writePaint(this.legendItemPaint, stream);
1795         SerialUtilities.writePaint(this.plotBackgroundPaint, stream);
1796         SerialUtilities.writePaint(this.plotOutlinePaint, stream);
1797         SerialUtilities.writePaint(this.labelLinkPaint, stream);
1798         SerialUtilities.writePaint(this.baselinePaint, stream);
1799         SerialUtilities.writePaint(this.domainGridlinePaint, stream);
1800         SerialUtilities.writePaint(this.rangeGridlinePaint, stream);
1801         SerialUtilities.writePaint(this.crosshairPaint, stream);
1802         SerialUtilities.writePaint(this.axisLabelPaint, stream);
1803         SerialUtilities.writePaint(this.tickLabelPaint, stream);
1804         SerialUtilities.writePaint(this.itemLabelPaint, stream);
1805         SerialUtilities.writePaint(this.shadowPaint, stream);
1806         SerialUtilities.writePaint(this.thermometerPaint, stream);
1807         SerialUtilities.writePaint(this.wallPaint, stream);
1808         SerialUtilities.writePaint(this.errorIndicatorPaint, stream);
1809         SerialUtilities.writePaint(this.gridBandPaint, stream);
1810         SerialUtilities.writePaint(this.gridBandAlternatePaint, stream);
1811     }
1812 
1813     /**
1814      * Provides serialization support.
1815      *
1816      * @param stream  the input stream (<code>null</code> not permitted).
1817      *
1818      * @throws IOException  if there is an I/O error.
1819      * @throws ClassNotFoundException  if there is a classpath problem.
1820      */
readObject(ObjectInputStream stream)1821     private void readObject(ObjectInputStream stream)
1822         throws IOException, ClassNotFoundException {
1823         stream.defaultReadObject();
1824         this.titlePaint = SerialUtilities.readPaint(stream);
1825         this.subtitlePaint = SerialUtilities.readPaint(stream);
1826         this.chartBackgroundPaint = SerialUtilities.readPaint(stream);
1827         this.legendBackgroundPaint = SerialUtilities.readPaint(stream);
1828         this.legendItemPaint = SerialUtilities.readPaint(stream);
1829         this.plotBackgroundPaint = SerialUtilities.readPaint(stream);
1830         this.plotOutlinePaint = SerialUtilities.readPaint(stream);
1831         this.labelLinkPaint = SerialUtilities.readPaint(stream);
1832         this.baselinePaint = SerialUtilities.readPaint(stream);
1833         this.domainGridlinePaint = SerialUtilities.readPaint(stream);
1834         this.rangeGridlinePaint = SerialUtilities.readPaint(stream);
1835         this.crosshairPaint = SerialUtilities.readPaint(stream);
1836         this.axisLabelPaint = SerialUtilities.readPaint(stream);
1837         this.tickLabelPaint = SerialUtilities.readPaint(stream);
1838         this.itemLabelPaint = SerialUtilities.readPaint(stream);
1839         this.shadowPaint = SerialUtilities.readPaint(stream);
1840         this.thermometerPaint = SerialUtilities.readPaint(stream);
1841         this.wallPaint = SerialUtilities.readPaint(stream);
1842         this.errorIndicatorPaint = SerialUtilities.readPaint(stream);
1843         this.gridBandPaint = SerialUtilities.readPaint(stream);
1844         this.gridBandAlternatePaint = SerialUtilities.readPaint(stream);
1845     }
1846 
1847 }
1848