001 /*
002 * $Id: BasicGradientPainter.java,v 1.1 2006/03/22 19:05:44 rbair Exp $
003 *
004 * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
005 * Santa Clara, California 95054, U.S.A. All rights reserved.
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * You should have received a copy of the GNU Lesser General Public
018 * License along with this library; if not, write to the Free Software
019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
020 */
021
022 package org.jdesktop.swingx.painter.gradient;
023
024 import java.awt.Color;
025 import java.awt.GradientPaint;
026 import java.awt.Paint;
027 import java.awt.PaintContext;
028 import java.awt.Rectangle;
029 import java.awt.RenderingHints;
030 import java.awt.color.ColorSpace;
031 import java.awt.geom.AffineTransform;
032 import java.awt.geom.Point2D;
033 import java.awt.geom.Rectangle2D;
034 import java.awt.image.ColorModel;
035 import javax.swing.UIManager;
036
037 /**
038 * <p>A Gradient based Painter that uses GradientPaint to paint the gradient.
039 * Simply specify the GradientPaint to use.</p>
040 *
041 * <p>In order for resizing to work properly with GradientPaint
042 * it is necessary that the various control points used in
043 * these paints be specified in such a manner that they can be reliably resized.
044 * For example, BasicGradientPainter takes GradientPaints who's point1 and point2
045 * properties are specified between 0 and 1, representing at what percentage of
046 * the distance from the origin the gradient begins and ends. Thus, if I created
047 * a GradientPaint like this:
048 * <pre><code>
049 * GradientPaint gp = new GradientPaint(
050 * new Point2D.Double(.2d, 0),
051 * Color.BLUE,
052 * new Point2D.Double(.8d, 0),
053 * Color.WHITE);
054 * </code></pre>
055 *
056 * then when painted, the gradient will start with a BLUE at 20% of the width of
057 * the component, and finish with WHITE at 80% of the width of the component.</p>
058 *
059 * <p>Various built in gradients also exist as public static final properties.
060 * They are defined as GradientPaints rather than BasicGradientPainters because
061 * BasicGradientPainter is mutable and thus don't make very reliable public static
062 * final defaults. To use:
063 * <pre><code>
064 * panel.setBackgroundPainter(new BasicGradientPainter(BasicGradientPainter.BLUE_EXPERIENCE));
065 * </code></pre></p>
066 *
067 * @author rbair
068 */
069 public class BasicGradientPainter extends AbstractGradientPainter {
070 // public static final GradientPaint WHITE_TO_CONTROL_HORZONTAL = new GradientPaint(
071 // new Point2D.Double(0, 0),
072 // Color.WHITE,
073 // new Point2D.Double(1, 0),
074 // new UIColor("control"));
075 // public static final GradientPaint WHITE_TO_CONTROL_VERTICAL = new GradientPaint(
076 // new Point2D.Double(0, 0),
077 // Color.WHITE,
078 // new Point2D.Double(0, 1),
079 // new UIColor("control"));
080 public static final GradientPaint BLUE_EXPERIENCE = new GradientPaint(
081 new Point2D.Double(0, 0),
082 new Color(168, 204, 241),
083 new Point2D.Double(0, 1),
084 new Color(44, 61, 146));
085 public static final GradientPaint MAC_OSX_SELECTED = new GradientPaint(
086 new Point2D.Double(0, 0),
087 new Color(81, 141, 236),
088 new Point2D.Double(0, 1),
089 new Color(36, 96, 192));
090 public static final GradientPaint MAC_OSX = new GradientPaint(
091 new Point2D.Double(0, 0),
092 new Color(167, 210, 250),
093 new Point2D.Double(0, 1),
094 new Color(99, 147, 206));
095 public static final GradientPaint AERITH = new GradientPaint(
096 new Point2D.Double(0, 0),
097 Color.WHITE,
098 new Point2D.Double(0, 1),
099 new Color(64, 110, 161));
100 public static final GradientPaint GRAY = new GradientPaint(
101 new Point2D.Double(0, 0),
102 new Color(226, 226, 226),
103 new Point2D.Double(0, 1),
104 new Color(250, 248, 248));
105 public static final GradientPaint RED_XP = new GradientPaint(
106 new Point2D.Double(0, 0),
107 new Color(236, 81, 81),
108 new Point2D.Double(0, 1),
109 new Color(192, 36, 36));
110 public static final GradientPaint NIGHT_GRAY = new GradientPaint(
111 new Point2D.Double(0, 0),
112 new Color(102, 111, 127),
113 new Point2D.Double(0, 1),
114 new Color(38, 45, 61));
115 public static final GradientPaint NIGHT_GRAY_LIGHT = new GradientPaint(
116 new Point2D.Double(0, 0),
117 new Color(129, 138, 155),
118 new Point2D.Double(0, 1),
119 new Color(58, 66, 82));
120
121
122
123 private GradientPaint paint;
124
125 /**
126 * Creates a new instance of BasicGradientPainter
127 */
128 public BasicGradientPainter() {
129 }
130
131 /**
132 * Creates a new instance of BasicGradientPainter
133 */
134 public BasicGradientPainter(GradientPaint paint) {
135 this.paint = paint;
136 }
137
138 /**
139 * Constructs a simple acyclic <code>BasicGradientPainter</code> object.
140 *
141 * @param x1 x coordinate of the first specified
142 * <code>Point</code> in user space
143 * @param y1 y coordinate of the first specified
144 * <code>Point</code> in user space
145 * @param startColor <code>Color</code> at the first specified
146 * <code>Point</code>
147 * @param x2 x coordinate of the second specified
148 * <code>Point</code> in user space
149 * @param y2 y coordinate of the second specified
150 * <code>Point</code> in user space
151 * @param endColor <code>Color</code> at the second specified
152 * <code>Point</code>
153 * @throws NullPointerException if either one of colors is null
154 */
155 public BasicGradientPainter(float x1,
156 float y1,
157 Color startColor,
158 float x2,
159 float y2,
160 Color endColor) {
161 this.paint = new GradientPaint(x1, y1, startColor, x2, y2, endColor);
162 }
163
164 /**
165 * Constructs a simple acyclic <code>BasicGradientPainter</code> object.
166 *
167 * @param startPoint the first specified <code>Point</code> in user space
168 * @param startColor <code>Color</code> at the first specified
169 * <code>Point</code>
170 * @param endPoint the second specified <code>Point</code> in user space
171 * @param endColor <code>Color</code> at the second specified
172 * <code>Point</code>
173 * @throws NullPointerException if either one of colors or points
174 * is null
175 */
176 public BasicGradientPainter(Point2D startPoint,
177 Color startColor,
178 Point2D endPoint,
179 Color endColor) {
180
181 this.paint = new GradientPaint(startPoint, startColor, endPoint, endColor);
182 }
183
184 /**
185 * Constructs either a cyclic or acyclic <code>BasicGradientPainter</code>
186 * object depending on the <code>boolean</code> parameter.
187 *
188 * @param x1 x coordinate of the first specified
189 * <code>Point</code> in user space
190 * @param y1 y coordinate of the first specified
191 * <code>Point</code> in user space
192 * @param startColor <code>Color</code> at the first specified
193 * <code>Point</code>
194 * @param x2 x coordinate of the second specified
195 * <code>Point</code> in user space
196 * @param y2 y coordinate of the second specified
197 * <code>Point</code> in user space
198 * @param endColor <code>Color</code> at the second specified
199 * <code>Point</code>
200 * @param cyclic <code>true</code> if the gradient pattern should cycle
201 * repeatedly between the two colors; <code>false</code> otherwise
202 */
203 public BasicGradientPainter(float x1,
204 float y1,
205 Color startColor,
206 float x2,
207 float y2,
208 Color endColor,
209 boolean cyclic) {
210 paint = new GradientPaint(x1, y1, startColor, x2, y2, endColor, cyclic);
211 }
212
213 /**
214 * Constructs either a cyclic or acyclic <code>BasicGradientPainter</code>
215 * object depending on the <code>boolean</code> parameter.
216 *
217 * @param startPoint the first specified <code>Point</code>
218 * in user space
219 * @param startColor <code>Color</code> at the first specified
220 * <code>Point</code>
221 * @param endPoint the second specified <code>Point</code>
222 * in user space
223 * @param endColor <code>Color</code> at the second specified
224 * <code>Point</code>
225 * @param cyclic <code>true</code> if the gradient pattern should cycle
226 * repeatedly between the two colors; <code>false</code> otherwise
227 * @throws NullPointerException if either one of colors or points
228 * is null
229 */
230 public BasicGradientPainter(Point2D startPoint,
231 Color startColor,
232 Point2D endPoint,
233 Color endColor,
234 boolean cyclic) {
235 paint = new GradientPaint(startPoint, startColor, endPoint, endColor, cyclic);
236 }
237
238 /**
239 * Set the gradient paint to use. This may be null. If null, nothing is painted
240 *
241 * @param paint the GradientPaint to use
242 */
243 public void setGradientPaint(GradientPaint paint) {
244 GradientPaint old = getGradientPaint();
245 this.paint = paint;
246 firePropertyChange("gradientPaint", old, getGradientPaint());
247 }
248
249 /**
250 * @return the GradientPaint used for painting. This may be null
251 */
252 public GradientPaint getGradientPaint() {
253 return paint;
254 }
255
256 /**
257 * @inheritDoc
258 */
259 protected Paint calculateSizedPaint(int width, int height) {
260 GradientPaint paint = getGradientPaint();
261 if (paint == null) {
262 return null;
263 }
264
265 Point2D startPoint = paint.getPoint1();
266 Point2D endPoint = paint.getPoint2();
267
268 double x1 = isResizeHorizontal() ? startPoint.getX() * width : startPoint.getX();
269 double y1 = isResizeVertical() ? startPoint.getY() * height : startPoint.getY();
270 double x2 = isResizeHorizontal() ? endPoint.getX() * width : endPoint.getX();
271 double y2 = isResizeVertical() ? endPoint.getY() * height : endPoint.getY();
272 startPoint = new Point2D.Double(x1, y1);
273 endPoint = new Point2D.Double(x2, y2);
274
275 return new GradientPaint(
276 startPoint,
277 paint.getColor1(),
278 endPoint,
279 paint.getColor2());
280 }
281
282 //Experimental support for getting colors for gradients out of UIManager
283 //and hiding that fact from users, at least part of the time
284 // private static final class UIColor extends Color {
285 // private Color c = null;
286 // private Object key;
287 //
288 // public UIColor(Object key) {
289 // super(0xffffffff);
290 // this.key = key;
291 // maybeUpdate();
292 // }
293 //
294 // private void maybeUpdate() {
295 // Color newc = UIManager.getColor(key);
296 // if (c != newc) {
297 // c = newc;
298 // }
299 // if (c == null) {
300 // c = Color.WHITE;
301 // }
302 // }
303 //
304 // public float[] getComponents(ColorSpace cspace, float[] compArray) {
305 // maybeUpdate();
306 // return c.getComponents(cspace, compArray);
307 // }
308 //
309 // public float[] getColorComponents(ColorSpace cspace, float[] compArray) {
310 // maybeUpdate();
311 // return c.getColorComponents(cspace, compArray);
312 // }
313 //
314 // public PaintContext createContext(ColorModel cm, Rectangle r, Rectangle2D r2d, AffineTransform xform, RenderingHints hints) {
315 // maybeUpdate();
316 // return c.createContext(cm, r, r2d, xform, hints);
317 // }
318 //
319 // public float[] getRGBComponents(float[] compArray) {
320 // maybeUpdate();
321 // return c.getRGBComponents(compArray);
322 // }
323 //
324 // public float[] getRGBColorComponents(float[] compArray) {
325 // maybeUpdate();
326 // return c.getRGBColorComponents(compArray);
327 // }
328 //
329 // public float[] getColorComponents(float[] compArray) {
330 // maybeUpdate();
331 // return c.getColorComponents(compArray);
332 // }
333 //
334 // public float[] getComponents(float[] compArray) {
335 // maybeUpdate();
336 // return c.getComponents(compArray);
337 // }
338 //
339 // public int getGreen() {
340 // maybeUpdate();
341 // return c.getGreen();
342 // }
343 //
344 // public int getBlue() {
345 // maybeUpdate();
346 // return c.getBlue();
347 // }
348 //
349 // public ColorSpace getColorSpace() {
350 // maybeUpdate();
351 // return c.getColorSpace();
352 // }
353 //
354 // public Color brighter() {
355 // maybeUpdate();
356 // return c.brighter();
357 // }
358 //
359 // public int getAlpha() {
360 // maybeUpdate();
361 // return c.getAlpha();
362 // }
363 //
364 // public int getRed() {
365 // maybeUpdate();
366 // return c.getRed();
367 // }
368 //
369 // public int getRGB() {
370 // maybeUpdate();
371 // return c.getRGB();
372 // }
373 //
374 // public int getTransparency() {
375 // maybeUpdate();
376 // return c.getTransparency();
377 // }
378 //
379 // public Color darker() {
380 // maybeUpdate();
381 // return c.darker();
382 // }
383 // }
384 }