blob: ec6f0300c8af8e70e502df4fd7486736227de4c6 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1998-2003 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package javax.swing.plaf.metal;
27
28import java.awt.*;
29import java.awt.image.*;
30import javax.swing.*;
31import java.io.*;
32import java.util.*;
33
34/**
35 * Implements the bumps used throughout the Metal Look and Feel.
36 *
37 * @author Tom Santos
38 * @author Steve Wilson
39 */
40
41
42class MetalBumps implements Icon {
43
44 static final Color ALPHA = new Color(0, 0, 0, 0);
45
46 protected int xBumps;
47 protected int yBumps;
48 protected Color topColor;
49 protected Color shadowColor;
50 protected Color backColor;
51
52 protected static Vector buffers = new Vector();
53 protected BumpBuffer buffer;
54
55 public MetalBumps( Dimension bumpArea ) {
56 this( bumpArea.width, bumpArea.height );
57 }
58
59 public MetalBumps( int width, int height ) {
60 this(width, height, MetalLookAndFeel.getPrimaryControlHighlight(),
61 MetalLookAndFeel.getPrimaryControlDarkShadow(),
62 MetalLookAndFeel.getPrimaryControlShadow());
63 }
64
65 /**
66 * Creates MetalBumps of the specified size with the specified colors.
67 * If <code>newBackColor</code> is null, the background will be
68 * transparent.
69 */
70 public MetalBumps( int width, int height,
71 Color newTopColor, Color newShadowColor, Color newBackColor ) {
72 setBumpArea( width, height );
73 setBumpColors( newTopColor, newShadowColor, newBackColor );
74 }
75
76 private BumpBuffer getBuffer(GraphicsConfiguration gc, Color aTopColor,
77 Color aShadowColor, Color aBackColor) {
78 if (buffer != null && buffer.hasSameConfiguration(
79 gc, aTopColor, aShadowColor, aBackColor)) {
80 return buffer;
81 }
82 BumpBuffer result = null;
83
84 Enumeration elements = buffers.elements();
85
86 while ( elements.hasMoreElements() ) {
87 BumpBuffer aBuffer = (BumpBuffer)elements.nextElement();
88 if ( aBuffer.hasSameConfiguration(gc, aTopColor, aShadowColor,
89 aBackColor)) {
90 result = aBuffer;
91 break;
92 }
93 }
94 if (result == null) {
95 result = new BumpBuffer(gc, topColor, shadowColor, backColor);
96 buffers.addElement(result);
97 }
98 return result;
99 }
100
101 public void setBumpArea( Dimension bumpArea ) {
102 setBumpArea( bumpArea.width, bumpArea.height );
103 }
104
105 public void setBumpArea( int width, int height ) {
106 xBumps = width / 2;
107 yBumps = height / 2;
108 }
109
110 public void setBumpColors( Color newTopColor, Color newShadowColor, Color newBackColor ) {
111 topColor = newTopColor;
112 shadowColor = newShadowColor;
113 if (newBackColor == null) {
114 backColor = ALPHA;
115 }
116 else {
117 backColor = newBackColor;
118 }
119 }
120
121 public void paintIcon( Component c, Graphics g, int x, int y ) {
122 GraphicsConfiguration gc = (g instanceof Graphics2D) ?
123 (GraphicsConfiguration)((Graphics2D)g).
124 getDeviceConfiguration() : null;
125
126 buffer = getBuffer(gc, topColor, shadowColor, backColor);
127
128 int bufferWidth = buffer.getImageSize().width;
129 int bufferHeight = buffer.getImageSize().height;
130 int iconWidth = getIconWidth();
131 int iconHeight = getIconHeight();
132 int x2 = x + iconWidth;
133 int y2 = y + iconHeight;
134 int savex = x;
135
136 while (y < y2) {
137 int h = Math.min(y2 - y, bufferHeight);
138 for (x = savex; x < x2; x += bufferWidth) {
139 int w = Math.min(x2 - x, bufferWidth);
140 g.drawImage(buffer.getImage(),
141 x, y, x+w, y+h,
142 0, 0, w, h,
143 null);
144 }
145 y += bufferHeight;
146 }
147 }
148
149 public int getIconWidth() {
150 return xBumps * 2;
151 }
152
153 public int getIconHeight() {
154 return yBumps * 2;
155 }
156}
157
158
159class 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,
182 Color aBackColor) {
183 if (this.gc != null) {
184 if (!this.gc.equals(gc)) {
185 return false;
186 }
187 }
188 else if (gc != null) {
189 return false;
190 }
191 return topColor.equals( aTopColor ) &&
192 shadowColor.equals( aShadowColor ) &&
193 backColor.equals( aBackColor );
194 }
195
196 /**
197 * Returns the Image containing the bumps appropriate for the passed in
198 * <code>GraphicsConfiguration</code>.
199 */
200 public Image getImage() {
201 return image;
202 }
203
204 public Dimension getImageSize() {
205 return imageSize;
206 }
207
208 /**
209 * Paints the bumps into the current image.
210 */
211 private void fillBumpBuffer() {
212 Graphics g = image.getGraphics();
213
214 g.setColor( backColor );
215 g.fillRect( 0, 0, IMAGE_SIZE, IMAGE_SIZE );
216
217 g.setColor(topColor);
218 for (int x = 0; x < IMAGE_SIZE; x+=4) {
219 for (int y = 0; y < IMAGE_SIZE; y+=4) {
220 g.drawLine( x, y, x, y );
221 g.drawLine( x+2, y+2, x+2, y+2);
222 }
223 }
224
225 g.setColor(shadowColor);
226 for (int x = 0; x < IMAGE_SIZE; x+=4) {
227 for (int y = 0; y < IMAGE_SIZE; y+=4) {
228 g.drawLine( x+1, y+1, x+1, y+1 );
229 g.drawLine( x+3, y+3, x+3, y+3);
230 }
231 }
232 g.dispose();
233 }
234
235 /**
236 * Creates the image appropriate for the passed in
237 * <code>GraphicsConfiguration</code>, which may be null.
238 */
239 private void createImage() {
240 if (gc != null) {
241 image = gc.createCompatibleImage(IMAGE_SIZE, IMAGE_SIZE,
242 (backColor != MetalBumps.ALPHA) ? Transparency.OPAQUE :
243 Transparency.BITMASK);
244 }
245 else {
246 int cmap[] = { backColor.getRGB(), topColor.getRGB(),
247 shadowColor.getRGB() };
248 IndexColorModel icm = new IndexColorModel(8, 3, cmap, 0, false,
249 (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}