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