    001/* ===========================================================
    002 * Orson Charts : a 3D chart library for the Java(tm) platform
    003 * ===========================================================
    004 *
    005 * (C)opyright 2013-2016, by Object Refinery Limited.  All rights reserved.
    006 *
    007 * http://www.object-refinery.com/orsoncharts/index.html
    008 *
    009 * This program is free software: you can redistribute it and/or modify
    010 * it under the terms of the GNU General Public License as published by
    011 * the Free Software Foundation, either version 3 of the License, or
    012 * (at your option) any later version.
    013 *
    014 * This program is distributed in the hope that it will be useful,
    015 * but WITHOUT ANY WARRANTY; without even the implied warranty of
    016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    017 * GNU General Public License for more details.
    018 *
    019 * You should have received a copy of the GNU General Public License
    020 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    021 *
    022 * [Oracle and Java are registered trademarks of Oracle and/or its affiliates.
    023 * Other names may be trademarks of their respective owners.]
    024 *
    025 * If you do not wish to be bound by the terms of the GPL, an alternative
    026 * commercial license can be purchased.  For details, please see visit the
    027 * Orson Charts home page:
    028 *
    029 * http://www.object-refinery.com/orsoncharts/index.html
    030 *
    031 */
    032
    033package com.orsoncharts.plot;
    034
    035import java.awt.Color;
    036import java.io.Serializable;
    037import java.util.Arrays;
    038
    039import com.orsoncharts.util.ArgChecks;
    040import com.orsoncharts.data.DefaultKeyedValues;
    041import com.orsoncharts.Colors;
    042
    043/**
    044 * A standard implementation of the {@link ColorSource} interface.
    045 * <br><br>
    046 * NOTE: This class is serializable, but the serialization format is subject
    047 * to change in future releases and should not be relied upon for persisting
    048 * instances of this class.
    049 */
    050@SuppressWarnings("serial")
    051public final class StandardColorSource implements ColorSource,
    052        Serializable {
    053
    054    /**
    055     * An array of standard colors from which a color will be assigned if
    056     * there is not one already stored for a given key.
    057     */
    058    private Color[] standardColors;
    059
    060    /** Storage for the colors assigned to keys. */
    061    private DefaultKeyedValues<Color> colors;
    062
    063    /**
    064     * Creates a new instance with default colors.
    065     */
    066    public StandardColorSource() {
    067        this(Colors.getDefaultColors());
    068    }
    069
    070    /**
    071     * Creates a new instance with the supplied sequence of colors.  The
    072     * supplied array must have at least one entry, and all entries must be
    073     * non-{@code null}.
    074     *
    075     * @param colors  the colors ({@code null} not permitted).
    076     */
    077    public StandardColorSource(Color... colors) {
    078        ArgChecks.nullNotPermitted(colors, "colors");
    079        if (colors.length == 0) {
    080            throw new IllegalArgumentException(
    081                    "Zero length array not permitted.");
    082        }
    083        for (Color c: colors) {
    084            if (c == null) {
    085                throw new IllegalArgumentException(
    086                        "Null array entries not permitted.");
    087            }
    088        }
    089        this.standardColors = colors.clone();
    090        this.colors = new DefaultKeyedValues<Color>();
    091    }
    092
    093    /**
    094     * Returns the color associated with the specified key.
    095     *
    096     * @param key  the key ({@code null} not permitted).
    097     *
    098     * @return The color (never {@code null}).
    099     */
    100    @Override
    101    public Color getColor(Comparable<?> key) {
    102        // defer argument check
    103        Color c = this.colors.getValue(key);
    104        if (c != null) {
    105            return c;
    106        }
    107        c = this.standardColors[this.colors.getItemCount()
    108                % this.standardColors.length];
    109        this.colors.put(key, c);
    110        return c;
    111    }
    112
    113    /**
    114     * Sets the color for the specified key.
    115     *
    116     * @param key  the key ({@code null} not permitted).
    117     * @param color  the color ({@code null} permitted).
    118     */
    119    @Override
    120    public void setColor(Comparable<?> key, Color color) {
    121        if (color != null) {
    122            this.colors.put(key, color);
    123        } else {
    124            this.colors.remove(key);
    125        }
    126    }
    127
    128    /**
    129     * Clears existing color settings and sets the default colors to the
    130     * supplied value.  This method is used by the framework and is not
    131     * normally called by client code.
    132     *
    133     * @param colors  the colors ({@code null} not permitted).
    134     *
    135     * @since 1.2
    136     */
    137    @Override
    138    public void style(Color... colors) {
    139        this.standardColors = colors;
    140        this.colors.clear();
    141    }
    142
    143    /**
    144     * Tests this paint source for equality with an arbitrary object.
    145     *
    146     * @param obj  the object ({@code null} permitted).
    147     *
    148     * @return A boolean.
    149     */
    150    @Override
    151    public boolean equals(Object obj) {
    152        if (obj == this) {
    153            return true;
    154        }
    155        if (!(obj instanceof StandardColorSource)) {
    156            return false;
    157        }
    158        StandardColorSource that = (StandardColorSource) obj;
    159        if (!Arrays.equals(this.standardColors, that.standardColors)) {
    160            return false;
    161        }
    162        if (!this.colors.equals(that.colors)) {
    163            return false;
    164        }
    165        return true;
    166    }
    167
    168}