001: /*
002: * Copyright (C) 2004 NNL Technology AB
003: * Visit www.infonode.net for information about InfoNode(R)
004: * products and how to contact NNL Technology AB.
005: *
006: * This program is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU General Public License
008: * as published by the Free Software Foundation; either version 2
009: * of the License, or (at your option) any later version.
010: *
011: * This program is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: * GNU General Public License for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * along with this program; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
019: * MA 02111-1307, USA.
020: */
021:
022: // $Id: GradientComponentPainter.java,v 1.11 2005/12/04 13:46:03 jesper Exp $
023: package net.infonode.gui.componentpainter;
024:
025: import net.infonode.gui.colorprovider.ColorProvider;
026: import net.infonode.gui.colorprovider.FixedColorProvider;
027: import net.infonode.util.ColorUtil;
028: import net.infonode.util.Direction;
029: import net.infonode.util.ImageUtils;
030:
031: import java.awt.*;
032: import java.awt.image.MemoryImageSource;
033: import java.io.Serializable;
034: import java.lang.ref.SoftReference;
035:
036: /**
037: * A painter that paints an gradient area specified by four corner colors.
038: *
039: * @author $Author: jesper $
040: * @version $Revision: 1.11 $
041: */
042: public class GradientComponentPainter extends AbstractComponentPainter
043: implements Serializable {
044: private static final long serialVersionUID = 1;
045:
046: private ColorProvider[] colorProviders = new ColorProvider[4];
047: private transient Color[] colors;
048: private int size = 128;
049: private transient SoftReference[] images;
050: private transient boolean hasAlpha;
051:
052: /**
053: * Constructor.
054: *
055: * @param topLeftColor the top left corner color
056: * @param topRightColor the top right corner color
057: * @param bottomLeftColor the bottom left corner color
058: * @param bottomRightColor the bottom right corner color
059: */
060: public GradientComponentPainter(Color topLeftColor,
061: Color topRightColor, Color bottomLeftColor,
062: Color bottomRightColor) {
063: this (new FixedColorProvider(topLeftColor),
064: new FixedColorProvider(topRightColor),
065: new FixedColorProvider(bottomLeftColor),
066: new FixedColorProvider(bottomRightColor));
067: }
068:
069: /**
070: * Constructor.
071: *
072: * @param topLeftColor the top left corner color provider
073: * @param topRightColor the top right corner color provider
074: * @param bottomLeftColor the bottom left corner color provider
075: * @param bottomRightColor the bottom right corner color provider
076: */
077: public GradientComponentPainter(ColorProvider topLeftColor,
078: ColorProvider topRightColor, ColorProvider bottomLeftColor,
079: ColorProvider bottomRightColor) {
080: colorProviders[0] = topLeftColor;
081: colorProviders[1] = topRightColor;
082: colorProviders[2] = bottomLeftColor;
083: colorProviders[3] = bottomRightColor;
084: }
085:
086: public void paint(Component component, Graphics g, int x, int y,
087: int width, int height, Direction direction,
088: boolean horizontalFlip, boolean verticalFlip) {
089: updateColors(component);
090:
091: if (colors[0] != null && colors[1] != null && colors[2] != null
092: && colors[3] != null) {
093: if (colors[0].equals(colors[2])
094: && colors[1].equals(colors[3])
095: && colors[0].equals(colors[1])) {
096: g.setColor(colors[0]);
097: g.fillRect(x, y, width, height);
098: } else {
099: int imageIndex = direction.getValue()
100: + (horizontalFlip ? 4 : 0)
101: + (verticalFlip ? 8 : 0);
102: SoftReference ref = images[imageIndex];
103: Image image = ref == null ? null : (Image) ref.get();
104:
105: if (image == null) {
106: image = createGradientImage(fixColors(direction,
107: horizontalFlip, verticalFlip));
108: images[imageIndex] = new SoftReference(image);
109: }
110:
111: g.drawImage(image, x, y, width, height, null);
112: }
113: }
114:
115: }
116:
117: /*
118: * private Image createLineImage(Direction direction, Color c1, Color c2) {
119: * BufferedImage image = new BufferedImage(direction.isHorizontal() ? size : 1,
120: * direction.isHorizontal() ? 1 : size, BufferedImage.TYPE_INT_RGB);
121: *
122: * int dx = direction == Direction.RIGHT ? 1 : direction == Direction.LEFT ? -1 :
123: * 0; int dy = direction == Direction.DOWN ? 1 : direction == Direction.UP ? -1 :
124: * 0;
125: *
126: * int x = direction == Direction.LEFT ? size - 1 : 0; int y = direction ==
127: * Direction.UP ? size - 1 : 0;
128: *
129: * for (int i = 0; i < size; i++) { Color c = ColorUtil.blend(c1, c2, (double) i /
130: * size); image.setRGB(x, y, c.getRGB()); x += dx; y += dy; }
131: *
132: * return image; }
133: */
134: /* private static void drawLines(Direction direction, Graphics g, int x, int y, int width, int height, Color c1, Color c2) {
135: int size = direction.isHorizontal() ? width : height;
136: Int4 c = ImageUtils.toInt4(c1);
137: Int4 dc = ImageUtils.toInt4(c2).sub(ImageUtils.toInt4(c1)).div(size);
138:
139: for (int i = 0; i < size; i++) {
140: g.setColor(ImageUtils.toColor(c));
141:
142: if (direction == Direction.RIGHT)
143: g.drawLine(x + i, y, x + i, y + height - 1);
144: else if (direction == Direction.DOWN)
145: g.drawLine(x, y + i, x + width - 1, y + i);
146: else if (direction == Direction.LEFT)
147: g.drawLine(x + width - 1 - i, y, x + width - 1 - i, y + height - 1);
148: else
149: g.drawLine(x, y + height - 1 - i, x + width - 1, y + height - 1 - i);
150:
151: c.add(dc);
152: }
153: }*/
154:
155: private Color[] fixColors(Direction direction,
156: boolean horizontalFlip, boolean verticalFlip) {
157: Color[] c = new Color[4];
158: Color t;
159:
160: if (horizontalFlip) {
161: c[0] = colors[1];
162: c[1] = colors[0];
163: c[2] = colors[3];
164: c[3] = colors[2];
165: } else {
166: c[0] = colors[0];
167: c[1] = colors[1];
168: c[2] = colors[2];
169: c[3] = colors[3];
170: }
171:
172: if (verticalFlip) {
173: t = c[2];
174: c[2] = c[0];
175: c[0] = t;
176:
177: t = c[3];
178: c[3] = c[1];
179: c[1] = t;
180: }
181:
182: if (direction == Direction.RIGHT) {
183: return c;
184: } else if (direction == Direction.DOWN) {
185: t = c[0];
186: c[0] = c[2];
187: c[2] = c[3];
188: c[3] = c[1];
189: c[1] = t;
190: } else if (direction == Direction.LEFT) {
191: t = c[0];
192: c[0] = c[3];
193: c[3] = t;
194:
195: t = c[1];
196: c[1] = c[2];
197: c[2] = t;
198: } else if (direction == Direction.UP) {
199: t = c[0];
200: c[0] = c[1];
201: c[1] = c[3];
202: c[3] = c[2];
203: c[2] = t;
204: }
205:
206: return c;
207: }
208:
209: private Image createGradientImage(Color[] colors) {
210: return Toolkit.getDefaultToolkit().createImage(
211: new MemoryImageSource(size, size, ImageUtils
212: .createGradientPixels(colors, size, size), 0,
213: size));
214: }
215:
216: private void updateColors(Component component) {
217: if (images == null) {
218: images = new SoftReference[16];
219: }
220:
221: if (colors == null)
222: colors = new Color[4];
223:
224: for (int i = 0; i < colors.length; i++) {
225: Color c = colorProviders[i].getColor(component);
226:
227: if (c != null && !c.equals(colors[i])) {
228: for (int j = 0; j < images.length; j++) {
229: images[j] = null;
230: }
231: }
232:
233: colors[i] = c;
234: hasAlpha |= c != null && c.getAlpha() != 255;
235: }
236: }
237:
238: public boolean isOpaque(Component component) {
239: updateColors(component);
240: return !hasAlpha;
241: }
242:
243: public Color getColor(Component component) {
244: updateColors(component);
245: return ColorUtil.blend(ColorUtil.blend(colors[0], colors[1],
246: 0.5), ColorUtil.blend(colors[2], colors[3], 0.5), 0.5);
247: }
248: }
|