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 }