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