001/* =========================================================== 002 * Orson Charts : a 3D chart library for the Java(tm) platform 003 * =========================================================== 004 * 005 * (C)opyright 2013-2022, by David Gilbert. All rights reserved. 006 * 007 * https://github.com/jfree/orson-charts 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 org.jfree.chart3d.table; 034 035import java.awt.Color; 036import java.awt.GradientPaint; 037import java.awt.Graphics2D; 038import java.awt.Paint; 039import java.awt.geom.Point2D; 040import java.awt.geom.Rectangle2D; 041import java.io.Serializable; 042 043import org.jfree.chart3d.TitleAnchor; 044import org.jfree.chart3d.graphics2d.Anchor2D; 045import org.jfree.chart3d.internal.Args; 046import org.jfree.chart3d.internal.ObjectUtils; 047 048/** 049 * A {@link RectanglePainter} that can fill a rectangle with a gradient (the 050 * gradient is generated using anchor points to fit any size rectangle on 051 * demand). Instances of this class are immutable. 052 * <br><br> 053 * NOTE: This class is serializable, but the serialization format is subject 054 * to change in future releases and should not be relied upon for persisting 055 * instances of this class. 056 */ 057@SuppressWarnings("serial") 058public final class GradientRectanglePainter implements RectanglePainter, 059 Serializable { 060 061 /** The first color for the gradient. */ 062 private final Color color1; 063 064 /** The anchor point used to find the starting point for the gradient. */ 065 private final Anchor2D anchor1; 066 067 /** The first color for the gradient. */ 068 private final Color color2; 069 070 /** The anchor point used to find the ending point for the gradient. */ 071 private final Anchor2D anchor2; 072 073 /** 074 * Creates a new instance. 075 * <br><br> 076 * NOTE: some useful standard anchor points are defined in the 077 * {@link TitleAnchor} class. 078 * 079 * @param color1 the first color for the gradient ({@code null} not 080 * permitted). 081 * @param anchor1 the anchor point used to determine the starting point 082 * for the gradient ({@code null} not permitted). 083 * @param color2 the second color for the gradient ({@code null} not 084 * permitted). 085 * @param anchor2 the anchor point used to determine the ending point for 086 * the gradient ({@code null} not permitted). 087 */ 088 public GradientRectanglePainter(Color color1, Anchor2D anchor1, 089 Color color2, Anchor2D anchor2) { 090 Args.nullNotPermitted(color1, "color1"); 091 Args.nullNotPermitted(anchor1, "anchor1"); 092 Args.nullNotPermitted(color2, "color2"); 093 Args.nullNotPermitted(anchor2, "anchor2"); 094 this.color1 = color1; 095 this.anchor1 = anchor1; 096 this.color2 = color2; 097 this.anchor2 = anchor2; 098 } 099 100 /** 101 * Returns the first color for the gradient (as specified via the 102 * constructor). There is no setter method because instances of this class 103 * are immutable. 104 * 105 * @return The first color for the gradient (never {@code null}). 106 */ 107 public Color getColor1() { 108 return this.color1; 109 } 110 111 /** 112 * Returns the anchor point used to find the starting point for the 113 * gradient (as specified via the constructor). There is no setter method 114 * because instances of this class are immutable. 115 * 116 * @return The anchor point (never {@code null}). 117 */ 118 public Anchor2D getAnchor1() { 119 return this.anchor1; 120 } 121 122 /** 123 * Returns the second color for the gradient (as specified via the 124 * constructor). There is no setter method because instances of this class 125 * are immutable. 126 * 127 * @return The second color for the gradient (never {@code null}). 128 */ 129 public Color getColor2() { 130 return this.color2; 131 } 132 133 /** 134 * Returns the anchor point used to find the ending point for the 135 * gradient (as specified via the constructor). There is no setter method 136 * because instances of this class are immutable. 137 * 138 * @return The anchor point (never {@code null}). 139 */ 140 public Anchor2D getAnchor2() { 141 return this.anchor2; 142 } 143 144 /** 145 * Returns a {@code GradientPaint} instance with coordinates based 146 * on the painter's anchor points and the supplied rectangle. 147 * 148 * @param area the area ({@code null} not permitted). 149 * 150 * @return A gradient paint (never {@code null}). 151 */ 152 private GradientPaint createTransformedGradient(Rectangle2D area) { 153 // defer arg check 154 Point2D pt1 = this.anchor1.getAnchorPoint(area); 155 Point2D pt2 = this.anchor2.getAnchorPoint(area); 156 return new GradientPaint(pt1, this.color1, pt2, this.color2); 157 } 158 159 /** 160 * Fills the specified {@code area} with a gradient paint created 161 * using the colors and anchor points of this painter. 162 * 163 * @param g2 the graphics target ({@code null} not permitted). 164 * @param area the area to fill ({@code null} not permitted). 165 */ 166 @Override 167 public void fill(Graphics2D g2, Rectangle2D area) { 168 Paint saved = g2.getPaint(); 169 g2.setPaint(createTransformedGradient(area)); 170 g2.fill(area); 171 g2.setPaint(saved); 172 } 173 174 /** 175 * Tests this instance for equality with an arbitrary object. 176 * 177 * @param obj the object ({@code null} not permitted). 178 * 179 * @return A boolean. 180 */ 181 @Override 182 public boolean equals(Object obj) { 183 if (obj == this) { 184 return true; 185 } 186 if (!(obj instanceof GradientRectanglePainter)) { 187 return false; 188 } 189 GradientRectanglePainter that = (GradientRectanglePainter) obj; 190 if (!this.color1.equals(that.color1)) { 191 return false; 192 } 193 if (!this.anchor1.equals(that.anchor1)) { 194 return false; 195 } 196 if (!this.color2.equals(that.color2)) { 197 return false; 198 } 199 if (!this.anchor2.equals(that.anchor2)) { 200 return false; 201 } 202 return true; 203 } 204 205 @Override 206 public int hashCode() { 207 int hash = 5; 208 hash = 67 * hash + ObjectUtils.hashCode(this.color1); 209 hash = 67 * hash + ObjectUtils.hashCode(this.anchor1); 210 hash = 67 * hash + ObjectUtils.hashCode(this.color2); 211 hash = 67 * hash + ObjectUtils.hashCode(this.anchor2); 212 return hash; 213 } 214 215}