001 /*
002 * Copyright 1998-2003 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025
026 package javax.swing.plaf.metal;
027
028 import java.awt.*;
029 import java.awt.image.*;
030 import javax.swing.*;
031 import java.io.*;
032 import java.util.*;
033
034 /**
035 * Implements the bumps used throughout the Metal Look and Feel.
036 *
037 * @version 1.32 05/05/07
038 * @author Tom Santos
039 * @author Steve Wilson
040 */
041
042 class MetalBumps implements Icon {
043
044 static final Color ALPHA = new Color(0, 0, 0, 0);
045
046 protected int xBumps;
047 protected int yBumps;
048 protected Color topColor;
049 protected Color shadowColor;
050 protected Color backColor;
051
052 protected static Vector buffers = new Vector();
053 protected BumpBuffer buffer;
054
055 public MetalBumps(Dimension bumpArea) {
056 this (bumpArea.width, bumpArea.height);
057 }
058
059 public MetalBumps(int width, int height) {
060 this (width, height, MetalLookAndFeel
061 .getPrimaryControlHighlight(), MetalLookAndFeel
062 .getPrimaryControlDarkShadow(), MetalLookAndFeel
063 .getPrimaryControlShadow());
064 }
065
066 /**
067 * Creates MetalBumps of the specified size with the specified colors.
068 * If <code>newBackColor</code> is null, the background will be
069 * transparent.
070 */
071 public MetalBumps(int width, int height, Color newTopColor,
072 Color newShadowColor, Color newBackColor) {
073 setBumpArea(width, height);
074 setBumpColors(newTopColor, newShadowColor, newBackColor);
075 }
076
077 private BumpBuffer getBuffer(GraphicsConfiguration gc,
078 Color aTopColor, Color aShadowColor, Color aBackColor) {
079 if (buffer != null
080 && buffer.hasSameConfiguration(gc, aTopColor,
081 aShadowColor, aBackColor)) {
082 return buffer;
083 }
084 BumpBuffer result = null;
085
086 Enumeration elements = buffers.elements();
087
088 while (elements.hasMoreElements()) {
089 BumpBuffer aBuffer = (BumpBuffer) elements.nextElement();
090 if (aBuffer.hasSameConfiguration(gc, aTopColor,
091 aShadowColor, aBackColor)) {
092 result = aBuffer;
093 break;
094 }
095 }
096 if (result == null) {
097 result = new BumpBuffer(gc, topColor, shadowColor,
098 backColor);
099 buffers.addElement(result);
100 }
101 return result;
102 }
103
104 public void setBumpArea(Dimension bumpArea) {
105 setBumpArea(bumpArea.width, bumpArea.height);
106 }
107
108 public void setBumpArea(int width, int height) {
109 xBumps = width / 2;
110 yBumps = height / 2;
111 }
112
113 public void setBumpColors(Color newTopColor, Color newShadowColor,
114 Color newBackColor) {
115 topColor = newTopColor;
116 shadowColor = newShadowColor;
117 if (newBackColor == null) {
118 backColor = ALPHA;
119 } else {
120 backColor = newBackColor;
121 }
122 }
123
124 public void paintIcon(Component c, Graphics g, int x, int y) {
125 GraphicsConfiguration gc = (g instanceof Graphics2D) ? (GraphicsConfiguration) ((Graphics2D) g)
126 .getDeviceConfiguration()
127 : null;
128
129 buffer = getBuffer(gc, topColor, shadowColor, backColor);
130
131 int bufferWidth = buffer.getImageSize().width;
132 int bufferHeight = buffer.getImageSize().height;
133 int iconWidth = getIconWidth();
134 int iconHeight = getIconHeight();
135 int x2 = x + iconWidth;
136 int y2 = y + iconHeight;
137 int savex = x;
138
139 while (y < y2) {
140 int h = Math.min(y2 - y, bufferHeight);
141 for (x = savex; x < x2; x += bufferWidth) {
142 int w = Math.min(x2 - x, bufferWidth);
143 g.drawImage(buffer.getImage(), x, y, x + w, y + h, 0,
144 0, w, h, null);
145 }
146 y += bufferHeight;
147 }
148 }
149
150 public int getIconWidth() {
151 return xBumps * 2;
152 }
153
154 public int getIconHeight() {
155 return yBumps * 2;
156 }
157 }
158
159 class BumpBuffer {
160
161 static final int IMAGE_SIZE = 64;
162 static Dimension imageSize = new Dimension(IMAGE_SIZE, IMAGE_SIZE);
163
164 transient Image image;
165 Color topColor;
166 Color shadowColor;
167 Color backColor;
168 private GraphicsConfiguration gc;
169
170 public BumpBuffer(GraphicsConfiguration gc, Color aTopColor,
171 Color aShadowColor, Color aBackColor) {
172 this .gc = gc;
173 topColor = aTopColor;
174 shadowColor = aShadowColor;
175 backColor = aBackColor;
176 createImage();
177 fillBumpBuffer();
178 }
179
180 public boolean hasSameConfiguration(GraphicsConfiguration gc,
181 Color aTopColor, Color aShadowColor, Color aBackColor) {
182 if (this .gc != null) {
183 if (!this .gc.equals(gc)) {
184 return false;
185 }
186 } else if (gc != null) {
187 return false;
188 }
189 return topColor.equals(aTopColor)
190 && shadowColor.equals(aShadowColor)
191 && backColor.equals(aBackColor);
192 }
193
194 /**
195 * Returns the Image containing the bumps appropriate for the passed in
196 * <code>GraphicsConfiguration</code>.
197 */
198 public Image getImage() {
199 return image;
200 }
201
202 public Dimension getImageSize() {
203 return imageSize;
204 }
205
206 /**
207 * Paints the bumps into the current image.
208 */
209 private void fillBumpBuffer() {
210 Graphics g = image.getGraphics();
211
212 g.setColor(backColor);
213 g.fillRect(0, 0, IMAGE_SIZE, IMAGE_SIZE);
214
215 g.setColor(topColor);
216 for (int x = 0; x < IMAGE_SIZE; x += 4) {
217 for (int y = 0; y < IMAGE_SIZE; y += 4) {
218 g.drawLine(x, y, x, y);
219 g.drawLine(x + 2, y + 2, x + 2, y + 2);
220 }
221 }
222
223 g.setColor(shadowColor);
224 for (int x = 0; x < IMAGE_SIZE; x += 4) {
225 for (int y = 0; y < IMAGE_SIZE; y += 4) {
226 g.drawLine(x + 1, y + 1, x + 1, y + 1);
227 g.drawLine(x + 3, y + 3, x + 3, y + 3);
228 }
229 }
230 g.dispose();
231 }
232
233 /**
234 * Creates the image appropriate for the passed in
235 * <code>GraphicsConfiguration</code>, which may be null.
236 */
237 private void createImage() {
238 if (gc != null) {
239 image = gc
240 .createCompatibleImage(
241 IMAGE_SIZE,
242 IMAGE_SIZE,
243 (backColor != MetalBumps.ALPHA) ? Transparency.OPAQUE
244 : Transparency.BITMASK);
245 } else {
246 int cmap[] = { backColor.getRGB(), topColor.getRGB(),
247 shadowColor.getRGB() };
248 IndexColorModel icm = new IndexColorModel(8, 3, cmap, 0,
249 false, (backColor == MetalBumps.ALPHA) ? 0 : -1,
250 DataBuffer.TYPE_BYTE);
251 image = new BufferedImage(IMAGE_SIZE, IMAGE_SIZE,
252 BufferedImage.TYPE_BYTE_INDEXED, icm);
253 }
254 }
255 }
|