001/* ===========================================================
002 * JFreeChart : a free chart library for the Java(tm) platform
003 * ===========================================================
004 *
005 * (C) Copyright 2000-present, by David Gilbert 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 * StandardBarPainter.java
029 * -----------------------
030 * (C) Copyright 2008-present, by David Gilbert.
031 *
032 * Original Author:  David Gilbert;
033 * Contributor(s):   -;
034 */
035
036package org.jfree.chart.renderer.category;
037
038import java.awt.Color;
039import java.awt.GradientPaint;
040import java.awt.Graphics2D;
041import java.awt.Paint;
042import java.awt.Stroke;
043import java.awt.geom.Rectangle2D;
044import java.awt.geom.RectangularShape;
045import java.io.Serializable;
046import org.jfree.chart.ui.GradientPaintTransformer;
047import org.jfree.chart.ui.RectangleEdge;
048
049/**
050 * An implementation of the {@link BarPainter} interface that preserves the
051 * behaviour of bar painting that existed prior to the introduction of the
052 * {@link BarPainter} interface.
053 *
054 * @see GradientBarPainter
055 */
056public class StandardBarPainter implements BarPainter, Serializable {
057
058    /**
059     * Creates a new instance.
060     */
061    public StandardBarPainter() {
062    }
063
064    /**
065     * Paints a single bar instance.
066     *
067     * @param g2  the graphics target.
068     * @param renderer  the renderer.
069     * @param row  the row index.
070     * @param column  the column index.
071     * @param bar  the bar
072     * @param base  indicates which side of the rectangle is the base of the
073     *              bar.
074     */
075    @Override
076    public void paintBar(Graphics2D g2, BarRenderer renderer, int row,
077            int column, RectangularShape bar, RectangleEdge base) {
078
079        Paint itemPaint = renderer.getItemPaint(row, column);
080        GradientPaintTransformer t = renderer.getGradientPaintTransformer();
081        if (t != null && itemPaint instanceof GradientPaint) {
082            itemPaint = t.transform((GradientPaint) itemPaint, bar);
083        }
084        g2.setPaint(itemPaint);
085        g2.fill(bar);
086
087        // draw the outline...
088        if (renderer.isDrawBarOutline()) {
089               // && state.getBarWidth() > BAR_OUTLINE_WIDTH_THRESHOLD) {
090            Stroke stroke = renderer.getItemOutlineStroke(row, column);
091            Paint paint = renderer.getItemOutlinePaint(row, column);
092            if (stroke != null && paint != null) {
093                g2.setStroke(stroke);
094                g2.setPaint(paint);
095                g2.draw(bar);
096            }
097        }
098
099    }
100
101    /**
102     * Paints a single bar instance.
103     *
104     * @param g2  the graphics target.
105     * @param renderer  the renderer.
106     * @param row  the row index.
107     * @param column  the column index.
108     * @param bar  the bar
109     * @param base  indicates which side of the rectangle is the base of the
110     *              bar.
111     * @param pegShadow  peg the shadow to the base of the bar?
112     */
113    @Override
114    public void paintBarShadow(Graphics2D g2, BarRenderer renderer, int row,
115            int column, RectangularShape bar, RectangleEdge base,
116            boolean pegShadow) {
117
118        // handle a special case - if the bar colour has alpha == 0, it is
119        // invisible so we shouldn't draw any shadow
120        Paint itemPaint = renderer.getItemPaint(row, column);
121        if (itemPaint instanceof Color) {
122            Color c = (Color) itemPaint;
123            if (c.getAlpha() == 0) {
124                return;
125            }
126        }
127
128        RectangularShape shadow = createShadow(bar, renderer.getShadowXOffset(),
129                renderer.getShadowYOffset(), base, pegShadow);
130        g2.setPaint(renderer.getShadowPaint());
131        g2.fill(shadow);
132
133    }
134
135    /**
136     * Creates a shadow for the bar.
137     *
138     * @param bar  the bar shape.
139     * @param xOffset  the x-offset for the shadow.
140     * @param yOffset  the y-offset for the shadow.
141     * @param base  the edge that is the base of the bar.
142     * @param pegShadow  peg the shadow to the base?
143     *
144     * @return A rectangle for the shadow.
145     */
146    private Rectangle2D createShadow(RectangularShape bar, double xOffset,
147            double yOffset, RectangleEdge base, boolean pegShadow) {
148        double x0 = bar.getMinX();
149        double x1 = bar.getMaxX();
150        double y0 = bar.getMinY();
151        double y1 = bar.getMaxY();
152        if (base == RectangleEdge.TOP) {
153            x0 += xOffset;
154            x1 += xOffset;
155            if (!pegShadow) {
156                y0 += yOffset;
157            }
158            y1 += yOffset;
159        }
160        else if (base == RectangleEdge.BOTTOM) {
161            x0 += xOffset;
162            x1 += xOffset;
163            y0 += yOffset;
164            if (!pegShadow) {
165                y1 += yOffset;
166            }
167        }
168        else if (base == RectangleEdge.LEFT) {
169            if (!pegShadow) {
170                x0 += xOffset;
171            }
172            x1 += xOffset;
173            y0 += yOffset;
174            y1 += yOffset;
175        }
176        else if (base == RectangleEdge.RIGHT) {
177            x0 += xOffset;
178            if (!pegShadow) {
179                x1 += xOffset;
180            }
181            y0 += yOffset;
182            y1 += yOffset;
183        }
184        return new Rectangle2D.Double(x0, y0, (x1 - x0), (y1 - y0));
185    }
186
187    /**
188     * Tests this instance for equality with an arbitrary object.
189     *
190     * @param obj  the obj ({@code null} permitted).
191     *
192     * @return A boolean.
193     */
194    @Override
195    public boolean equals(Object obj) {
196        if (obj == this) {
197            return true;
198        }
199        if (!(obj instanceof StandardBarPainter)) {
200            return false;
201        }
202        return true;
203    }
204
205    /**
206     * Returns a hash code for this instance.
207     *
208     * @return A hash code.
209     */
210    @Override
211    public int hashCode() {
212        int hash = 37;
213        // no fields to compute...
214        return hash;
215    }
216
217}