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