KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > java > swing > plaf > motif > MotifGraphicsUtils


1 /*
2  * @(#)MotifGraphicsUtils.java 1.45 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 com.sun.java.swing.plaf.motif;
8
9 import com.sun.java.swing.SwingUtilities2;
10
11 import javax.swing.*;
12 import java.awt.Color JavaDoc;
13 import java.awt.Dimension JavaDoc;
14 import java.awt.Graphics JavaDoc;
15 import java.awt.Font JavaDoc;
16 import java.awt.FontMetrics JavaDoc;
17 import java.awt.Rectangle JavaDoc;
18 import java.awt.Component JavaDoc;
19 import java.awt.Insets JavaDoc;
20 import java.awt.event.KeyEvent JavaDoc;
21 import java.awt.Container JavaDoc;
22
23 import javax.swing.plaf.basic.*;
24 import javax.swing.text.View JavaDoc;
25
26 /*
27  * @version 1.45 12/19/03
28  * @author Jeff Dinkins
29  * @author Dave Kloba
30  */

31
32 public class MotifGraphicsUtils implements SwingConstants
33 {
34     /* Client Property keys for text and accelerator text widths */
35     private static final String JavaDoc MAX_ACC_WIDTH = "maxAccWidth";
36     
37     /**
38      * Draws the point (<b>x</b>, <b>y</b>) in the current color.
39      */

40     static void drawPoint(Graphics JavaDoc g, int x, int y) {
41         g.drawLine(x, y, x, y);
42     }
43
44     /*
45      * Convenience method for drawing a grooved line
46      *
47      */

48     public static void drawGroove(Graphics JavaDoc g, int x, int y, int w, int h,
49                                   Color JavaDoc shadow, Color JavaDoc highlight)
50     {
51         Color JavaDoc oldColor = g.getColor(); // Make no net change to g
52
g.translate(x, y);
53
54         g.setColor(shadow);
55         g.drawRect(0, 0, w-2, h-2);
56
57         g.setColor(highlight);
58         g.drawLine(1, h-3, 1, 1);
59         g.drawLine(1, 1, w-3, 1);
60
61         g.drawLine(0, h-1, w-1, h-1);
62         g.drawLine(w-1, h-1, w-1, 0);
63
64         g.translate(-x, -y);
65         g.setColor(oldColor);
66     }
67
68     /** Draws <b>aString</b> in the rectangle defined by
69       * (<b>x</b>, <b>y</b>, <b>width</b>, <b>height</b>).
70       * <b>justification</b> specifies the text's justification, one of
71       * LEFT, CENTER, or RIGHT.
72       * <b>drawStringInRect()</b> does not clip to the rectangle, but instead
73       * uses this rectangle and the desired justification to compute the point
74       * at which to begin drawing the text.
75       * @see #drawString
76       */

77     public static void drawStringInRect(Graphics JavaDoc g, String JavaDoc aString, int x, int y,
78                                  int width, int height, int justification) {
79         drawStringInRect(null, g, aString, x, y, width, height, justification);
80     }
81
82     static void drawStringInRect(JComponent c, Graphics JavaDoc g, String JavaDoc aString,
83                                  int x, int y, int width, int height,
84                                  int justification) {
85         FontMetrics JavaDoc fontMetrics;
86         int drawWidth, startX, startY, delta;
87
88         if (g.getFont() == null) {
89 // throw new InconsistencyException("No font set");
90
return;
91         }
92         fontMetrics = SwingUtilities2.getFontMetrics(c, g);
93         if (fontMetrics == null) {
94 // throw new InconsistencyException("No metrics for Font " + font());
95
return;
96         }
97
98         if (justification == CENTER) {
99             drawWidth = SwingUtilities2.stringWidth(c, fontMetrics, aString);
100             if (drawWidth > width) {
101                 drawWidth = width;
102             }
103             startX = x + (width - drawWidth) / 2;
104         } else if (justification == RIGHT) {
105             drawWidth = SwingUtilities2.stringWidth(c, fontMetrics, aString);
106             if (drawWidth > width) {
107                 drawWidth = width;
108             }
109             startX = x + width - drawWidth;
110         } else {
111             startX = x;
112         }
113
114         delta = (height - fontMetrics.getAscent() - fontMetrics.getDescent()) / 2;
115         if (delta < 0) {
116             delta = 0;
117         }
118
119         startY = y + height - delta - fontMetrics.getDescent();
120
121         SwingUtilities2.drawString(c, g, aString, startX, startY);
122     }
123
124
125   public static void paintMenuItem(Graphics JavaDoc g, JComponent c,
126                                    Icon checkIcon, Icon arrowIcon,
127                                    Color JavaDoc background, Color JavaDoc foreground,
128                                    int defaultTextIconGap)
129     {
130
131         JMenuItem b = (JMenuItem) c;
132     ButtonModel model = b.getModel();
133     
134     Dimension JavaDoc size = b.getSize();
135     Insets JavaDoc i = c.getInsets();
136     
137     Rectangle JavaDoc viewRect = new Rectangle JavaDoc(size);
138     
139     viewRect.x += i.left;
140     viewRect.y += i.top;
141     viewRect.width -= (i.right + viewRect.x);
142     viewRect.height -= (i.bottom + viewRect.y);
143     
144     Rectangle JavaDoc iconRect = new Rectangle JavaDoc();
145     Rectangle JavaDoc textRect = new Rectangle JavaDoc();
146     Rectangle JavaDoc acceleratorRect = new Rectangle JavaDoc();
147     Rectangle JavaDoc checkRect = new Rectangle JavaDoc();
148     Rectangle JavaDoc arrowRect = new Rectangle JavaDoc();
149     
150     Font JavaDoc holdf = g.getFont();
151     Font JavaDoc f = c.getFont();
152     g.setFont(f);
153     FontMetrics JavaDoc fm = SwingUtilities2.getFontMetrics(c, g, f);
154     FontMetrics JavaDoc fmAccel = SwingUtilities2.getFontMetrics(
155             c, g, UIManager.getFont("MenuItem.acceleratorFont"));
156     
157     if (c.isOpaque()) {
158         if (model.isArmed()|| (c instanceof JMenu && model.isSelected())) {
159         g.setColor(background);
160         } else {
161         g.setColor(c.getBackground());
162         }
163         g.fillRect(0,0, size.width, size.height);
164     }
165     
166     // get Accelerator text
167
KeyStroke accelerator = b.getAccelerator();
168     String JavaDoc acceleratorText = "";
169     if (accelerator != null) {
170         int modifiers = accelerator.getModifiers();
171         if (modifiers > 0) {
172         acceleratorText = KeyEvent.getKeyModifiersText(modifiers);
173         acceleratorText += "+";
174         }
175         acceleratorText += KeyEvent.getKeyText(accelerator.getKeyCode());
176     }
177     
178     // layout the text and icon
179
String JavaDoc text = layoutMenuItem(c, fm, b.getText(), fmAccel,
180                      acceleratorText, b.getIcon(),
181                      checkIcon, arrowIcon,
182                      b.getVerticalAlignment(),
183                      b.getHorizontalAlignment(),
184                      b.getVerticalTextPosition(),
185                      b.getHorizontalTextPosition(),
186                      viewRect, iconRect,
187                      textRect, acceleratorRect,
188                      checkRect, arrowRect,
189                      b.getText() == null
190                      ? 0 : defaultTextIconGap,
191                      defaultTextIconGap
192                      );
193     
194     // Paint the Check
195
Color JavaDoc holdc = g.getColor();
196     if (checkIcon != null) {
197         if(model.isArmed() || (c instanceof JMenu && model.isSelected()))
198         g.setColor(foreground);
199         checkIcon.paintIcon(c, g, checkRect.x, checkRect.y);
200         g.setColor(holdc);
201     }
202     
203     // Paint the Icon
204
if(b.getIcon() != null) {
205         Icon icon;
206         if(!model.isEnabled()) {
207         icon = (Icon) b.getDisabledIcon();
208         } else if(model.isPressed() && model.isArmed()) {
209         icon = (Icon) b.getPressedIcon();
210         if(icon == null) {
211             // Use default icon
212
icon = (Icon) b.getIcon();
213         }
214         } else {
215         icon = (Icon) b.getIcon();
216         }
217         
218         if (icon!=null) {
219         icon.paintIcon(c, g, iconRect.x, iconRect.y);
220         }
221     }
222     
223     // Draw the Text
224
if(text != null && !text.equals("")) {
225         // Once BasicHTML becomes public, use BasicHTML.propertyKey
226
// instead of the hardcoded string below!
227
View JavaDoc v = (View JavaDoc) c.getClientProperty("html");
228         if (v != null) {
229         v.paint(g, textRect);
230         } else {
231         int mnemIndex = b.getDisplayedMnemonicIndex();
232
233         if(!model.isEnabled()) {
234             // *** paint the text disabled
235
g.setColor(b.getBackground().brighter());
236             SwingUtilities2.drawStringUnderlineCharAt(b, g,text,
237                         mnemIndex,
238                         textRect.x, textRect.y + fmAccel.getAscent());
239             g.setColor(b.getBackground().darker());
240             SwingUtilities2.drawStringUnderlineCharAt(b, g,text,
241                         mnemIndex,
242                         textRect.x - 1, textRect.y + fmAccel.getAscent() - 1);
243             
244         } else {
245             // *** paint the text normally
246
if (model.isArmed()|| (c instanceof JMenu && model.isSelected())) {
247             g.setColor(foreground);
248             } else {
249             g.setColor(b.getForeground());
250             }
251             SwingUtilities2.drawStringUnderlineCharAt(b, g,text,
252                           mnemIndex,
253                           textRect.x,
254                           textRect.y + fm.getAscent());
255         }
256         }
257     }
258     
259     // Draw the Accelerator Text
260
if(acceleratorText != null && !acceleratorText.equals("")) {
261
262         //Get the maxAccWidth from the parent to calculate the offset.
263
int accOffset = 0;
264         Container JavaDoc parent = b.getParent();
265         if (parent != null && parent instanceof JComponent) {
266         JComponent p = (JComponent) parent;
267         Integer JavaDoc maxValueInt = (Integer JavaDoc) p.getClientProperty(MotifGraphicsUtils.MAX_ACC_WIDTH);
268         int maxValue = maxValueInt != null ?
269                     maxValueInt.intValue() : acceleratorRect.width;
270         
271         //Calculate the offset, with which the accelerator texts will be drawn with.
272
accOffset = maxValue - acceleratorRect.width;
273         }
274
275         g.setFont( UIManager.getFont("MenuItem.acceleratorFont") );
276         if(!model.isEnabled()) {
277         // *** paint the acceleratorText disabled
278
g.setColor(b.getBackground().brighter());
279         SwingUtilities2.drawString(c, g,acceleratorText,
280                           acceleratorRect.x - accOffset, acceleratorRect.y + fm.getAscent());
281         g.setColor(b.getBackground().darker());
282         SwingUtilities2.drawString(c, g,acceleratorText,
283                           acceleratorRect.x - accOffset - 1, acceleratorRect.y + fm.getAscent() - 1);
284         } else {
285         // *** paint the acceleratorText normally
286
if (model.isArmed()|| (c instanceof JMenu && model.isSelected()))
287             {
288             g.setColor(foreground);
289             } else {
290             g.setColor(b.getForeground());
291             }
292         SwingUtilities2.drawString(c, g,acceleratorText,
293                           acceleratorRect.x - accOffset,
294                           acceleratorRect.y + fmAccel.getAscent());
295         }
296     }
297     
298     // Paint the Arrow
299
if (arrowIcon != null) {
300         if(model.isArmed() || (c instanceof JMenu && model.isSelected()))
301         g.setColor(foreground);
302         if( !(b.getParent() instanceof JMenuBar) )
303         arrowIcon.paintIcon(c, g, arrowRect.x, arrowRect.y);
304     }
305     
306     g.setColor(holdc);
307     g.setFont(holdf);
308     }
309
310
311     /**
312      * Compute and return the location of the icons origin, the
313      * location of origin of the text baseline, and a possibly clipped
314      * version of the compound labels string. Locations are computed
315      * relative to the viewR rectangle.
316      */

317
318     private static String JavaDoc layoutMenuItem(
319         JComponent c,
320         FontMetrics JavaDoc fm,
321         String JavaDoc text,
322         FontMetrics JavaDoc fmAccel,
323         String JavaDoc acceleratorText,
324         Icon icon,
325         Icon checkIcon,
326         Icon arrowIcon,
327         int verticalAlignment,
328         int horizontalAlignment,
329         int verticalTextPosition,
330         int horizontalTextPosition,
331         Rectangle JavaDoc viewR,
332         Rectangle JavaDoc iconR,
333         Rectangle JavaDoc textR,
334         Rectangle JavaDoc acceleratorR,
335         Rectangle JavaDoc checkIconR,
336         Rectangle JavaDoc arrowIconR,
337         int textIconGap,
338         int menuItemGap
339         )
340     {
341
342         SwingUtilities.layoutCompoundLabel(c,
343                                            fm,
344                                            text,
345                                            icon,
346                                            verticalAlignment,
347                                            horizontalAlignment,
348                                            verticalTextPosition,
349                                            horizontalTextPosition,
350                                            viewR,
351                                            iconR,
352                                            textR,
353                                            textIconGap);
354
355         /* Initialize the acceelratorText bounds rectangle textR. If a null
356          * or and empty String was specified we substitute "" here
357          * and use 0,0,0,0 for acceleratorTextR.
358          */

359         if( (acceleratorText == null) || acceleratorText.equals("") ) {
360             acceleratorR.width = acceleratorR.height = 0;
361             acceleratorText = "";
362         }
363         else {
364             acceleratorR.width
365                 = SwingUtilities2.stringWidth(c, fmAccel, acceleratorText);
366             acceleratorR.height = fmAccel.getHeight();
367         }
368
369         /* Initialize the checkIcon bounds rectangle checkIconR.
370          */

371
372         if (checkIcon != null) {
373             checkIconR.width = checkIcon.getIconWidth();
374             checkIconR.height = checkIcon.getIconHeight();
375         }
376         else {
377             checkIconR.width = checkIconR.height = 0;
378         }
379
380         /* Initialize the arrowIcon bounds rectangle arrowIconR.
381          */

382
383         if (arrowIcon != null) {
384             arrowIconR.width = arrowIcon.getIconWidth();
385             arrowIconR.height = arrowIcon.getIconHeight();
386         }
387         else {
388             arrowIconR.width = arrowIconR.height = 0;
389         }
390         
391
392         Rectangle JavaDoc labelR = iconR.union(textR);
393         if( MotifGraphicsUtils.isLeftToRight(c) ) {
394             textR.x += checkIconR.width + menuItemGap;
395             iconR.x += checkIconR.width + menuItemGap;
396
397             // Position the Accelerator text rect
398
acceleratorR.x = viewR.x + viewR.width - arrowIconR.width
399                              - menuItemGap - acceleratorR.width;
400
401             // Position the Check and Arrow Icons
402
checkIconR.x = viewR.x;
403             arrowIconR.x = viewR.x + viewR.width - menuItemGap
404                            - arrowIconR.width;
405         } else {
406             textR.x -= (checkIconR.width + menuItemGap);
407             iconR.x -= (checkIconR.width + menuItemGap);
408
409             // Position the Accelerator text rect
410
acceleratorR.x = viewR.x + arrowIconR.width + menuItemGap;
411
412             // Position the Check and Arrow Icons
413
checkIconR.x = viewR.x + viewR.width - checkIconR.width;
414             arrowIconR.x = viewR.x + menuItemGap;
415         }
416         
417         // Align the accelertor text and the check and arrow icons vertically
418
// with the center of the label rect.
419
acceleratorR.y = labelR.y + (labelR.height/2) - (acceleratorR.height/2);
420         arrowIconR.y = labelR.y + (labelR.height/2) - (arrowIconR.height/2);
421         checkIconR.y = labelR.y + (labelR.height/2) - (checkIconR.height/2);
422         
423         /*
424           System.out.println("Layout: v=" +viewR+" c="+checkIconR+" i="+
425           iconR+" t="+textR+" acc="+acceleratorR+" a="+arrowIconR);
426           */

427         return text;
428     }
429
430   private static void drawMenuBezel(Graphics JavaDoc g, Color JavaDoc background,
431                                     int x, int y,
432                                     int width, int height)
433     {
434       // shadowed button region
435
g.setColor(background);
436       g.fillRect(x,y,width,height);
437
438       g.setColor(background.brighter().brighter());
439       g.drawLine(x+1, y+height-1, x+width-1, y+height-1);
440       g.drawLine(x+width-1, y+height-2, x+width-1, y+1);
441             
442       g.setColor(background.darker().darker());
443       g.drawLine(x, y, x+width-2, y);
444       g.drawLine(x, y+1, x, y+height-2);
445       
446     }
447
448     /*
449      * Convenience function for determining ComponentOrientation. Helps us
450      * avoid having Munge directives throughout the code.
451      */

452     static boolean isLeftToRight( Component JavaDoc c ) {
453     return c.getComponentOrientation().isLeftToRight();
454     }
455 }
456
Popular Tags