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