001 /*
002 * Copyright 1997-2005 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 package javax.swing.plaf.basic;
026
027 import javax.swing.*;
028 import java.awt.Component;
029 import java.awt.Color;
030 import java.awt.Dimension;
031 import java.awt.Font;
032 import java.awt.FontMetrics;
033 import java.awt.Graphics;
034 import java.awt.Insets;
035 import java.awt.Rectangle;
036 import java.awt.event.KeyEvent;
037 import sun.swing.SwingUtilities2;
038
039 /*
040 * @version 1.44 02/11/99
041 * @author Hans Muller
042 */
043
044 public class BasicGraphicsUtils {
045
046 private static final Insets GROOVE_INSETS = new Insets(2, 2, 2, 2);
047 private static final Insets ETCHED_INSETS = new Insets(2, 2, 2, 2);
048
049 public static void drawEtchedRect(Graphics g, int x, int y, int w,
050 int h, Color shadow, Color darkShadow, Color highlight,
051 Color lightHighlight) {
052 Color oldColor = g.getColor(); // Make no net change to g
053 g.translate(x, y);
054
055 g.setColor(shadow);
056 g.drawLine(0, 0, w - 1, 0); // outer border, top
057 g.drawLine(0, 1, 0, h - 2); // outer border, left
058
059 g.setColor(darkShadow);
060 g.drawLine(1, 1, w - 3, 1); // inner border, top
061 g.drawLine(1, 2, 1, h - 3); // inner border, left
062
063 g.setColor(lightHighlight);
064 g.drawLine(w - 1, 0, w - 1, h - 1); // outer border, bottom
065 g.drawLine(0, h - 1, w - 1, h - 1); // outer border, right
066
067 g.setColor(highlight);
068 g.drawLine(w - 2, 1, w - 2, h - 3); // inner border, right
069 g.drawLine(1, h - 2, w - 2, h - 2); // inner border, bottom
070
071 g.translate(-x, -y);
072 g.setColor(oldColor);
073 }
074
075 /**
076 * Returns the amount of space taken up by a border drawn by
077 * <code>drawEtchedRect()</code>
078 *
079 * @return the inset of an etched rect
080 */
081 public static Insets getEtchedInsets() {
082 return ETCHED_INSETS;
083 }
084
085 public static void drawGroove(Graphics g, int x, int y, int w,
086 int h, Color shadow, Color highlight) {
087 Color oldColor = g.getColor(); // Make no net change to g
088 g.translate(x, y);
089
090 g.setColor(shadow);
091 g.drawRect(0, 0, w - 2, h - 2);
092
093 g.setColor(highlight);
094 g.drawLine(1, h - 3, 1, 1);
095 g.drawLine(1, 1, w - 3, 1);
096
097 g.drawLine(0, h - 1, w - 1, h - 1);
098 g.drawLine(w - 1, h - 1, w - 1, 0);
099
100 g.translate(-x, -y);
101 g.setColor(oldColor);
102 }
103
104 /**
105 * Returns the amount of space taken up by a border drawn by
106 * <code>drawGroove()</code>
107 *
108 * @return the inset of a groove border
109 */
110 public static Insets getGrooveInsets() {
111 return GROOVE_INSETS;
112 }
113
114 public static void drawBezel(Graphics g, int x, int y, int w,
115 int h, boolean isPressed, boolean isDefault, Color shadow,
116 Color darkShadow, Color highlight, Color lightHighlight) {
117 Color oldColor = g.getColor(); // Make no net change to g
118 g.translate(x, y);
119
120 if (isPressed && isDefault) {
121 g.setColor(darkShadow);
122 g.drawRect(0, 0, w - 1, h - 1);
123 g.setColor(shadow);
124 g.drawRect(1, 1, w - 3, h - 3);
125 } else if (isPressed) {
126 drawLoweredBezel(g, x, y, w, h, shadow, darkShadow,
127 highlight, lightHighlight);
128 } else if (isDefault) {
129 g.setColor(darkShadow);
130 g.drawRect(0, 0, w - 1, h - 1);
131
132 g.setColor(lightHighlight);
133 g.drawLine(1, 1, 1, h - 3);
134 g.drawLine(2, 1, w - 3, 1);
135
136 g.setColor(highlight);
137 g.drawLine(2, 2, 2, h - 4);
138 g.drawLine(3, 2, w - 4, 2);
139
140 g.setColor(shadow);
141 g.drawLine(2, h - 3, w - 3, h - 3);
142 g.drawLine(w - 3, 2, w - 3, h - 4);
143
144 g.setColor(darkShadow);
145 g.drawLine(1, h - 2, w - 2, h - 2);
146 g.drawLine(w - 2, h - 2, w - 2, 1);
147 } else {
148 g.setColor(lightHighlight);
149 g.drawLine(0, 0, 0, h - 1);
150 g.drawLine(1, 0, w - 2, 0);
151
152 g.setColor(highlight);
153 g.drawLine(1, 1, 1, h - 3);
154 g.drawLine(2, 1, w - 3, 1);
155
156 g.setColor(shadow);
157 g.drawLine(1, h - 2, w - 2, h - 2);
158 g.drawLine(w - 2, 1, w - 2, h - 3);
159
160 g.setColor(darkShadow);
161 g.drawLine(0, h - 1, w - 1, h - 1);
162 g.drawLine(w - 1, h - 1, w - 1, 0);
163 }
164 g.translate(-x, -y);
165 g.setColor(oldColor);
166 }
167
168 public static void drawLoweredBezel(Graphics g, int x, int y,
169 int w, int h, Color shadow, Color darkShadow,
170 Color highlight, Color lightHighlight) {
171 g.setColor(darkShadow);
172 g.drawLine(0, 0, 0, h - 1);
173 g.drawLine(1, 0, w - 2, 0);
174
175 g.setColor(shadow);
176 g.drawLine(1, 1, 1, h - 2);
177 g.drawLine(1, 1, w - 3, 1);
178
179 g.setColor(lightHighlight);
180 g.drawLine(0, h - 1, w - 1, h - 1);
181 g.drawLine(w - 1, h - 1, w - 1, 0);
182
183 g.setColor(highlight);
184 g.drawLine(1, h - 2, w - 2, h - 2);
185 g.drawLine(w - 2, h - 2, w - 2, 1);
186 }
187
188 /** Draw a string with the graphics <code>g</code> at location (x,y)
189 * just like <code>g.drawString</code> would.
190 * The first occurrence of <code>underlineChar</code>
191 * in text will be underlined. The matching algorithm is
192 * not case sensitive.
193 */
194 public static void drawString(Graphics g, String text,
195 int underlinedChar, int x, int y) {
196 int index = -1;
197
198 if (underlinedChar != '\0') {
199 char uc = Character.toUpperCase((char) underlinedChar);
200 char lc = Character.toLowerCase((char) underlinedChar);
201 int uci = text.indexOf(uc);
202 int lci = text.indexOf(lc);
203
204 if (uci == -1) {
205 index = lci;
206 } else if (lci == -1) {
207 index = uci;
208 } else {
209 index = (lci < uci) ? lci : uci;
210 }
211 }
212 drawStringUnderlineCharAt(g, text, index, x, y);
213 }
214
215 /**
216 * Draw a string with the graphics <code>g</code> at location
217 * (<code>x</code>, <code>y</code>)
218 * just like <code>g.drawString</code> would.
219 * The character at index <code>underlinedIndex</code>
220 * in text will be underlined. If <code>index</code> is beyond the
221 * bounds of <code>text</code> (including < 0), nothing will be
222 * underlined.
223 *
224 * @param g Graphics to draw with
225 * @param text String to draw
226 * @param underlinedIndex Index of character in text to underline
227 * @param x x coordinate to draw at
228 * @param y y coordinate to draw at
229 * @since 1.4
230 */
231 public static void drawStringUnderlineCharAt(Graphics g,
232 String text, int underlinedIndex, int x, int y) {
233 SwingUtilities2.drawStringUnderlineCharAt(null, g, text,
234 underlinedIndex, x, y);
235 }
236
237 public static void drawDashedRect(Graphics g, int x, int y,
238 int width, int height) {
239 int vx, vy;
240
241 // draw upper and lower horizontal dashes
242 for (vx = x; vx < (x + width); vx += 2) {
243 g.fillRect(vx, y, 1, 1);
244 g.fillRect(vx, y + height - 1, 1, 1);
245 }
246
247 // draw left and right vertical dashes
248 for (vy = y; vy < (y + height); vy += 2) {
249 g.fillRect(x, vy, 1, 1);
250 g.fillRect(x + width - 1, vy, 1, 1);
251 }
252 }
253
254 public static Dimension getPreferredButtonSize(AbstractButton b,
255 int textIconGap) {
256 if (b.getComponentCount() > 0) {
257 return null;
258 }
259
260 Icon icon = (Icon) b.getIcon();
261 String text = b.getText();
262
263 Font font = b.getFont();
264 FontMetrics fm = b.getFontMetrics(font);
265
266 Rectangle iconR = new Rectangle();
267 Rectangle textR = new Rectangle();
268 Rectangle viewR = new Rectangle(Short.MAX_VALUE,
269 Short.MAX_VALUE);
270
271 SwingUtilities.layoutCompoundLabel((JComponent) b, fm, text,
272 icon, b.getVerticalAlignment(), b
273 .getHorizontalAlignment(), b
274 .getVerticalTextPosition(), b
275 .getHorizontalTextPosition(), viewR, iconR,
276 textR, (text == null ? 0 : textIconGap));
277
278 /* The preferred size of the button is the size of
279 * the text and icon rectangles plus the buttons insets.
280 */
281
282 Rectangle r = iconR.union(textR);
283
284 Insets insets = b.getInsets();
285 r.width += insets.left + insets.right;
286 r.height += insets.top + insets.bottom;
287
288 return r.getSize();
289 }
290
291 /*
292 * Convenience function for determining ComponentOrientation. Helps us
293 * avoid having Munge directives throughout the code.
294 */
295 static boolean isLeftToRight(Component c) {
296 return c.getComponentOrientation().isLeftToRight();
297 }
298 }
|