blob: c588b034e0c44ef1b20068964df219032e8e19f3 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1997-2005 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 com.sun.java.swing.plaf.motif;
27
28import sun.swing.SwingUtilities2;
29import javax.swing.*;
30import javax.swing.border.*;
31import javax.swing.plaf.*;
32
33import java.awt.Color;
34import java.awt.Component;
35import java.awt.Dimension;
36import java.awt.Font;
37import java.awt.FontMetrics;
38import java.awt.Graphics;
39import java.awt.Insets;
40import java.awt.Point;
41import java.awt.Rectangle;
42
43import java.io.Serializable;
44
45/**
46 * Factory object that can vend Icons appropriate for the basic L & F.
47 * <p>
48 * <strong>Warning:</strong>
49 * Serialized objects of this class will not be compatible with
50 * future Swing releases. The current serialization support is appropriate
51 * for short term storage or RMI between applications running the same
52 * version of Swing. A future release of Swing will provide support for
53 * long term persistence.
54 *
55 * @author Amy Fowler
56 */
57public class MotifBorders {
58
59 public static class BevelBorder extends AbstractBorder implements UIResource {
60 private Color darkShadow = UIManager.getColor("controlShadow");
61 private Color lightShadow = UIManager.getColor("controlLtHighlight");
62 private boolean isRaised;
63
64 public BevelBorder(boolean isRaised, Color darkShadow, Color lightShadow) {
65 this.isRaised = isRaised;
66 this.darkShadow = darkShadow;
67 this.lightShadow = lightShadow;
68 }
69
70 public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) {
71 g.setColor((isRaised) ? lightShadow : darkShadow);
72 g.drawLine(x, y, x+w-1, y); // top
73 g.drawLine(x, y+h-1, x, y+1); // left
74
75 g.setColor((isRaised) ? darkShadow : lightShadow);
76 g.drawLine(x+1, y+h-1, x+w-1, y+h-1); // bottom
77 g.drawLine(x+w-1, y+h-1, x+w-1, y+1); // right
78 }
79
80 public Insets getBorderInsets(Component c, Insets insets) {
81 insets.set(1, 1, 1, 1);
82 return insets;
83 }
84
85 public boolean isOpaque(Component c) {
86 return true;
87 }
88
89 }
90
91
92 public static class FocusBorder extends AbstractBorder implements UIResource {
93 private Color focus;
94 private Color control;
95
96 public FocusBorder(Color control, Color focus) {
97 this.control = control;
98 this.focus = focus;
99 }
100
101 public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) {
102 if (((JComponent)c).hasFocus()) {
103 g.setColor(focus);
104 g.drawRect(x, y, w-1, h-1);
105 } else {
106 g.setColor(control);
107 g.drawRect(x, y, w-1, h-1);
108 }
109 }
110
111 public Insets getBorderInsets(Component c, Insets insets) {
112 insets.set(1, 1, 1, 1);
113 return insets;
114 }
115 }
116
117
118 public static class ButtonBorder extends AbstractBorder implements UIResource {
119 protected Color focus = UIManager.getColor("activeCaptionBorder");
120 protected Color shadow = UIManager.getColor("Button.shadow");
121 protected Color highlight = UIManager.getColor("Button.light");
122 protected Color darkShadow;
123
124 public ButtonBorder(Color shadow, Color highlight, Color darkShadow, Color focus) {
125 this.shadow = shadow;
126 this.highlight = highlight;
127 this.darkShadow = darkShadow;
128 this.focus = focus;
129 }
130
131 public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) {
132 boolean isPressed = false;
133 boolean hasFocus = false;
134 boolean canBeDefault = false;
135 boolean isDefault = false;
136
137 if (c instanceof AbstractButton) {
138 AbstractButton b = (AbstractButton)c;
139 ButtonModel model = b.getModel();
140
141 isPressed = (model.isArmed() && model.isPressed());
142 hasFocus = (model.isArmed() && isPressed) ||
143 (b.isFocusPainted() && b.hasFocus());
144 if (b instanceof JButton) {
145 canBeDefault = ((JButton)b).isDefaultCapable();
146 isDefault = ((JButton)b).isDefaultButton();
147 }
148 }
149 int bx1 = x+1;
150 int by1 = y+1;
151 int bx2 = x+w-2;
152 int by2 = y+h-2;
153
154 if (canBeDefault) {
155 if (isDefault) {
156 g.setColor(shadow);
157 g.drawLine(x+3, y+3, x+3, y+h-4);
158 g.drawLine(x+3, y+3, x+w-4, y+3);
159
160 g.setColor(highlight);
161 g.drawLine(x+4, y+h-4, x+w-4, y+h-4);
162 g.drawLine(x+w-4, y+3, x+w-4, y+h-4);
163 }
164 bx1 +=6;
165 by1 += 6;
166 bx2 -= 6;
167 by2 -= 6;
168 }
169
170 if (hasFocus) {
171 g.setColor(focus);
172 if (isDefault) {
173 g.drawRect(x, y, w-1, h-1);
174 } else {
175 g.drawRect(bx1-1, by1-1, bx2-bx1+2, by2-by1+2);
176 }
177 }
178
179 g.setColor(isPressed? shadow : highlight);
180 g.drawLine(bx1, by1, bx2, by1);
181 g.drawLine(bx1, by1, bx1, by2);
182
183 g.setColor(isPressed? highlight : shadow);
184 g.drawLine(bx2, by1+1, bx2, by2);
185 g.drawLine(bx1+1, by2, bx2, by2);
186 }
187
188 public Insets getBorderInsets(Component c, Insets insets) {
189 int thickness = (c instanceof JButton && ((JButton)c).isDefaultCapable())? 8 : 2;
190 insets.set(thickness, thickness, thickness, thickness);
191 return insets;
192 }
193
194 }
195
196 public static class ToggleButtonBorder extends ButtonBorder {
197
198 public ToggleButtonBorder(Color shadow, Color highlight, Color darkShadow, Color focus) {
199 super(shadow, highlight, darkShadow, focus);
200 }
201
202 public void paintBorder(Component c, Graphics g, int x, int y,
203 int width, int height) {
204 if (c instanceof AbstractButton) {
205 AbstractButton b = (AbstractButton)c;
206 ButtonModel model = b.getModel();
207
208 if (model.isArmed() && model.isPressed() || model.isSelected()) {
209 drawBezel(g, x, y, width, height,
210 (model.isPressed() || model.isSelected()),
211 b.isFocusPainted() && b.hasFocus(), shadow, highlight, darkShadow, focus);
212 } else {
213 drawBezel(g, x, y, width, height,
214 false, b.isFocusPainted() && b.hasFocus(),
215 shadow, highlight, darkShadow, focus);
216 }
217 } else {
218 drawBezel(g, x, y, width, height, false, false,
219 shadow, highlight, darkShadow, focus);
220 }
221 }
222
223 public Insets getBorderInsets(Component c, Insets insets) {
224 insets.set(2, 2, 3, 3);
225 return insets;
226 }
227 }
228
229 public static class MenuBarBorder extends ButtonBorder {
230
231 public MenuBarBorder(Color shadow, Color highlight, Color darkShadow, Color focus) {
232 super(shadow, highlight, darkShadow, focus);
233 }
234
235 public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
236 JMenuBar menuBar = (JMenuBar)c;
237 if (menuBar.isBorderPainted() == true) {
238 // this draws the MenuBar border
239 Dimension size = menuBar.getSize();
240 drawBezel(g,x,y,size.width,size.height,false,false,
241 shadow, highlight, darkShadow, focus);
242 }
243 }
244
245 public Insets getBorderInsets(Component c, Insets insets) {
246 insets.set(6, 6, 6, 6);
247 return insets;
248 }
249 }
250
251 public static class FrameBorder extends AbstractBorder implements UIResource {
252
253 JComponent jcomp;
254 Color frameHighlight;
255 Color frameColor;
256 Color frameShadow;
257
258 // The width of the border
259 public final static int BORDER_SIZE = 5;
260
261 /** Constructs an FrameBorder for the JComponent <b>comp</b>.
262 */
263 public FrameBorder(JComponent comp) {
264 jcomp = comp;
265 }
266
267 /** Sets the FrameBorder's JComponent.
268 */
269 public void setComponent(JComponent comp) {
270 jcomp = comp;
271 }
272
273 /** Returns the FrameBorder's JComponent.
274 * @see #setComponent
275 */
276 public JComponent component() {
277 return jcomp;
278 }
279
280 protected Color getFrameHighlight() {
281 return frameHighlight;
282 }
283
284 protected Color getFrameColor() {
285 return frameColor;
286 }
287
288 protected Color getFrameShadow() {
289 return frameShadow;
290 }
291
292 public Insets getBorderInsets(Component c, Insets newInsets) {
293 newInsets.set(BORDER_SIZE, BORDER_SIZE, BORDER_SIZE, BORDER_SIZE);
294 return newInsets;
295 }
296
297 /** Draws the FrameBorder's top border.
298 */
299 protected boolean drawTopBorder(Component c, Graphics g,
300 int x, int y, int width, int height) {
301 Rectangle titleBarRect = new Rectangle(x, y, width, BORDER_SIZE);
302 if (!g.getClipBounds().intersects(titleBarRect)) {
303 return false;
304 }
305
306 int maxX = width - 1;
307 int maxY = BORDER_SIZE - 1;
308
309 // Draw frame
310 g.setColor(frameColor);
311 g.drawLine(x, y + 2, maxX - 2, y + 2);
312 g.drawLine(x, y + 3, maxX - 2, y + 3);
313 g.drawLine(x, y + 4, maxX - 2, y + 4);
314
315 // Draw highlights
316 g.setColor(frameHighlight);
317 g.drawLine(x, y, maxX, y);
318 g.drawLine(x, y + 1, maxX, y + 1);
319 g.drawLine(x, y + 2, x, y + 4);
320 g.drawLine(x + 1, y + 2, x + 1, y + 4);
321
322 // Draw shadows
323 g.setColor(frameShadow);
324 g.drawLine(x + 4, y + 4, maxX - 4, y + 4);
325 g.drawLine(maxX, y + 1, maxX, maxY);
326 g.drawLine(maxX - 1, y + 2, maxX - 1, maxY);
327
328 return true;
329 }
330
331 /** Draws the FrameBorder's left border.
332 */
333 protected boolean drawLeftBorder(Component c, Graphics g, int x, int y,
334 int width, int height) {
335 Rectangle borderRect =
336 new Rectangle(0, 0, getBorderInsets(c).left, height);
337 if (!g.getClipBounds().intersects(borderRect)) {
338 return false;
339 }
340
341 int startY = BORDER_SIZE;
342
343 g.setColor(frameHighlight);
344 g.drawLine(x, startY, x, height - 1);
345 g.drawLine(x + 1, startY, x + 1, height - 2);
346
347 g.setColor(frameColor);
348 g.fillRect(x + 2, startY, x + 2, height - 3);
349
350 g.setColor(frameShadow);
351 g.drawLine(x + 4, startY, x + 4, height - 5);
352
353 return true;
354 }
355
356 /** Draws the FrameBorder's right border.
357 */
358 protected boolean drawRightBorder(Component c, Graphics g, int x, int y,
359 int width, int height) {
360 Rectangle borderRect = new Rectangle(
361 width - getBorderInsets(c).right, 0,
362 getBorderInsets(c).right, height);
363 if (!g.getClipBounds().intersects(borderRect)) {
364 return false;
365 }
366
367 int startX = width - getBorderInsets(c).right;
368 int startY = BORDER_SIZE;
369
370 g.setColor(frameColor);
371 g.fillRect(startX + 1, startY, 2, height - 1);
372
373 g.setColor(frameShadow);
374 g.fillRect(startX + 3, startY, 2, height - 1);
375
376 g.setColor(frameHighlight);
377 g.drawLine(startX, startY, startX, height - 1);
378
379 return true;
380 }
381
382 /** Draws the FrameBorder's bottom border.
383 */
384 protected boolean drawBottomBorder(Component c, Graphics g, int x, int y,
385 int width, int height) {
386 Rectangle borderRect;
387 int marginHeight, startY;
388
389 borderRect = new Rectangle(0, height - getBorderInsets(c).bottom,
390 width, getBorderInsets(c).bottom);
391 if (!g.getClipBounds().intersects(borderRect)) {
392 return false;
393 }
394
395 startY = height - getBorderInsets(c).bottom;
396
397 g.setColor(frameShadow);
398 g.drawLine(x + 1, height - 1, width - 1, height - 1);
399 g.drawLine(x + 2, height - 2, width - 2, height - 2);
400
401 g.setColor(frameColor);
402 g.fillRect(x + 2, startY + 1, width - 4, 2);
403
404 g.setColor(frameHighlight);
405 g.drawLine(x + 5, startY, width - 5, startY);
406
407 return true;
408 }
409
410 // Returns true if the associated component has focus.
411 protected boolean isActiveFrame() {
412 return jcomp.hasFocus();
413 }
414
415 /** Draws the FrameBorder in the given Rect. Calls
416 * <b>drawTitleBar</b>, <b>drawLeftBorder</b>, <b>drawRightBorder</b> and
417 * <b>drawBottomBorder</b>.
418 */
419 public void paintBorder(Component c, Graphics g,
420 int x, int y, int width, int height) {
421 if (isActiveFrame()) {
422 frameColor = UIManager.getColor("activeCaptionBorder");
423 } else {
424 frameColor = UIManager.getColor("inactiveCaptionBorder");
425 }
426 frameHighlight = frameColor.brighter();
427 frameShadow = frameColor.darker().darker();
428
429 drawTopBorder(c, g, x, y, width, height);
430 drawLeftBorder(c, g, x, y, width, height);
431 drawRightBorder(c, g, x, y, width, height);
432 drawBottomBorder(c, g, x, y, width, height);
433 }
434 }
435
436 public static class InternalFrameBorder extends FrameBorder {
437
438 JInternalFrame frame;
439
440 // The size of the bounding box for Motif frame corners.
441 public final static int CORNER_SIZE = 24;
442
443 /** Constructs an InternalFrameBorder for the InternalFrame
444 * <b>aFrame</b>.
445 */
446 public InternalFrameBorder(JInternalFrame aFrame) {
447 super(aFrame);
448 frame = aFrame;
449 }
450
451 /** Sets the InternalFrameBorder's InternalFrame.
452 */
453 public void setFrame(JInternalFrame aFrame) {
454 frame = aFrame;
455 }
456
457 /** Returns the InternalFrameBorder's InternalFrame.
458 * @see #setFrame
459 */
460 public JInternalFrame frame() {
461 return frame;
462 }
463
464 /** Returns the width of the InternalFrameBorder's resize controls,
465 * appearing along the InternalFrameBorder's bottom border. Clicking
466 * and dragging within these controls lets the user change both the
467 * InternalFrame's width and height, while dragging between the controls
468 * constrains resizing to just the vertical dimension. Override this
469 * method if you implement your own bottom border painting and use a
470 * resize control with a different size.
471 */
472 public int resizePartWidth() {
473 if (!frame.isResizable()) {
474 return 0;
475 }
476 return FrameBorder.BORDER_SIZE;
477 }
478
479 /** Draws the InternalFrameBorder's top border.
480 */
481 protected boolean drawTopBorder(Component c, Graphics g,
482 int x, int y, int width, int height) {
483 if (super.drawTopBorder(c, g, x, y, width, height) &&
484 frame.isResizable()) {
485 g.setColor(getFrameShadow());
486 g.drawLine(CORNER_SIZE - 1, y + 1, CORNER_SIZE - 1, y + 4);
487 g.drawLine(width - CORNER_SIZE - 1, y + 1,
488 width - CORNER_SIZE - 1, y + 4);
489
490 g.setColor(getFrameHighlight());
491 g.drawLine(CORNER_SIZE, y, CORNER_SIZE, y + 4);
492 g.drawLine(width - CORNER_SIZE, y, width - CORNER_SIZE, y + 4);
493 return true;
494 }
495 return false;
496 }
497
498 /** Draws the InternalFrameBorder's left border.
499 */
500 protected boolean drawLeftBorder(Component c, Graphics g, int x, int y,
501 int width, int height) {
502 if (super.drawLeftBorder(c, g, x, y, width, height) &&
503 frame.isResizable()) {
504 g.setColor(getFrameHighlight());
505 int topY = y + CORNER_SIZE;
506 g.drawLine(x, topY, x + 4, topY);
507 int bottomY = height - CORNER_SIZE;
508 g.drawLine(x + 1, bottomY, x + 5, bottomY);
509 g.setColor(getFrameShadow());
510 g.drawLine(x + 1, topY - 1, x + 5, topY - 1);
511 g.drawLine(x + 1, bottomY - 1, x + 5, bottomY - 1);
512 return true;
513 }
514 return false;
515 }
516
517 /** Draws the InternalFrameBorder's right border.
518 */
519 protected boolean drawRightBorder(Component c, Graphics g, int x, int y,
520 int width, int height) {
521 if (super.drawRightBorder(c, g, x, y, width, height) &&
522 frame.isResizable()) {
523 int startX = width - getBorderInsets(c).right;
524 g.setColor(getFrameHighlight());
525 int topY = y + CORNER_SIZE;
526 g.drawLine(startX, topY, width - 2, topY);
527 int bottomY = height - CORNER_SIZE;
528 g.drawLine(startX + 1, bottomY, startX + 3, bottomY);
529 g.setColor(getFrameShadow());
530 g.drawLine(startX + 1, topY - 1, width - 2, topY - 1);
531 g.drawLine(startX + 1, bottomY - 1, startX + 3, bottomY - 1);
532 return true;
533 }
534 return false;
535 }
536
537 /** Draws the InternalFrameBorder's bottom border.
538 */
539 protected boolean drawBottomBorder(Component c, Graphics g, int x, int y,
540 int width, int height) {
541 if (super.drawBottomBorder(c, g, x, y, width, height) &&
542 frame.isResizable()) {
543 int startY = height - getBorderInsets(c).bottom;
544
545 g.setColor(getFrameShadow());
546 g.drawLine(CORNER_SIZE - 1, startY + 1,
547 CORNER_SIZE - 1, height - 1);
548 g.drawLine(width - CORNER_SIZE, startY + 1,
549 width - CORNER_SIZE, height - 1);
550
551 g.setColor(getFrameHighlight());
552 g.drawLine(CORNER_SIZE, startY, CORNER_SIZE, height - 2);
553 g.drawLine(width - CORNER_SIZE + 1, startY,
554 width - CORNER_SIZE + 1, height - 2);
555 return true;
556 }
557 return false;
558 }
559
560 // Returns true if the associated internal frame has focus.
561 protected boolean isActiveFrame() {
562 return frame.isSelected();
563 }
564 }
565
566 public static void drawBezel(Graphics g, int x, int y, int w, int h,
567 boolean isPressed, boolean hasFocus,
568 Color shadow, Color highlight,
569 Color darkShadow, Color focus) {
570
571 Color oldColor = g.getColor();
572 g.translate(x, y);
573
574 if (isPressed) {
575 if (hasFocus){
576 g.setColor(focus);
577 g.drawRect(0, 0, w-1, h-1);
578 }
579 g.setColor(shadow); // inner border
580 g.drawRect(1, 1, w-3, h-3);
581
582 g.setColor(highlight); // inner 3D border
583 g.drawLine(2, h-3, w-3, h-3);
584 g.drawLine(w-3, 2, w-3, h-4);
585
586 } else {
587 if (hasFocus) {
588 g.setColor(focus);
589 g.drawRect(0, 0, w-1, h-1);
590
591 g.setColor(highlight); // inner 3D border
592 g.drawLine(1, 1, 1, h-3);
593 g.drawLine(2, 1, w-4, 1);
594
595 g.setColor(shadow);
596 g.drawLine(2, h-3, w-3, h-3);
597 g.drawLine(w-3, 1, w-3, h-4);
598
599 g.setColor(darkShadow); // black drop shadow __|
600 g.drawLine(1, h-2, w-2, h-2);
601 g.drawLine(w-2, h-2, w-2, 1);
602 } else {
603 g.setColor(highlight); // inner 3D border
604 g.drawLine(1,1,1,h-3);
605 g.drawLine(2,1,w-4,1);
606 g.setColor(shadow);
607 g.drawLine(2,h-3,w-3,h-3);
608 g.drawLine(w-3,1,w-3,h-4);
609
610 g.setColor(darkShadow); // black drop shadow __|
611 g.drawLine(1,h-2,w-2,h-2);
612 g.drawLine(w-2,h-2,w-2,0);
613
614 }
615 g.translate(-x, -y);
616 }
617 g.setColor(oldColor);
618 }
619
620 public static class MotifPopupMenuBorder extends AbstractBorder implements UIResource {
621 protected Font font;
622 protected Color background;
623 protected Color foreground;
624 protected Color shadowColor;
625 protected Color highlightColor;
626
627 // Space between the border and text
628 static protected final int TEXT_SPACING = 2;
629
630 // Space for the separator under the title
631 static protected final int GROOVE_HEIGHT = 2;
632
633 /**
634 * Creates a MotifPopupMenuBorder instance
635 *
636 */
637 public MotifPopupMenuBorder(
638 Font titleFont,
639 Color bgColor,
640 Color fgColor,
641 Color shadow,
642 Color highlight) {
643 this.font = titleFont;
644 this.background = bgColor;
645 this.foreground = fgColor;
646 this.shadowColor = shadow;
647 this.highlightColor = highlight;
648 }
649
650 /**
651 * Paints the border for the specified component with the
652 * specified position and size.
653 * @param c the component for which this border is being painted
654 * @param g the paint graphics
655 * @param x the x position of the painted border
656 * @param y the y position of the painted border
657 * @param width the width of the painted border
658 * @param height the height of the painted border
659 */
660 public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
661
662 Font origFont = g.getFont();
663 Color origColor = g.getColor();
664 JPopupMenu popup = (JPopupMenu)c;
665
666 String title = popup.getLabel();
667 if (title == null) {
668 return;
669 }
670
671 g.setFont(font);
672
673 FontMetrics fm = SwingUtilities2.getFontMetrics(popup, g, font);
674 int fontHeight = fm.getHeight();
675 int descent = fm.getDescent();
676 int ascent = fm.getAscent();
677 Point textLoc = new Point();
678 int stringWidth = SwingUtilities2.stringWidth(popup, fm,
679 title);
680
681 textLoc.y = y + ascent + TEXT_SPACING;
682 textLoc.x = x + ((width - stringWidth) / 2);
683
684 g.setColor(background);
685 g.fillRect(textLoc.x - TEXT_SPACING, textLoc.y - (fontHeight-descent),
686 stringWidth + (2 * TEXT_SPACING), fontHeight - descent);
687 g.setColor(foreground);
688 SwingUtilities2.drawString(popup, g, title, textLoc.x, textLoc.y);
689
690 MotifGraphicsUtils.drawGroove(g, x, textLoc.y + TEXT_SPACING,
691 width, GROOVE_HEIGHT,
692 shadowColor, highlightColor);
693
694 g.setFont(origFont);
695 g.setColor(origColor);
696 }
697
698 /**
699 * Reinitialize the insets parameter with this Border's current Insets.
700 * @param c the component for which this border insets value applies
701 * @param insets the object to be reinitialized
702 */
703 public Insets getBorderInsets(Component c, Insets insets) {
704 FontMetrics fm;
705 int descent = 0;
706 int ascent = 16;
707
708 String title = ((JPopupMenu)c).getLabel();
709 if (title == null) {
710 insets.left = insets.top = insets.right = insets.bottom = 0;
711 return insets;
712 }
713
714 fm = c.getFontMetrics(font);
715
716 if(fm != null) {
717 descent = fm.getDescent();
718 ascent = fm.getAscent();
719 }
720
721 insets.top += ascent + descent + TEXT_SPACING + GROOVE_HEIGHT;
722 return insets;
723 }
724
725 }
726
727}