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
125: : centerPoint.getX();
126: double y1 = isResizeVertical() ? centerPoint.getY() * height
127: : centerPoint.getY();
128: double x2 = isResizeHorizontal() ? focusPoint.getX() * width
129: : focusPoint.getX();
130: double y2 = isResizeVertical() ? focusPoint.getY() * height
131: : focusPoint.getY();
132: centerPoint = new Point2D.Double(x1, y1);
133: focusPoint = new Point2D.Double(x2, y2);
134:
135: float radius = paint.getRadius();
136: Resize r = getResizeRadius();
137: r = r == null ? Resize.BOTH : r;
138: switch (r) {
139: case HORIZONTAL:
140: radius = radius * width;
141: break;
142: case VERTICAL:
143: radius = radius * height;
144: break;
145: case BOTH:
146: radius = radius * Math.min(width, height);
147: break;
148: case NONE:
149: break;
150: default:
151: throw new AssertionError("Cannot happen");
152: }
153:
154: return new RadialGradientPaint(centerPoint, radius, focusPoint,
155: paint.getFractions(), paint.getColors(), paint
156: .getCycleMethod(), paint.getColorSpace(), paint
157: .getTransform());
158: }
159: }
|