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