KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > swing > plaf > synth > SynthGraphicsUtils


1 /*
2  * @(#)SynthGraphicsUtils.java 1.16 03/12/19
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7 package javax.swing.plaf.synth;
8
9 import com.sun.java.swing.SwingUtilities2;
10 import java.awt.*;
11 import javax.swing.*;
12 import javax.swing.plaf.basic.BasicHTML JavaDoc;
13 import javax.swing.text.*;
14 import sun.swing.plaf.synth.*;
15
16 /**
17  * Wrapper for primitive graphics calls.
18  *
19  * @version 1.16, 12/19/03
20  * @since 1.5
21  * @author Scott Violet
22  */

23 public class SynthGraphicsUtils {
24     // These are used in the text painting code to avoid allocating a bunch of
25
// garbage.
26
private Rectangle paintIconR = new Rectangle();
27     private Rectangle paintTextR = new Rectangle();
28     private Rectangle paintViewR = new Rectangle();
29     private Insets paintInsets = new Insets(0, 0, 0, 0);
30
31     // These Rectangles/Insets are used in the text size calculation to avoid a
32
// a bunch of garbage.
33
private Rectangle iconR = new Rectangle();
34     private Rectangle textR = new Rectangle();
35     private Rectangle viewR = new Rectangle();
36     private Insets viewSizingInsets = new Insets(0, 0, 0, 0);
37
38     /**
39      * Creates a <code>SynthGraphicsUtils</code>.
40      */

41     public SynthGraphicsUtils() {
42     }
43
44     /**
45      * Draws a line between the two end points.
46      *
47      * @param context Identifies hosting region.
48      * @param paintKey Identifies the portion of the component being asked
49      * to paint, may be null.
50      * @param g Graphics object to paint to
51      * @param x1 x origin
52      * @param y1 y origin
53      * @param x2 x destination
54      * @param y2 y destination
55      */

56     public void drawLine(SynthContext JavaDoc context, Object JavaDoc paintKey,
57                          Graphics g, int x1, int y1, int x2, int y2) {
58         g.drawLine(x1, y1, x2, y2);
59     }
60
61     /**
62      * Lays out text and an icon returning, by reference, the location to
63      * place the icon and text.
64      *
65      * @param ss SynthContext
66      * @param fm FontMetrics for the Font to use, this may be ignored
67      * @param text Text to layout
68      * @param icon Icon to layout
69      * @param hAlign horizontal alignment
70      * @param vAlign vertical alignment
71      * @param hTextPosition horizontal text position
72      * @param vTextPosition vertical text position
73      * @param viewR Rectangle to layout text and icon in.
74      * @param iconR Rectangle to place icon bounds in
75      * @param textR Rectangle to place text in
76      * @param iconTextGap gap between icon and text
77      */

78     public String JavaDoc layoutText(SynthContext JavaDoc ss, FontMetrics fm,
79                          String JavaDoc text, Icon icon, int hAlign,
80                          int vAlign, int hTextPosition,
81                          int vTextPosition, Rectangle viewR,
82                          Rectangle iconR, Rectangle textR, int iconTextGap) {
83         if (icon instanceof SynthIcon) {
84             SynthIconWrapper wrapper = SynthIconWrapper.get((SynthIcon)icon,
85                                                             ss);
86             String JavaDoc formattedText = SwingUtilities.layoutCompoundLabel(
87                       ss.getComponent(), fm, text, wrapper, vAlign, hAlign,
88                       vTextPosition, hTextPosition, viewR, iconR, textR,
89                       iconTextGap);
90             SynthIconWrapper.release(wrapper);
91             return formattedText;
92         }
93         return SwingUtilities.layoutCompoundLabel(
94                       ss.getComponent(), fm, text, icon, vAlign, hAlign,
95                       vTextPosition, hTextPosition, viewR, iconR, textR,
96                       iconTextGap);
97     }
98
99     /**
100      * Returns the size of the passed in string.
101      *
102      * @param ss SynthContext
103      * @param font Font to use
104      * @param metrics FontMetrics, may be ignored
105      * @param text Text to get size of.
106      */

107     public int computeStringWidth(SynthContext JavaDoc ss, Font font,
108                                   FontMetrics metrics, String JavaDoc text) {
109         return SwingUtilities2.stringWidth(ss.getComponent(), metrics,
110                                           text);
111     }
112
113     /**
114      * Returns the minimum size needed to properly render an icon and text.
115      *
116      * @param ss SynthContext
117      * @param font Font to use
118      * @param text Text to layout
119      * @param icon Icon to layout
120      * @param hAlign horizontal alignment
121      * @param vAlign vertical alignment
122      * @param hTextPosition horizontal text position
123      * @param vTextPosition vertical text position
124      * @param iconTextGap gap between icon and text
125      * @param mnemonicIndex Index into text to render the mnemonic at, -1
126      * indicates no mnemonic.
127      */

128     public Dimension getMinimumSize(SynthContext JavaDoc ss, Font font, String JavaDoc text,
129                       Icon icon, int hAlign, int vAlign, int hTextPosition,
130                       int vTextPosition, int iconTextGap, int mnemonicIndex) {
131         JComponent c = ss.getComponent();
132         Dimension size = getPreferredSize(ss, font, text, icon, hAlign,
133                                           vAlign, hTextPosition, vTextPosition,
134                                           iconTextGap, mnemonicIndex);
135     View v = (View) c.getClientProperty(BasicHTML.propertyKey);
136
137     if (v != null) {
138         size.width -= v.getPreferredSpan(View.X_AXIS) -
139                           v.getMinimumSpan(View.X_AXIS);
140     }
141         return size;
142     }
143
144     /**
145      * Returns the maximum size needed to properly render an icon and text.
146      *
147      * @param ss SynthContext
148      * @param font Font to use
149      * @param text Text to layout
150      * @param icon Icon to layout
151      * @param hAlign horizontal alignment
152      * @param vAlign vertical alignment
153      * @param hTextPosition horizontal text position
154      * @param vTextPosition vertical text position
155      * @param iconTextGap gap between icon and text
156      * @param mnemonicIndex Index into text to render the mnemonic at, -1
157      * indicates no mnemonic.
158      */

159     public Dimension getMaximumSize(SynthContext JavaDoc ss, Font font, String JavaDoc text,
160                       Icon icon, int hAlign, int vAlign, int hTextPosition,
161                       int vTextPosition, int iconTextGap, int mnemonicIndex) {
162         JComponent c = ss.getComponent();
163         Dimension size = getPreferredSize(ss, font, text, icon, hAlign,
164                                           vAlign, hTextPosition, vTextPosition,
165                                           iconTextGap, mnemonicIndex);
166     View v = (View) c.getClientProperty(BasicHTML.propertyKey);
167
168     if (v != null) {
169         size.width += v.getMaximumSpan(View.X_AXIS) -
170                           v.getPreferredSpan(View.X_AXIS);
171     }
172         return size;
173     }
174
175     /**
176      * Returns the maximum height of the the Font from the passed in
177      * SynthContext.
178      *
179      * @param context SynthContext used to determine font.
180      * @return maximum height of the characters for the font from the passed
181      * in context.
182      */

183     public int getMaximumCharHeight(SynthContext JavaDoc context) {
184         FontMetrics fm = context.getComponent().getFontMetrics(
185             context.getStyle().getFont(context));
186         return (fm.getAscent() + fm.getDescent());
187     }
188
189     /**
190      * Returns the preferred size needed to properly render an icon and text.
191      *
192      * @param ss SynthContext
193      * @param font Font to use
194      * @param text Text to layout
195      * @param icon Icon to layout
196      * @param hAlign horizontal alignment
197      * @param vAlign vertical alignment
198      * @param hTextPosition horizontal text position
199      * @param vTextPosition vertical text position
200      * @param iconTextGap gap between icon and text
201      * @param mnemonicIndex Index into text to render the mnemonic at, -1
202      * indicates no mnemonic.
203      */

204     public Dimension getPreferredSize(SynthContext JavaDoc ss, Font font, String JavaDoc text,
205                       Icon icon, int hAlign, int vAlign, int hTextPosition,
206                       int vTextPosition, int iconTextGap, int mnemonicIndex) {
207         JComponent c = ss.getComponent();
208         Insets insets = c.getInsets(viewSizingInsets);
209         int dx = insets.left + insets.right;
210         int dy = insets.top + insets.bottom;
211
212         if (icon == null && (text == null || font == null)) {
213             return new Dimension(dx, dy);
214         }
215         else if ((text == null) || ((icon != null) && (font == null))) {
216             return new Dimension(SynthIcon.getIconWidth(icon, ss) + dx,
217                                  SynthIcon.getIconHeight(icon, ss) + dy);
218         }
219         else {
220             FontMetrics fm = c.getFontMetrics(font);
221
222             iconR.x = iconR.y = iconR.width = iconR.height = 0;
223             textR.x = textR.y = textR.width = textR.height = 0;
224             viewR.x = dx;
225             viewR.y = dy;
226             viewR.width = viewR.height = Short.MAX_VALUE;
227
228             layoutText(ss, fm, text, icon, hAlign, vAlign,
229                    hTextPosition, vTextPosition, viewR, iconR, textR,
230                    iconTextGap);
231             int x1 = Math.min(iconR.x, textR.x);
232             int x2 = Math.max(iconR.x + iconR.width, textR.x + textR.width);
233             int y1 = Math.min(iconR.y, textR.y);
234             int y2 = Math.max(iconR.y + iconR.height, textR.y + textR.height);
235             Dimension rv = new Dimension(x2 - x1, y2 - y1);
236
237             rv.width += dx;
238             rv.height += dy;
239             return rv;
240         }
241     }
242
243     /**
244      * Paints text at the specified location. This will not attempt to
245      * render the text as html nor will it offset by the insets of the
246      * component.
247      *
248      * @param ss SynthContext
249      * @param g Graphics used to render string in.
250      * @param text Text to render
251      * @param bounds Bounds of the text to be drawn.
252      * @param mnemonicIndex Index to draw string at.
253      */

254     public void paintText(SynthContext JavaDoc ss, Graphics g, String JavaDoc text,
255                           Rectangle bounds, int mnemonicIndex) {
256         paintText(ss, g, text, bounds.x, bounds.y, mnemonicIndex);
257     }
258
259     /**
260      * Paints text at the specified location. This will not attempt to
261      * render the text as html nor will it offset by the insets of the
262      * component.
263      *
264      * @param ss SynthContext
265      * @param g Graphics used to render string in.
266      * @param text Text to render
267      * @param x X location to draw text at.
268      * @param y Upper left corner to draw text at.
269      * @param mnemonicIndex Index to draw string at.
270      */

271     public void paintText(SynthContext JavaDoc ss, Graphics g, String JavaDoc text,
272                           int x, int y, int mnemonicIndex) {
273         if (text != null) {
274             JComponent c = ss.getComponent();
275             SynthStyle JavaDoc style = ss.getStyle();
276             FontMetrics fm = SwingUtilities2.getFontMetrics(c, g);
277
278             y += fm.getAscent();
279             SwingUtilities2.drawString(c, g, text, x, y);
280             if (mnemonicIndex >= 0 && mnemonicIndex < text.length()) {
281                 int underlineX = x + SwingUtilities2.stringWidth(
282                              c, fm, text.substring(0, mnemonicIndex));
283                 int underlineY = y;
284                 int underlineWidth = fm.charWidth(text.charAt(mnemonicIndex));
285                 int underlineHeight = 1;
286
287                 g.fillRect(underlineX, underlineY + fm.getDescent() - 1,
288                            underlineWidth, underlineHeight);
289             }
290         }
291     }
292
293     /**
294      * Paints an icon and text. This will render the text as html, if
295      * necessary, and offset the location by the insets of the component.
296      *
297      * @param ss SynthContext
298      * @param g Graphics to render string and icon into
299      * @param text Text to layout
300      * @param icon Icon to layout
301      * @param hAlign horizontal alignment
302      * @param vAlign vertical alignment
303      * @param hTextPosition horizontal text position
304      * @param vTextPosition vertical text position
305      * @param iconTextGap gap between icon and text
306      * @param mnemonicIndex Index into text to render the mnemonic at, -1
307      * indicates no mnemonic.
308      * @param textOffset Amount to offset the text when painting
309      */

310     public void paintText(SynthContext JavaDoc ss, Graphics g, String JavaDoc text,
311                       Icon icon, int hAlign, int vAlign, int hTextPosition,
312                       int vTextPosition, int iconTextGap, int mnemonicIndex,
313                       int textOffset) {
314         if ((icon == null) && (text == null)) {
315             return;
316         }
317         JComponent c = ss.getComponent();
318         FontMetrics fm = SwingUtilities2.getFontMetrics(c, g);
319         Insets insets = SynthLookAndFeel.getPaintingInsets(ss, paintInsets);
320
321         paintViewR.x = insets.left;
322         paintViewR.y = insets.top;
323         paintViewR.width = c.getWidth() - (insets.left + insets.right);
324         paintViewR.height = c.getHeight() - (insets.top + insets.bottom);
325
326         paintIconR.x = paintIconR.y = paintIconR.width = paintIconR.height = 0;
327         paintTextR.x = paintTextR.y = paintTextR.width = paintTextR.height = 0;
328
329         String JavaDoc clippedText =
330             layoutText(ss, fm, text, icon, hAlign, vAlign,
331                    hTextPosition, vTextPosition, paintViewR, paintIconR,
332                    paintTextR, iconTextGap);
333
334         if (icon != null) {
335             Color color = g.getColor();
336             paintIconR.x += textOffset;
337             paintIconR.y += textOffset;
338             SynthIcon.paintIcon(icon, ss, g, paintIconR.x, paintIconR.y,
339                                 paintIconR.width, paintIconR.height);
340             g.setColor(color);
341         }
342
343         if (text != null) {
344         View v = (View) c.getClientProperty(BasicHTML.propertyKey);
345
346         if (v != null) {
347         v.paint(g, paintTextR);
348         } else {
349                 paintTextR.x += textOffset;
350                 paintTextR.y += textOffset;
351
352                 paintText(ss, g, clippedText, paintTextR, mnemonicIndex);
353         }
354         }
355     }
356
357
358     /**
359      * Wraps a SynthIcon around the Icon interface, forwarding calls to
360      * the SynthIcon with a given SynthContext.
361      */

362     private static class SynthIconWrapper implements Icon {
363         private static final java.util.List JavaDoc CACHE = new java.util.ArrayList JavaDoc(1);
364
365         private SynthIcon synthIcon;
366         private SynthContext JavaDoc context;
367
368         static SynthIconWrapper get(SynthIcon icon, SynthContext JavaDoc context) {
369             synchronized(CACHE) {
370                 int size = CACHE.size();
371                 if (size > 0) {
372                     SynthIconWrapper wrapper = (SynthIconWrapper)CACHE.remove(
373                                                size - 1);
374                     wrapper.reset(icon, context);
375                     return wrapper;
376                 }
377             }
378             return new SynthIconWrapper(icon, context);
379         }
380
381         static void release(SynthIconWrapper wrapper) {
382             wrapper.reset(null, null);
383             synchronized(CACHE) {
384                 CACHE.add(wrapper);
385             }
386         }
387
388         SynthIconWrapper(SynthIcon icon, SynthContext JavaDoc context) {
389             reset(icon, context);
390         }
391
392         void reset(SynthIcon icon, SynthContext JavaDoc context) {
393             synthIcon = icon;
394             this.context = context;
395         }
396
397         public void paintIcon(Component c, Graphics g, int x, int y) {
398             // This is a noop as this should only be for sizing calls.
399
}
400
401         public int getIconWidth() {
402             return synthIcon.getIconWidth(context);
403         }
404
405         public int getIconHeight() {
406             return synthIcon.getIconHeight(context);
407         }
408     }
409 }
410
Popular Tags