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} 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} P2 with 38 * {@code Color} C2 are specified in user space, the 39 * {@code Color} 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} C1 while points on the P2 side 52 * have the constant {@code Color} 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} object. 69 * @param x1 x coordinate of the first specified 70 * {@code Point} in user space 71 * @param y1 y coordinate of the first specified 72 * {@code Point} in user space 73 * @param color1 {@code Color} at the first specified 74 * {@code Point} 75 * @param x2 x coordinate of the second specified 76 * {@code Point} in user space 77 * @param y2 y coordinate of the second specified 78 * {@code Point} in user space 79 * @param color2 {@code Color} at the second specified 80 * {@code Point} 81 * @throws NullPointerException if either one of colors is null 82 */ 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} object. 101 * @param pt1 the first specified {@code Point} in user space 102 * @param color1 {@code Color} at the first specified 103 * {@code Point} 104 * @param pt2 the second specified {@code Point} in user space 105 * @param color2 {@code Color} at the second specified 106 * {@code Point} 107 * @throws NullPointerException if either one of colors or points 108 * is null 109 */ 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} 127 * object depending on the {@code boolean} parameter. 128 * @param x1 x coordinate of the first specified 129 * {@code Point} in user space 130 * @param y1 y coordinate of the first specified 131 * {@code Point} in user space 132 * @param color1 {@code Color} at the first specified 133 * {@code Point} 134 * @param x2 x coordinate of the second specified 135 * {@code Point} in user space 136 * @param y2 y coordinate of the second specified 137 * {@code Point} in user space 138 * @param color2 {@code Color} at the second specified 139 * {@code Point} 140 * @param cyclic {@code true} if the gradient pattern should cycle 141 * repeatedly between the two colors; {@code false} otherwise 142 */ 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} 156 * object depending on the {@code boolean} parameter. 157 * @param pt1 the first specified {@code Point} 158 * in user space 159 * @param color1 {@code Color} at the first specified 160 * {@code Point} 161 * @param pt2 the second specified {@code Point} 162 * in user space 163 * @param color2 {@code Color} at the second specified 164 * {@code Point} 165 * @param cyclic {@code true} if the gradient pattern should cycle 166 * repeatedly between the two colors; {@code false} otherwise 167 * @throws NullPointerException if either one of colors or points 168 * is null 169 */ 170 @ConstructorProperties({ "point1", "color1", "point2", "color2", "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}. 185 */ 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} object that is the color 193 * anchored by P1. 194 */ 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}. 204 */ 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} object that is the color 212 * anchored by P2. 213 */ 214 public Color getColor2() { 215 return color2; 216 } 217 218 /** 219 * Returns {@code true} if the gradient cycles repeatedly 220 * between the two colors C1 and C2. 221 * @return {@code true} if the gradient cycles repeatedly 222 * between the two colors; {@code false} otherwise. 223 */ 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 */ 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}. 268 * @return an integer value representing this {@code GradientPaint} 269 * object's transparency mode. 270 * @see Transparency 271 */ 272 public int getTransparency() { 273 int a1 = color1.getAlpha(); 274 int a2 = color2.getAlpha(); 275 return (((a1 & a2) == 0xff) ? OPAQUE : TRANSLUCENT); 276 } 277 278 }