jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifBorders.java
changeset 25859 3317bb8137f4
parent 23632 cd7a34d12e8c
child 31164 a61c96d50ddd
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifBorders.java	Sun Aug 17 15:54:13 2014 +0100
@@ -0,0 +1,742 @@
+/*
+ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.java.swing.plaf.motif;
+
+import sun.swing.SwingUtilities2;
+import javax.swing.*;
+import javax.swing.border.*;
+import javax.swing.plaf.*;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Insets;
+import java.awt.Point;
+import java.awt.Rectangle;
+
+/**
+ * Factory object that can vend Icons appropriate for the basic L & F.
+ * <p>
+ * <strong>Warning:</strong>
+ * Serialized objects of this class will not be compatible with
+ * future Swing releases.  The current serialization support is appropriate
+ * for short term storage or RMI between applications running the same
+ * version of Swing.  A future release of Swing will provide support for
+ * long term persistence.
+ *
+ * @author Amy Fowler
+ */
+public class MotifBorders {
+
+    @SuppressWarnings("serial") // Superclass is not serializable across versions
+    public static class BevelBorder extends AbstractBorder implements UIResource {
+        private Color darkShadow = UIManager.getColor("controlShadow");
+        private Color lightShadow = UIManager.getColor("controlLtHighlight");
+        private boolean isRaised;
+
+        public BevelBorder(boolean isRaised, Color darkShadow, Color lightShadow) {
+            this.isRaised = isRaised;
+            this.darkShadow = darkShadow;
+            this.lightShadow = lightShadow;
+        }
+
+        public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) {
+            g.setColor((isRaised) ? lightShadow : darkShadow);
+            g.drawLine(x, y, x+w-1, y);           // top
+            g.drawLine(x, y+h-1, x, y+1);         // left
+
+            g.setColor((isRaised) ? darkShadow : lightShadow);
+            g.drawLine(x+1, y+h-1, x+w-1, y+h-1); // bottom
+            g.drawLine(x+w-1, y+h-1, x+w-1, y+1); // right
+        }
+
+        public Insets getBorderInsets(Component c, Insets insets) {
+            insets.set(1, 1, 1, 1);
+            return insets;
+        }
+
+        public boolean isOpaque(Component c) {
+            return true;
+        }
+
+    }
+
+
+    @SuppressWarnings("serial") // Superclass is not serializable across versions
+    public static class FocusBorder extends AbstractBorder implements UIResource {
+        private Color focus;
+        private Color control;
+
+        public FocusBorder(Color control, Color focus) {
+            this.control = control;
+            this.focus = focus;
+        }
+
+        public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) {
+            if (c.hasFocus()) {
+                g.setColor(focus);
+                g.drawRect(x, y, w-1, h-1);
+            } else {
+                g.setColor(control);
+                g.drawRect(x, y, w-1, h-1);
+            }
+        }
+
+        public Insets getBorderInsets(Component c, Insets insets) {
+            insets.set(1, 1, 1, 1);
+            return insets;
+        }
+    }
+
+
+    @SuppressWarnings("serial") // Superclass is not serializable across versions
+    public static class ButtonBorder extends AbstractBorder implements UIResource {
+        protected Color focus = UIManager.getColor("activeCaptionBorder");
+        protected Color shadow = UIManager.getColor("Button.shadow");
+        protected Color highlight = UIManager.getColor("Button.light");
+        protected Color darkShadow;
+
+        public ButtonBorder(Color shadow, Color highlight, Color darkShadow, Color focus) {
+            this.shadow = shadow;
+            this.highlight = highlight;
+            this.darkShadow = darkShadow;
+            this.focus = focus;
+        }
+
+        public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) {
+            boolean isPressed = false;
+            boolean hasFocus = false;
+            boolean canBeDefault = false;
+            boolean isDefault = false;
+
+            if (c instanceof AbstractButton) {
+                AbstractButton b = (AbstractButton)c;
+                ButtonModel model = b.getModel();
+
+                isPressed = (model.isArmed() && model.isPressed());
+                hasFocus = (model.isArmed() && isPressed) ||
+                           (b.isFocusPainted() && b.hasFocus());
+                if (b instanceof JButton) {
+                    canBeDefault = ((JButton)b).isDefaultCapable();
+                    isDefault = ((JButton)b).isDefaultButton();
+                }
+            }
+            int bx1 = x+1;
+            int by1 = y+1;
+            int bx2 = x+w-2;
+            int by2 = y+h-2;
+
+            if (canBeDefault) {
+                if (isDefault) {
+                    g.setColor(shadow);
+                    g.drawLine(x+3, y+3, x+3, y+h-4);
+                    g.drawLine(x+3, y+3, x+w-4, y+3);
+
+                    g.setColor(highlight);
+                    g.drawLine(x+4, y+h-4, x+w-4, y+h-4);
+                    g.drawLine(x+w-4, y+3, x+w-4, y+h-4);
+                }
+                bx1 +=6;
+                by1 += 6;
+                bx2 -= 6;
+                by2 -= 6;
+            }
+
+            if (hasFocus) {
+                g.setColor(focus);
+                if (isDefault) {
+                    g.drawRect(x, y, w-1, h-1);
+                } else {
+                    g.drawRect(bx1-1, by1-1, bx2-bx1+2, by2-by1+2);
+                }
+            }
+
+            g.setColor(isPressed? shadow : highlight);
+            g.drawLine(bx1, by1, bx2, by1);
+            g.drawLine(bx1, by1, bx1, by2);
+
+            g.setColor(isPressed? highlight : shadow);
+            g.drawLine(bx2, by1+1, bx2, by2);
+            g.drawLine(bx1+1, by2, bx2, by2);
+        }
+
+        public Insets getBorderInsets(Component c, Insets insets) {
+            int thickness = (c instanceof JButton && ((JButton)c).isDefaultCapable())? 8 : 2;
+            insets.set(thickness, thickness, thickness, thickness);
+            return insets;
+        }
+
+    }
+
+    @SuppressWarnings("serial") // Superclass is not serializable across versions
+    public static class ToggleButtonBorder extends ButtonBorder {
+
+        public ToggleButtonBorder(Color shadow, Color highlight, Color darkShadow, Color focus) {
+             super(shadow, highlight, darkShadow, focus);
+        }
+
+        public void paintBorder(Component c, Graphics g, int x, int y,
+                            int width, int height) {
+            if (c instanceof AbstractButton) {
+                AbstractButton b = (AbstractButton)c;
+                ButtonModel model = b.getModel();
+
+                if (model.isArmed() && model.isPressed() || model.isSelected()) {
+                    drawBezel(g, x, y, width, height,
+                              (model.isPressed() || model.isSelected()),
+                              b.isFocusPainted() && b.hasFocus(), shadow, highlight, darkShadow, focus);
+                } else {
+                    drawBezel(g, x, y, width, height,
+                              false, b.isFocusPainted() && b.hasFocus(),
+                              shadow, highlight, darkShadow, focus);
+                }
+            } else {
+                drawBezel(g, x, y, width, height, false, false,
+                          shadow, highlight, darkShadow, focus);
+            }
+        }
+
+        public Insets getBorderInsets(Component c, Insets insets) {
+            insets.set(2, 2, 3, 3);
+            return insets;
+        }
+    }
+
+    @SuppressWarnings("serial") // Superclass is not serializable across versions
+    public static class MenuBarBorder extends ButtonBorder {
+
+        public MenuBarBorder(Color shadow, Color highlight, Color darkShadow, Color focus) {
+            super(shadow, highlight, darkShadow, focus);
+        }
+
+        public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
+            if (!(c instanceof JMenuBar)) {
+                return;
+            }
+            JMenuBar menuBar = (JMenuBar)c;
+            if (menuBar.isBorderPainted() == true) {
+                // this draws the MenuBar border
+                Dimension size = menuBar.getSize();
+                drawBezel(g,x,y,size.width,size.height,false,false,
+                          shadow, highlight, darkShadow, focus);
+            }
+        }
+
+        public Insets getBorderInsets(Component c, Insets insets) {
+            insets.set(6, 6, 6, 6);
+            return insets;
+        }
+    }
+
+    @SuppressWarnings("serial") // Superclass is not serializable across versions
+    public static class FrameBorder extends AbstractBorder implements UIResource {
+
+        JComponent jcomp;
+        Color frameHighlight;
+        Color frameColor;
+        Color frameShadow;
+
+        // The width of the border
+        public final static int BORDER_SIZE = 5;
+
+        /** Constructs an FrameBorder for the JComponent <b>comp</b>.
+        */
+        public FrameBorder(JComponent comp) {
+            jcomp = comp;
+        }
+
+        /** Sets the FrameBorder's JComponent.
+      */
+        public void setComponent(JComponent comp) {
+            jcomp = comp;
+        }
+
+        /** Returns the FrameBorder's JComponent.
+          * @see #setComponent
+          */
+        public JComponent component() {
+            return jcomp;
+        }
+
+        protected Color getFrameHighlight() {
+            return frameHighlight;
+        }
+
+        protected Color getFrameColor() {
+            return frameColor;
+        }
+
+        protected Color getFrameShadow() {
+            return frameShadow;
+        }
+
+        public Insets getBorderInsets(Component c, Insets newInsets) {
+            newInsets.set(BORDER_SIZE, BORDER_SIZE, BORDER_SIZE, BORDER_SIZE);
+            return newInsets;
+        }
+
+       /** Draws the FrameBorder's top border.
+         */
+        protected boolean drawTopBorder(Component c, Graphics g,
+                                    int x, int y, int width, int height) {
+            Rectangle titleBarRect = new Rectangle(x, y, width, BORDER_SIZE);
+            if (!g.getClipBounds().intersects(titleBarRect)) {
+                return false;
+            }
+
+            int maxX = width - 1;
+            int maxY = BORDER_SIZE - 1;
+
+            // Draw frame
+            g.setColor(frameColor);
+            g.drawLine(x, y + 2, maxX - 2, y + 2);
+            g.drawLine(x, y + 3, maxX - 2, y + 3);
+            g.drawLine(x, y + 4, maxX - 2, y + 4);
+
+            // Draw highlights
+            g.setColor(frameHighlight);
+            g.drawLine(x, y, maxX, y);
+            g.drawLine(x, y + 1, maxX, y + 1);
+            g.drawLine(x, y + 2, x, y + 4);
+            g.drawLine(x + 1, y + 2, x + 1, y + 4);
+
+            // Draw shadows
+            g.setColor(frameShadow);
+            g.drawLine(x + 4, y + 4, maxX - 4, y + 4);
+            g.drawLine(maxX, y + 1, maxX, maxY);
+            g.drawLine(maxX - 1, y + 2, maxX - 1, maxY);
+
+            return true;
+        }
+
+        /** Draws the FrameBorder's left border.
+          */
+        protected boolean drawLeftBorder(Component c, Graphics g, int x, int y,
+                               int width, int height) {
+            Rectangle borderRect =
+                new Rectangle(0, 0, getBorderInsets(c).left, height);
+            if (!g.getClipBounds().intersects(borderRect)) {
+                return false;
+            }
+
+            int startY = BORDER_SIZE;
+
+            g.setColor(frameHighlight);
+            g.drawLine(x, startY, x, height - 1);
+            g.drawLine(x + 1, startY, x + 1, height - 2);
+
+            g.setColor(frameColor);
+            g.fillRect(x + 2, startY, x + 2, height - 3);
+
+            g.setColor(frameShadow);
+            g.drawLine(x + 4, startY, x + 4, height - 5);
+
+            return true;
+        }
+
+        /** Draws the FrameBorder's right border.
+          */
+        protected boolean drawRightBorder(Component c, Graphics g, int x, int y,
+                                int width, int height) {
+            Rectangle borderRect = new Rectangle(
+                width - getBorderInsets(c).right, 0,
+                getBorderInsets(c).right, height);
+            if (!g.getClipBounds().intersects(borderRect)) {
+                return false;
+            }
+
+            int startX = width - getBorderInsets(c).right;
+            int startY = BORDER_SIZE;
+
+            g.setColor(frameColor);
+            g.fillRect(startX + 1, startY, 2, height - 1);
+
+            g.setColor(frameShadow);
+            g.fillRect(startX + 3, startY, 2, height - 1);
+
+            g.setColor(frameHighlight);
+            g.drawLine(startX, startY, startX, height - 1);
+
+            return true;
+        }
+
+        /** Draws the FrameBorder's bottom border.
+          */
+        protected boolean drawBottomBorder(Component c, Graphics g, int x, int y,
+                                 int width, int height) {
+            Rectangle    borderRect;
+            int     marginHeight, startY;
+
+            borderRect = new Rectangle(0, height - getBorderInsets(c).bottom,
+                                  width, getBorderInsets(c).bottom);
+            if (!g.getClipBounds().intersects(borderRect)) {
+                return false;
+            }
+
+            startY = height - getBorderInsets(c).bottom;
+
+            g.setColor(frameShadow);
+            g.drawLine(x + 1, height - 1, width - 1, height - 1);
+            g.drawLine(x + 2, height - 2, width - 2, height - 2);
+
+            g.setColor(frameColor);
+            g.fillRect(x + 2, startY + 1, width - 4, 2);
+
+            g.setColor(frameHighlight);
+            g.drawLine(x + 5, startY, width - 5, startY);
+
+            return true;
+        }
+
+        // Returns true if the associated component has focus.
+        protected boolean isActiveFrame() {
+            return jcomp.hasFocus();
+        }
+
+        /** Draws the FrameBorder in the given Rect.  Calls
+          * <b>drawTitleBar</b>, <b>drawLeftBorder</b>, <b>drawRightBorder</b> and
+          * <b>drawBottomBorder</b>.
+          */
+        public void paintBorder(Component c, Graphics g,
+                            int x, int y, int width, int height) {
+            if (isActiveFrame()) {
+                frameColor = UIManager.getColor("activeCaptionBorder");
+            } else {
+                frameColor = UIManager.getColor("inactiveCaptionBorder");
+            }
+            frameHighlight = frameColor.brighter();
+            frameShadow = frameColor.darker().darker();
+
+            drawTopBorder(c, g, x, y, width, height);
+            drawLeftBorder(c, g, x, y, width, height);
+            drawRightBorder(c, g, x, y, width, height);
+            drawBottomBorder(c, g, x, y, width, height);
+        }
+    }
+
+    @SuppressWarnings("serial") // Superclass is not serializable across versions
+    public static class InternalFrameBorder extends FrameBorder {
+
+        JInternalFrame frame;
+
+        // The size of the bounding box for Motif frame corners.
+        public final static int CORNER_SIZE = 24;
+
+        /** Constructs an InternalFrameBorder for the InternalFrame
+          * <b>aFrame</b>.
+          */
+        public InternalFrameBorder(JInternalFrame aFrame) {
+            super(aFrame);
+            frame = aFrame;
+        }
+
+        /** Sets the InternalFrameBorder's InternalFrame.
+          */
+        public void setFrame(JInternalFrame aFrame) {
+            frame = aFrame;
+        }
+
+        /** Returns the InternalFrameBorder's InternalFrame.
+          * @see #setFrame
+          */
+        public JInternalFrame frame() {
+            return frame;
+        }
+
+        /** Returns the width of the InternalFrameBorder's resize controls,
+          * appearing along the InternalFrameBorder's bottom border.  Clicking
+          * and dragging within these controls lets the user change both the
+          * InternalFrame's width and height, while dragging between the controls
+          * constrains resizing to just the vertical dimension.  Override this
+          * method if you implement your own bottom border painting and use a
+          * resize control with a different size.
+          */
+        public int resizePartWidth() {
+            if (!frame.isResizable()) {
+                return 0;
+            }
+            return FrameBorder.BORDER_SIZE;
+        }
+
+        /** Draws the InternalFrameBorder's top border.
+         */
+        protected boolean drawTopBorder(Component c, Graphics g,
+                                    int x, int y, int width, int height) {
+            if (super.drawTopBorder(c, g, x, y, width, height) &&
+                frame.isResizable()) {
+                g.setColor(getFrameShadow());
+                g.drawLine(CORNER_SIZE - 1, y + 1, CORNER_SIZE - 1, y + 4);
+                g.drawLine(width - CORNER_SIZE - 1, y + 1,
+                       width - CORNER_SIZE - 1, y + 4);
+
+                g.setColor(getFrameHighlight());
+                g.drawLine(CORNER_SIZE, y, CORNER_SIZE, y + 4);
+                g.drawLine(width - CORNER_SIZE, y, width - CORNER_SIZE, y + 4);
+                return true;
+            }
+            return false;
+        }
+
+        /** Draws the InternalFrameBorder's left border.
+          */
+        protected boolean drawLeftBorder(Component c, Graphics g, int x, int y,
+                                     int width, int height) {
+            if (super.drawLeftBorder(c, g, x, y, width, height) &&
+                frame.isResizable()) {
+                g.setColor(getFrameHighlight());
+                int topY = y + CORNER_SIZE;
+                g.drawLine(x, topY, x + 4, topY);
+                int bottomY = height - CORNER_SIZE;
+                g.drawLine(x + 1, bottomY, x + 5, bottomY);
+                g.setColor(getFrameShadow());
+                g.drawLine(x + 1, topY - 1, x + 5, topY - 1);
+                g.drawLine(x + 1, bottomY - 1, x + 5, bottomY - 1);
+                return true;
+            }
+            return false;
+        }
+
+        /** Draws the InternalFrameBorder's right border.
+          */
+        protected boolean drawRightBorder(Component c, Graphics g, int x, int y,
+                                      int width, int height) {
+            if (super.drawRightBorder(c, g, x, y, width, height) &&
+                frame.isResizable()) {
+                int startX = width - getBorderInsets(c).right;
+                g.setColor(getFrameHighlight());
+                int topY = y + CORNER_SIZE;
+                g.drawLine(startX, topY, width - 2, topY);
+                int bottomY = height - CORNER_SIZE;
+                g.drawLine(startX + 1, bottomY, startX + 3, bottomY);
+                g.setColor(getFrameShadow());
+                g.drawLine(startX + 1, topY - 1, width - 2, topY - 1);
+                g.drawLine(startX + 1, bottomY - 1, startX + 3, bottomY - 1);
+                return true;
+            }
+            return false;
+        }
+
+        /** Draws the InternalFrameBorder's bottom border.
+          */
+        protected boolean drawBottomBorder(Component c, Graphics g, int x, int y,
+                                       int width, int height) {
+            if (super.drawBottomBorder(c, g, x, y, width, height) &&
+                frame.isResizable()) {
+                int startY = height - getBorderInsets(c).bottom;
+
+                g.setColor(getFrameShadow());
+                g.drawLine(CORNER_SIZE - 1, startY + 1,
+                       CORNER_SIZE - 1, height - 1);
+                g.drawLine(width - CORNER_SIZE, startY + 1,
+                       width - CORNER_SIZE, height - 1);
+
+                g.setColor(getFrameHighlight());
+                g.drawLine(CORNER_SIZE, startY, CORNER_SIZE, height - 2);
+                g.drawLine(width - CORNER_SIZE + 1, startY,
+                       width - CORNER_SIZE + 1, height - 2);
+                return true;
+            }
+            return false;
+        }
+
+        // Returns true if the associated internal frame has focus.
+        protected boolean isActiveFrame() {
+            return frame.isSelected();
+        }
+    }
+
+    public static void drawBezel(Graphics g, int x, int y, int w, int h,
+                               boolean isPressed, boolean hasFocus,
+                               Color shadow, Color highlight,
+                               Color darkShadow, Color focus)  {
+
+        Color oldColor = g.getColor();
+        g.translate(x, y);
+
+        if (isPressed) {
+            if (hasFocus){
+                g.setColor(focus);
+                g.drawRect(0, 0, w-1, h-1);
+            }
+            g.setColor(shadow);         // inner border
+            g.drawRect(1, 1, w-3, h-3);
+
+            g.setColor(highlight);    // inner 3D border
+            g.drawLine(2, h-3, w-3, h-3);
+            g.drawLine(w-3, 2, w-3, h-4);
+
+        } else {
+            if (hasFocus) {
+                g.setColor(focus);
+                g.drawRect(0, 0, w-1, h-1);
+
+                g.setColor(highlight);   // inner 3D border
+                g.drawLine(1, 1, 1, h-3);
+                g.drawLine(2, 1, w-4, 1);
+
+                g.setColor(shadow);
+                g.drawLine(2, h-3, w-3, h-3);
+                g.drawLine(w-3, 1, w-3, h-4);
+
+                g.setColor(darkShadow);        // black drop shadow  __|
+                g.drawLine(1, h-2, w-2, h-2);
+                g.drawLine(w-2, h-2, w-2, 1);
+            } else {
+                g.setColor(highlight);    // inner 3D border
+                g.drawLine(1,1,1,h-3);
+                g.drawLine(2,1,w-4,1);
+                g.setColor(shadow);
+                g.drawLine(2,h-3,w-3,h-3);
+                g.drawLine(w-3,1,w-3,h-4);
+
+                g.setColor(darkShadow);         // black drop shadow  __|
+                g.drawLine(1,h-2,w-2,h-2);
+                g.drawLine(w-2,h-2,w-2,0);
+
+            }
+            g.translate(-x, -y);
+        }
+        g.setColor(oldColor);
+    }
+
+    @SuppressWarnings("serial") // Superclass is not serializable across versions
+    public static class MotifPopupMenuBorder extends AbstractBorder implements UIResource {
+        protected Font   font;
+        protected Color  background;
+        protected Color  foreground;
+        protected Color  shadowColor;
+        protected Color  highlightColor;
+
+        // Space between the border and text
+        static protected final int TEXT_SPACING = 2;
+
+        // Space for the separator under the title
+        static protected final int GROOVE_HEIGHT = 2;
+
+        /**
+         * Creates a MotifPopupMenuBorder instance
+         *
+         */
+        public MotifPopupMenuBorder(
+                                    Font titleFont,
+                                    Color bgColor,
+                                    Color fgColor,
+                                    Color shadow,
+                                    Color highlight)       {
+            this.font = titleFont;
+            this.background = bgColor;
+            this.foreground = fgColor;
+            this.shadowColor = shadow;
+            this.highlightColor = highlight;
+        }
+
+        /**
+         * Paints the border for the specified component with the
+         * specified position and size.
+         * @param c the component for which this border is being painted
+         * @param g the paint graphics
+         * @param x the x position of the painted border
+         * @param y the y position of the painted border
+         * @param width the width of the painted border
+         * @param height the height of the painted border
+         */
+        public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
+            if (!(c instanceof JPopupMenu)) {
+                return;
+            }
+
+            Font origFont = g.getFont();
+            Color origColor = g.getColor();
+            JPopupMenu popup = (JPopupMenu)c;
+
+            String title = popup.getLabel();
+            if (title == null) {
+                return;
+            }
+
+            g.setFont(font);
+
+            FontMetrics fm = SwingUtilities2.getFontMetrics(popup, g, font);
+            int         fontHeight = fm.getHeight();
+            int         descent = fm.getDescent();
+            int         ascent = fm.getAscent();
+            Point       textLoc = new Point();
+            int         stringWidth = SwingUtilities2.stringWidth(popup, fm,
+                                                                  title);
+
+            textLoc.y = y + ascent + TEXT_SPACING;
+            textLoc.x = x + ((width - stringWidth) / 2);
+
+            g.setColor(background);
+            g.fillRect(textLoc.x - TEXT_SPACING, textLoc.y - (fontHeight-descent),
+                       stringWidth + (2 * TEXT_SPACING), fontHeight - descent);
+            g.setColor(foreground);
+            SwingUtilities2.drawString(popup, g, title, textLoc.x, textLoc.y);
+
+            MotifGraphicsUtils.drawGroove(g, x, textLoc.y + TEXT_SPACING,
+                                          width, GROOVE_HEIGHT,
+                                          shadowColor, highlightColor);
+
+            g.setFont(origFont);
+            g.setColor(origColor);
+        }
+
+        /**
+         * Reinitialize the insets parameter with this Border's current Insets.
+         * @param c the component for which this border insets value applies
+         * @param insets the object to be reinitialized
+         */
+        public Insets getBorderInsets(Component c, Insets insets) {
+            if (!(c instanceof JPopupMenu)) {
+                return insets;
+            }
+            FontMetrics fm;
+            int         descent = 0;
+            int         ascent = 16;
+
+            String title = ((JPopupMenu)c).getLabel();
+            if (title == null) {
+                insets.left = insets.top = insets.right = insets.bottom = 0;
+                return insets;
+            }
+
+            fm = c.getFontMetrics(font);
+
+            if(fm != null) {
+                descent = fm.getDescent();
+                ascent = fm.getAscent();
+            }
+
+            insets.top += ascent + descent + TEXT_SPACING + GROOVE_HEIGHT;
+            return insets;
+        }
+
+    }
+
+}