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