001: /*
002: * @(#)MetalBumps.java 4/15/2007
003: *
004: * Copyright 2002 - 2007 JIDE Software Inc. All rights reserved.
005: */
006:
007: package com.jidesoft.plaf.metal;
008:
009: import javax.swing.*;
010: import javax.swing.plaf.metal.MetalLookAndFeel;
011: import java.awt.*;
012: import java.awt.image.BufferedImage;
013: import java.awt.image.DataBuffer;
014: import java.awt.image.IndexColorModel;
015: import java.util.Enumeration;
016: import java.util.Vector;
017:
018: /**
019: * Implements the bumps used throughout the Metal Look and Feel.
020: *
021: * @author Tom Santos
022: * @author Steve Wilson
023: * @version 1.22 12/03/01
024: */
025:
026: public class MetalBumps implements Icon {
027:
028: protected int xBumps;
029: protected int yBumps;
030: protected Color topColor;
031: protected Color shadowColor;
032: protected Color backColor;
033:
034: protected static Vector buffers = new Vector();
035: protected BumpBuffer buffer;
036:
037: public MetalBumps(Dimension bumpArea) {
038: this (bumpArea.width, bumpArea.height);
039: }
040:
041: public MetalBumps(int width, int height) {
042: this (width, height, MetalLookAndFeel
043: .getPrimaryControlHighlight(), MetalLookAndFeel
044: .getPrimaryControlDarkShadow(), MetalLookAndFeel
045: .getPrimaryControlShadow());
046: }
047:
048: public MetalBumps(int width, int height, Color newTopColor,
049: Color newShadowColor, Color newBackColor) {
050: setBumpArea(width, height);
051: setBumpColors(newTopColor, newShadowColor, newBackColor);
052: }
053:
054: private BumpBuffer getBuffer(GraphicsConfiguration gc,
055: Color aTopColor, Color aShadowColor, Color aBackColor) {
056: if (buffer != null
057: && buffer.hasSameConfiguration(gc, aTopColor,
058: aShadowColor, aBackColor)) {
059: return buffer;
060: }
061: BumpBuffer result = null;
062:
063: Enumeration elements = buffers.elements();
064:
065: while (elements.hasMoreElements()) {
066: BumpBuffer aBuffer = (BumpBuffer) elements.nextElement();
067: if (aBuffer.hasSameConfiguration(gc, aTopColor,
068: aShadowColor, aBackColor)) {
069: result = aBuffer;
070: break;
071: }
072: }
073: if (result == null) {
074: result = new BumpBuffer(gc, topColor, shadowColor,
075: backColor);
076: buffers.addElement(result);
077: }
078: return result;
079: }
080:
081: public void setBumpArea(Dimension bumpArea) {
082: setBumpArea(bumpArea.width, bumpArea.height);
083: }
084:
085: public void setBumpArea(int width, int height) {
086: xBumps = width >> 1;
087: yBumps = height >> 1;
088: }
089:
090: public void setBumpColors(Color newTopColor, Color newShadowColor,
091: Color newBackColor) {
092: topColor = newTopColor;
093: shadowColor = newShadowColor;
094: backColor = newBackColor;
095: }
096:
097: public void paintIcon(Component c, Graphics g, int x, int y) {
098: GraphicsConfiguration gc = (g instanceof Graphics2D) ? (GraphicsConfiguration) ((Graphics2D) g)
099: .getDeviceConfiguration()
100: : null;
101:
102: buffer = getBuffer(gc, topColor, shadowColor, backColor);
103:
104: int bufferWidth = buffer.getImageSize().width;
105: int bufferHeight = buffer.getImageSize().height;
106: int iconWidth = getIconWidth();
107: int iconHeight = getIconHeight();
108: int x2 = x + iconWidth;
109: int y2 = y + iconHeight;
110: int savex = x;
111:
112: while (y < y2) {
113: int h = Math.min(y2 - y, bufferHeight);
114: for (x = savex; x < x2; x += bufferWidth) {
115: int w = Math.min(x2 - x, bufferWidth);
116: g.drawImage(buffer.getImage(), x, y, x + w, y + h, 0,
117: 0, w, h, null);
118: }
119: y += bufferHeight;
120: }
121: }
122:
123: public int getIconWidth() {
124: return xBumps << 1;
125: }
126:
127: public int getIconHeight() {
128: return yBumps << 1;
129: }
130: }
131:
132: class BumpBuffer {
133:
134: static final int IMAGE_SIZE = 64;
135: static Dimension imageSize = new Dimension(IMAGE_SIZE, IMAGE_SIZE);
136:
137: transient Image image;
138: Color topColor;
139: Color shadowColor;
140: Color backColor;
141: private GraphicsConfiguration gc;
142:
143: public BumpBuffer(GraphicsConfiguration gc, Color aTopColor,
144: Color aShadowColor, Color aBackColor) {
145: this .gc = gc;
146: topColor = aTopColor;
147: shadowColor = aShadowColor;
148: backColor = aBackColor;
149: createImage();
150: fillBumpBuffer();
151: }
152:
153: public boolean hasSameConfiguration(GraphicsConfiguration gc,
154: Color aTopColor, Color aShadowColor, Color aBackColor) {
155: if (this .gc != null) {
156: if (!this .gc.equals(gc)) {
157: return false;
158: }
159: } else if (gc != null) {
160: return false;
161: }
162: return topColor.equals(aTopColor)
163: && shadowColor.equals(aShadowColor)
164: && backColor.equals(aBackColor);
165: }
166:
167: /**
168: * Returns the Image containing the bumps appropriate for the passed in
169: * <code>GraphicsConfiguration</code>.
170: */
171: public Image getImage() {
172: return image;
173: }
174:
175: public Dimension getImageSize() {
176: return imageSize;
177: }
178:
179: /**
180: * Paints the bumps into the current image.
181: */
182: private void fillBumpBuffer() {
183: Graphics g = image.getGraphics();
184:
185: g.setColor(backColor);
186: g.fillRect(0, 0, IMAGE_SIZE, IMAGE_SIZE);
187:
188: g.setColor(topColor);
189: for (int x = 0; x < IMAGE_SIZE; x += 4) {
190: for (int y = 0; y < IMAGE_SIZE; y += 4) {
191: g.drawLine(x, y, x, y);
192: g.drawLine(x + 2, y + 2, x + 2, y + 2);
193: }
194: }
195:
196: g.setColor(shadowColor);
197: for (int x = 0; x < IMAGE_SIZE; x += 4) {
198: for (int y = 0; y < IMAGE_SIZE; y += 4) {
199: g.drawLine(x + 1, y + 1, x + 1, y + 1);
200: g.drawLine(x + 3, y + 3, x + 3, y + 3);
201: }
202: }
203: g.dispose();
204: }
205:
206: /**
207: * Creates the image appropriate for the passed in
208: * <code>GraphicsConfiguration</code>, which may be null.
209: */
210: private void createImage() {
211: if (gc != null) {
212: image = gc.createCompatibleImage(IMAGE_SIZE, IMAGE_SIZE);
213: } else {
214: int cmap[] = { backColor.getRGB(), topColor.getRGB(),
215: shadowColor.getRGB() };
216: IndexColorModel icm = new IndexColorModel(8, 3, cmap, 0,
217: false, -1, DataBuffer.TYPE_BYTE);
218: image = new BufferedImage(IMAGE_SIZE, IMAGE_SIZE,
219: BufferedImage.TYPE_BYTE_INDEXED, icm);
220: }
221: }
222: }
|