001: /*
002: * BumpyGradientBumps.java
003: *
004: * Copyright (C) 2002, 2003, 2004, 2005, 2006 Takis Diakoumis
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 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, MA 02111-1307, USA.
019: *
020: */
021:
022: package org.underworldlabs.swing.plaf.bumpygradient;
023:
024: import java.awt.Color;
025: import java.awt.Component;
026: import java.awt.Dimension;
027: import java.awt.Graphics;
028: import java.awt.Graphics2D;
029: import java.awt.GraphicsConfiguration;
030: import java.awt.Image;
031: import java.awt.image.BufferedImage;
032: import java.awt.image.DataBuffer;
033: import java.awt.image.IndexColorModel;
034:
035: import java.util.Enumeration;
036: import java.util.Vector;
037:
038: import javax.swing.Icon;
039:
040: /* ----------------------------------------------------------
041: * CVS NOTE: Changes to the CVS repository prior to the
042: * release of version 3.0.0beta1 has meant a
043: * resetting of CVS revision numbers.
044: * ----------------------------------------------------------
045: */
046:
047: /**
048: *
049: * @author Takis Diakoumis
050: * @version $Revision: 1.4 $
051: * @date $Date: 2006/05/14 06:56:07 $
052: */
053: final class BumpyGradientBumps implements Icon {
054:
055: protected int xBumps;
056: protected int yBumps;
057: protected Color topColor;
058: protected Color shadowColor;
059: protected Color backColor;
060:
061: protected static Vector buffers = new Vector();
062: protected BumpBuffer buffer;
063:
064: public BumpyGradientBumps(Dimension bumpArea) {
065: this (bumpArea.width, bumpArea.height);
066: }
067:
068: public BumpyGradientBumps(int width, int height) {
069: this (width, height, BumpyGradientLookAndFeel
070: .getPrimaryControlHighlight(), BumpyGradientLookAndFeel
071: .getPrimaryControlDarkShadow(),
072: BumpyGradientLookAndFeel.getPrimaryControlShadow());
073: }
074:
075: public BumpyGradientBumps(int width, int height, Color newTopColor,
076: Color newShadowColor, Color newBackColor) {
077: setBumpArea(width, height);
078: setBumpColors(newTopColor, newShadowColor, newBackColor);
079: }
080:
081: private BumpBuffer getBuffer(GraphicsConfiguration gc,
082: Color aTopColor, Color aShadowColor, Color aBackColor) {
083: if (buffer != null
084: && buffer.hasSameConfiguration(gc, aTopColor,
085: aShadowColor, aBackColor)) {
086: return buffer;
087: }
088: BumpBuffer result = null;
089: Enumeration elements = buffers.elements();
090: while (elements.hasMoreElements()) {
091: BumpBuffer aBuffer = (BumpBuffer) elements.nextElement();
092: if (aBuffer.hasSameConfiguration(gc, aTopColor,
093: aShadowColor, aBackColor)) {
094: result = aBuffer;
095: break;
096: }
097: }
098: if (result == null) {
099: result = new BumpBuffer(gc, topColor, shadowColor,
100: backColor);
101: buffers.addElement(result);
102: }
103: return result;
104: }
105:
106: public void setBumpArea(Dimension bumpArea) {
107: setBumpArea(bumpArea.width, bumpArea.height);
108: }
109:
110: public void setBumpArea(int width, int height) {
111: xBumps = width / 2;
112: yBumps = height / 2;
113: }
114:
115: public void setBumpColors(Color newTopColor, Color newShadowColor,
116: Color newBackColor) {
117: topColor = newTopColor;
118: shadowColor = newShadowColor;
119: backColor = newBackColor;
120: }
121:
122: public void paintIcon(Component c, Graphics g, int x, int y) {
123: GraphicsConfiguration gc = (g instanceof Graphics2D) ? (GraphicsConfiguration) ((Graphics2D) g)
124: .getDeviceConfiguration()
125: : null;
126:
127: buffer = getBuffer(gc, topColor, shadowColor, backColor);
128:
129: int bufferWidth = buffer.getImageSize().width;
130: int bufferHeight = buffer.getImageSize().height;
131: int iconWidth = getIconWidth();
132: int iconHeight = getIconHeight();
133: int x2 = x + iconWidth;
134: int y2 = y + iconHeight;
135: int savex = x;
136:
137: while (y < y2) {
138: int h = Math.min(y2 - y, bufferHeight);
139: for (x = savex; x < x2; x += bufferWidth) {
140: int w = Math.min(x2 - x, bufferWidth);
141: g.drawImage(buffer.getImage(), x, y, x + w, y + h, 0,
142: 0, w, h, null);
143: }
144: y += bufferHeight;
145: }
146: }
147:
148: public int getIconWidth() {
149: return xBumps * 2;
150: }
151:
152: public int getIconHeight() {
153: return yBumps * 2;
154: }
155: }
156:
157: final class BumpBuffer {
158:
159: static final int IMAGE_SIZE = 64;
160: static Dimension imageSize = new Dimension(IMAGE_SIZE, IMAGE_SIZE);
161:
162: transient Image image;
163: Color topColor;
164: Color shadowColor;
165: Color backColor;
166: private GraphicsConfiguration gc;
167:
168: public BumpBuffer(GraphicsConfiguration gc, Color aTopColor,
169: Color aShadowColor, Color aBackColor) {
170: this .gc = gc;
171: topColor = aTopColor;
172: shadowColor = aShadowColor;
173: backColor = aBackColor;
174: createImage();
175: fillBumpBuffer();
176: }
177:
178: public boolean hasSameConfiguration(GraphicsConfiguration aGC,
179: Color aTopColor, Color aShadowColor, Color aBackColor) {
180: if (this .gc != null) {
181: if (!this .gc.equals(aGC)) {
182: return false;
183: }
184: } else if (aGC != null) {
185: return false;
186: }
187: return topColor.equals(aTopColor)
188: && shadowColor.equals(aShadowColor)
189: && backColor.equals(aBackColor);
190: }
191:
192: /**
193: * Returns the Image containing the bumps appropriate for the passed in
194: * <code>GraphicsConfiguration</code>.
195: */
196: public Image getImage() {
197: return image;
198: }
199:
200: public Dimension getImageSize() {
201: return imageSize;
202: }
203:
204: /**
205: * Paints the bumps into the current image.
206: */
207: private void fillBumpBuffer() {
208: Graphics g = image.getGraphics();
209:
210: g.setColor(backColor);
211: g.fillRect(0, 0, IMAGE_SIZE, IMAGE_SIZE);
212:
213: g.setColor(topColor);
214: for (int x = 0; x < IMAGE_SIZE; x += 4) {
215: for (int y = 0; y < IMAGE_SIZE; y += 4) {
216: g.drawLine(x, y, x, y);
217: g.drawLine(x + 2, y + 2, x + 2, y + 2);
218: }
219: }
220:
221: g.setColor(shadowColor);
222: for (int x = 0; x < IMAGE_SIZE; x += 4) {
223: for (int y = 0; y < IMAGE_SIZE; y += 4) {
224: g.drawLine(x + 1, y + 1, x + 1, y + 1);
225: g.drawLine(x + 3, y + 3, x + 3, y + 3);
226: }
227: }
228: g.dispose();
229: }
230:
231: /**
232: * Creates the image appropriate for the passed in
233: * <code>GraphicsConfiguration</code>, which may be null.
234: */
235: private void createImage() {
236: if (gc != null) {
237: image = gc.createCompatibleImage(IMAGE_SIZE, IMAGE_SIZE);
238: } else {
239: int cmap[] = { backColor.getRGB(), topColor.getRGB(),
240: shadowColor.getRGB() };
241: IndexColorModel icm = new IndexColorModel(8, 3, cmap, 0,
242: false, -1, DataBuffer.TYPE_BYTE);
243: image = new BufferedImage(IMAGE_SIZE, IMAGE_SIZE,
244: BufferedImage.TYPE_BYTE_INDEXED, icm);
245: }
246: }
247: }
|