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