1 /* 2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package java.awt; 27 28 import java.awt.geom.Point2D; 29 import java.awt.geom.Rectangle2D; 30 import java.awt.geom.AffineTransform; 31 import java.awt.image.ColorModel; 32 import java.beans.ConstructorProperties; 33 34 /** 35 * The <code>GradientPaint</code> class provides a way to fill 36 * a {@link Shape} with a linear color gradient pattern. 37 * If {@link Point} P1 with {@link Color} C1 and <code>Point</code> P2 with 38 * <code>Color</code> C2 are specified in user space, the 39 * <code>Color</code> on the P1, P2 connecting line is proportionally 40 * changed from C1 to C2. Any point P not on the extended P1, P2 41 * connecting line has the color of the point P' that is the perpendicular 42 * projection of P on the extended P1, P2 connecting line. 43 * Points on the extended line outside of the P1, P2 segment can be colored 44 * in one of two ways. 45 * <ul> 46 * <li> 47 * If the gradient is cyclic then the points on the extended P1, P2 48 * connecting line cycle back and forth between the colors C1 and C2. 49 * <li> 50 * If the gradient is acyclic then points on the P1 side of the segment 51 * have the constant <code>Color</code> C1 while points on the P2 side 52 * have the constant <code>Color</code> C2. 53 * </ul> 54 * 55 * @see Paint 56 * @see Graphics2D#setPaint 57 * @version 10 Feb 1997 58 */ 59 60 public class GradientPaint implements Paint { 61 Point2D.Float p1; 62 Point2D.Float p2; 63 Color color1; 64 Color color2; 65 boolean cyclic; 66 67 /** 68 * Constructs a simple acyclic <code>GradientPaint</code> object. 69 * @param x1 x coordinate of the first specified 70 * <code>Point</code> in user space 71 * @param y1 y coordinate of the first specified 72 * <code>Point</code> in user space 73 * @param color1 <code>Color</code> at the first specified 74 * <code>Point</code> 75 * @param x2 x coordinate of the second specified 76 * <code>Point</code> in user space 77 * @param y2 y coordinate of the second specified 78 * <code>Point</code> in user space 79 * @param color2 <code>Color</code> at the second specified 80 * <code>Point</code> 81 * @throws NullPointerException if either one of colors is null 82 */ GradientPaint(float x1, float y1, Color color1, float x2, float y2, Color color2)83 public GradientPaint(float x1, 84 float y1, 85 Color color1, 86 float x2, 87 float y2, 88 Color color2) { 89 if ((color1 == null) || (color2 == null)) { 90 throw new NullPointerException("Colors cannot be null"); 91 } 92 93 p1 = new Point2D.Float(x1, y1); 94 p2 = new Point2D.Float(x2, y2); 95 this.color1 = color1; 96 this.color2 = color2; 97 } 98 99 /** 100 * Constructs a simple acyclic <code>GradientPaint</code> object. 101 * @param pt1 the first specified <code>Point</code> in user space 102 * @param color1 <code>Color</code> at the first specified 103 * <code>Point</code> 104 * @param pt2 the second specified <code>Point</code> in user space 105 * @param color2 <code>Color</code> at the second specified 106 * <code>Point</code> 107 * @throws NullPointerException if either one of colors or points 108 * is null 109 */ GradientPaint(Point2D pt1, Color color1, Point2D pt2, Color color2)110 public GradientPaint(Point2D pt1, 111 Color color1, 112 Point2D pt2, 113 Color color2) { 114 if ((color1 == null) || (color2 == null) || 115 (pt1 == null) || (pt2 == null)) { 116 throw new NullPointerException("Colors and points should be non-null"); 117 } 118 119 p1 = new Point2D.Float((float)pt1.getX(), (float)pt1.getY()); 120 p2 = new Point2D.Float((float)pt2.getX(), (float)pt2.getY()); 121 this.color1 = color1; 122 this.color2 = color2; 123 } 124 125 /** 126 * Constructs either a cyclic or acyclic <code>GradientPaint</code> 127 * object depending on the <code>boolean</code> parameter. 128 * @param x1 x coordinate of the first specified 129 * <code>Point</code> in user space 130 * @param y1 y coordinate of the first specified 131 * <code>Point</code> in user space 132 * @param color1 <code>Color</code> at the first specified 133 * <code>Point</code> 134 * @param x2 x coordinate of the second specified 135 * <code>Point</code> in user space 136 * @param y2 y coordinate of the second specified 137 * <code>Point</code> in user space 138 * @param color2 <code>Color</code> at the second specified 139 * <code>Point</code> 140 * @param cyclic <code>true</code> if the gradient pattern should cycle 141 * repeatedly between the two colors; <code>false</code> otherwise 142 */ GradientPaint(float x1, float y1, Color color1, float x2, float y2, Color color2, boolean cyclic)143 public GradientPaint(float x1, 144 float y1, 145 Color color1, 146 float x2, 147 float y2, 148 Color color2, 149 boolean cyclic) { 150 this (x1, y1, color1, x2, y2, color2); 151 this.cyclic = cyclic; 152 } 153 154 /** 155 * Constructs either a cyclic or acyclic <code>GradientPaint</code> 156 * object depending on the <code>boolean</code> parameter. 157 * @param pt1 the first specified <code>Point</code> 158 * in user space 159 * @param color1 <code>Color</code> at the first specified 160 * <code>Point</code> 161 * @param pt2 the second specified <code>Point</code> 162 * in user space 163 * @param color2 <code>Color</code> at the second specified 164 * <code>Point</code> 165 * @param cyclic <code>true</code> if the gradient pattern should cycle 166 * repeatedly between the two colors; <code>false</code> otherwise 167 * @throws NullPointerException if either one of colors or points 168 * is null 169 */ 170 @ConstructorProperties({ "point1", "color1", "point2", "color2", "cyclic" }) GradientPaint(Point2D pt1, Color color1, Point2D pt2, Color color2, boolean cyclic)171 public GradientPaint(Point2D pt1, 172 Color color1, 173 Point2D pt2, 174 Color color2, 175 boolean cyclic) { 176 this (pt1, color1, pt2, color2); 177 this.cyclic = cyclic; 178 } 179 180 /** 181 * Returns a copy of the point P1 that anchors the first color. 182 * @return a {@link Point2D} object that is a copy of the point 183 * that anchors the first color of this 184 * <code>GradientPaint</code>. 185 */ getPoint1()186 public Point2D getPoint1() { 187 return new Point2D.Float(p1.x, p1.y); 188 } 189 190 /** 191 * Returns the color C1 anchored by the point P1. 192 * @return a <code>Color</code> object that is the color 193 * anchored by P1. 194 */ getColor1()195 public Color getColor1() { 196 return color1; 197 } 198 199 /** 200 * Returns a copy of the point P2 which anchors the second color. 201 * @return a {@link Point2D} object that is a copy of the point 202 * that anchors the second color of this 203 * <code>GradientPaint</code>. 204 */ getPoint2()205 public Point2D getPoint2() { 206 return new Point2D.Float(p2.x, p2.y); 207 } 208 209 /** 210 * Returns the color C2 anchored by the point P2. 211 * @return a <code>Color</code> object that is the color 212 * anchored by P2. 213 */ getColor2()214 public Color getColor2() { 215 return color2; 216 } 217 218 /** 219 * Returns <code>true</code> if the gradient cycles repeatedly 220 * between the two colors C1 and C2. 221 * @return <code>true</code> if the gradient cycles repeatedly 222 * between the two colors; <code>false</code> otherwise. 223 */ isCyclic()224 public boolean isCyclic() { 225 return cyclic; 226 } 227 228 /** 229 * Creates and returns a {@link PaintContext} used to 230 * generate a linear color gradient pattern. 231 * See the {@link Paint#createContext specification} of the 232 * method in the {@link Paint} interface for information 233 * on null parameter handling. 234 * 235 * @param cm the preferred {@link ColorModel} which represents the most convenient 236 * format for the caller to receive the pixel data, or {@code null} 237 * if there is no preference. 238 * @param deviceBounds the device space bounding box 239 * of the graphics primitive being rendered. 240 * @param userBounds the user space bounding box 241 * of the graphics primitive being rendered. 242 * @param xform the {@link AffineTransform} from user 243 * space into device space. 244 * @param hints the set of hints that the context object can use to 245 * choose between rendering alternatives. 246 * @return the {@code PaintContext} for 247 * generating color patterns. 248 * @see Paint 249 * @see PaintContext 250 * @see ColorModel 251 * @see Rectangle 252 * @see Rectangle2D 253 * @see AffineTransform 254 * @see RenderingHints 255 */ createContext(ColorModel cm, Rectangle deviceBounds, Rectangle2D userBounds, AffineTransform xform, RenderingHints hints)256 public PaintContext createContext(ColorModel cm, 257 Rectangle deviceBounds, 258 Rectangle2D userBounds, 259 AffineTransform xform, 260 RenderingHints hints) { 261 262 return new GradientPaintContext(cm, p1, p2, xform, 263 color1, color2, cyclic); 264 } 265 266 /** 267 * Returns the transparency mode for this <code>GradientPaint</code>. 268 * @return an integer value representing this <code>GradientPaint</code> 269 * object's transparency mode. 270 * @see Transparency 271 */ getTransparency()272 public int getTransparency() { 273 int a1 = color1.getAlpha(); 274 int a2 = color2.getAlpha(); 275 return (((a1 & a2) == 0xff) ? OPAQUE : TRANSLUCENT); 276 } 277 278 } 279