001 /* 002 * $Id: RadialGradientPainter.java,v 1.3 2006/03/26 07:02:08 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.Paint; 025 import java.awt.geom.Point2D; 026 import org.apache.batik.ext.awt.RadialGradientPaint; 027 import org.jdesktop.swingx.util.Resize; 028 029 /** 030 * <p>A Gradient based painter used for painting "multi-stop" radial gradients. These are 031 * gradients that imploys more than 2 colors, where each color is defined along 032 * with a float value between 0 and 1 indicating at what point along the gradient 033 * the new color is used.</p> 034 * 035 * <p>As with BasicGradienPainter and mentioned in AbstractGradientPainter, the values 036 * given to the centerPoint, radius, and focusPoint of the RadialGradientPainter are crucial. They 037 * represent what distance from the origin the gradient should begin and end at, 038 * depending on the size of the component. That is, they must be specified as values between 039 * 0 and 1, where 0 means "all the way on the left/top" and 1 means "all the way on the 040 * right/bottom".</p> 041 * 042 * <p>In addition, the resize behavior of the radius is specified in the resizeRadius 043 * property. If HORIZONTAL, then the width of the component is used to calculate 044 * the new radius. If VERTICAL then the height of the component is used. If BOTH, 045 * then the Math.min(width, height) is used. If NONE, then no resize occurs for 046 * the radius.</p> 047 * 048 * <p><strong>NOTE: RadialGradientPainter relies on LinearGradientPaint, which is 049 * included in the optional jar MultipleGradientPaint.jar. Be sure to have this 050 * jar on your classpath if you use this class</strong></p> 051 * 052 * @author rbair 053 */ 054 public class RadialGradientPainter extends AbstractGradientPainter { 055 private RadialGradientPaint paint; 056 private Resize resizeRadius = Resize.BOTH; 057 058 /** Creates a new instance of RadialGradientPainter */ 059 public RadialGradientPainter() { 060 } 061 062 /** 063 * Creates a new instance of RadialGradientPainter 064 * with the given RadialGradientPaint 065 * 066 * @param paint the RadialGradientPaint to use 067 */ 068 public RadialGradientPainter(RadialGradientPaint paint) { 069 this.paint = paint; 070 } 071 072 /** 073 * Set the gradient paint to use. This may be null. If null, nothing is painted 074 * 075 * @param paint the RadialGradientPaint to use 076 */ 077 public void setGradientPaint(RadialGradientPaint paint) { 078 RadialGradientPaint old = getGradientPaint(); 079 this.paint = paint; 080 firePropertyChange("gradientPaint", old, getGradientPaint()); 081 } 082 083 /** 084 * @return the RadialGradientPaint used for painting. This may be null 085 */ 086 public RadialGradientPaint getGradientPaint() { 087 return paint; 088 } 089 090 /** 091 * Specifies the resize behavior for the radius of the RadialGradientPaint. 092 * If HORIZONTAL, then the width of the component is used to calculate 093 * the new radius. If VERTICAL then the height of the component is used. If BOTH, 094 * then the Math.min(width, height) is used. If NONE, then no resize occurs for 095 * the radius. 096 * 097 * @param r the Resize behavior for the radius 098 */ 099 public void setResizeRadius(Resize r) { 100 Resize old = getResizeRadius(); 101 this.resizeRadius = r; 102 firePropertyChange("resizeRadius", old, getResizeRadius()); 103 } 104 105 /** 106 * @return the resize behavior for the radius 107 */ 108 public Resize getResizeRadius() { 109 return resizeRadius; 110 } 111 112 /** 113 * @inheritDoc 114 */ 115 protected Paint calculateSizedPaint(int width, int height) { 116 RadialGradientPaint paint = getGradientPaint(); 117 if (paint == null) { 118 return null; 119 } 120 121 Point2D centerPoint = paint.getCenterPoint(); 122 Point2D focusPoint = paint.getFocusPoint(); 123 124 double x1 = isResizeHorizontal() ? centerPoint.getX() * width : centerPoint.getX(); 125 double y1 = isResizeVertical() ? centerPoint.getY() * height : centerPoint.getY(); 126 double x2 = isResizeHorizontal() ? focusPoint.getX() * width : focusPoint.getX(); 127 double y2 = isResizeVertical() ? focusPoint.getY() * height : focusPoint.getY(); 128 centerPoint = new Point2D.Double(x1, y1); 129 focusPoint = new Point2D.Double(x2, y2); 130 131 float radius = paint.getRadius(); 132 Resize r = getResizeRadius(); 133 r = r == null ? Resize.BOTH : r; 134 switch (r) { 135 case HORIZONTAL: 136 radius = radius * width; 137 break; 138 case VERTICAL: 139 radius = radius * height; 140 break; 141 case BOTH: 142 radius = radius * Math.min(width, height); 143 break; 144 case NONE: 145 break; 146 default: 147 throw new AssertionError("Cannot happen"); 148 } 149 150 return new RadialGradientPaint( 151 centerPoint, 152 radius, 153 focusPoint, 154 paint.getFractions(), 155 paint.getColors(), 156 paint.getCycleMethod(), 157 paint.getColorSpace(), 158 paint.getTransform()); 159 } 160 }