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