home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 November / Chip_1998-11_cd.bin / tema / Cafe / jfc.bin / BasicGraphicsUtils.java < prev    next >
Text File  |  1998-02-26  |  20KB  |  645 lines

  1. /*
  2.  * @(#)BasicGraphicsUtils.java    1.34 98/02/04
  3.  *
  4.  * Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
  5.  *
  6.  * This software is the confidential and proprietary information of Sun
  7.  * Microsystems, Inc. ("Confidential Information").  You shall not
  8.  * disclose such Confidential Information and shall use it only in
  9.  * accordance with the terms of the license agreement you entered into
  10.  * with Sun.
  11.  *
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
  13.  * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  14.  * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  15.  * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
  16.  * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
  17.  * THIS SOFTWARE OR ITS DERIVATIVES.
  18.  *
  19.  */
  20. package com.sun.java.swing.plaf.basic;
  21.  
  22. import com.sun.java.swing.*;
  23. import java.awt.Color;
  24. import java.awt.Dimension;
  25. import java.awt.Font;
  26. import java.awt.FontMetrics;
  27. import java.awt.Graphics;
  28. import java.awt.Insets;
  29. import java.awt.Rectangle;
  30. import java.awt.event.KeyEvent;
  31.  
  32.  
  33.  
  34. /*
  35.  * @version 1.34 02/04/98
  36.  * @author Hans Muller
  37.  */
  38.  
  39. public class BasicGraphicsUtils
  40. {
  41.     public static final Font controlFont = new Font("Dialog", Font.PLAIN, 12);
  42.  
  43.     public static Color control = Color.lightGray;
  44.     public static Color controlShadow = Color.gray;
  45.     public static Color controlHighlight = Color.white;
  46.     public static Color controlBlack = Color.black;
  47.     public static Color controlWhite = Color.white;
  48.     public static Color scrollbarTrack = new Color(224, 224, 224);
  49.     public static Color toolTip = new Color(255, 255, 225);
  50.  
  51.     private static final Insets GROOVE_INSETS = new Insets(2, 2, 2, 2);
  52.     private static final Insets ETCHED_INSETS = new Insets(2, 2, 2, 2);
  53.  
  54.     public static void drawEtchedRect(Graphics g, int x, int y, int w, int h)
  55.     {
  56.     Color oldColor = g.getColor();    // Make no net change to g
  57.     g.translate(x, y);
  58.  
  59.     g.setColor(controlShadow);
  60.     g.drawLine(0, 0, w-1, 0);      // outer border, top
  61.     g.drawLine(0, 1, 0, h-2);      // outer border, left
  62.  
  63.     g.setColor(controlBlack);
  64.     g.drawLine(1, 1, w-3, 1);      // inner border, top
  65.     g.drawLine(1, 2, 1, h-3);      // inner border, left
  66.  
  67.     g.setColor(controlWhite);
  68.     g.drawLine(w-1, 0, w-1, h-1);  // outer border, bottom
  69.     g.drawLine(0, h-1, w-1, h-1);  // outer border, right
  70.  
  71.     g.setColor(control);
  72.     g.drawLine(w-2, 1, w-2, h-3);  // inner border, right
  73.     g.drawLine(1, h-2, w-3, h-2);  // inner border, bottom
  74.  
  75.     g.translate(-x, -y);
  76.     g.setColor(oldColor);
  77.     }
  78.  
  79.  
  80.     /**
  81.      * Returns the amount of space taken up by a border drawn by
  82.      * <code>drawEtchedRect()</code>
  83.      *
  84.      * @return    the inset of an etched rect
  85.      */
  86.     public static Insets getEtchedInsets() {
  87.     return ETCHED_INSETS;
  88.     }
  89.  
  90.  
  91.     public static void drawGroove(Graphics g, int x, int y, int w, int h)
  92.     {
  93.     Color oldColor = g.getColor();    // Make no net change to g
  94.     g.translate(x, y);
  95.  
  96.     g.setColor(controlShadow);
  97.     g.drawRect(0, 0, w-2, h-2);
  98.  
  99.     g.setColor(controlWhite);
  100.     g.drawLine(1, h-3, 1, 1);
  101.     g.drawLine(1, 1, w-3, 1);
  102.  
  103.     g.drawLine(0, h-1, w-1, h-1);
  104.     g.drawLine(w-1, h-1, w-1, 0);
  105.  
  106.     g.translate(-x, -y);
  107.     g.setColor(oldColor);
  108.     }
  109.  
  110.     /**
  111.      * Returns the amount of space taken up by a border drawn by
  112.      * <code>drawGroove()</code>
  113.      *
  114.      * @return    the inset of a groove border
  115.      */
  116.     public static Insets getGrooveInsets() {
  117.     return GROOVE_INSETS;
  118.     }
  119.  
  120.  
  121.     public static void drawBezel(Graphics g, int x, int y, int w, int h, boolean isPressed, boolean isDefault)
  122.     {
  123.     Color oldColor = g.getColor();    // Make no net change to g
  124.     g.translate(x, y);
  125.  
  126.     if (isPressed) {
  127.             if (isDefault) {
  128.             g.setColor(controlBlack);          // outer border
  129.             g.drawRect(0, 0, w-1, h-1);
  130.             }
  131.  
  132.         g.setColor(controlShadow);         // inner border
  133.         g.drawRect(1, 1, w-3, h-3);
  134.  
  135.     }
  136.     else {
  137.         if (isDefault) {
  138.         g.setColor(controlBlack);       // outer border
  139.         g.drawRect(0, 0, w-1, h-1);
  140.  
  141.         g.setColor(controlHighlight);   // inner 3D border
  142.         g.drawLine(1, 1, 1, h-3);
  143.         g.drawLine(2, 1, w-4, 1);
  144.  
  145.         g.setColor(controlShadow);
  146.         g.drawLine(2, h-3, w-3, h-3);
  147.         g.drawLine(w-3, 1, w-3, h-4);
  148.  
  149.         g.setColor(Color.black);        // black drop shadow  __|
  150.         g.drawLine(1, h-2, w-2, h-2);
  151.         g.drawLine(w-2, h-2, w-2, 1);
  152.         }
  153.         else {
  154.         g.setColor(controlHighlight);    // inner 3D border
  155.         g.drawLine(0, 0, 0, h-1);
  156.         g.drawLine(1, 0, w-3, 0);
  157.  
  158.         g.setColor(controlShadow);
  159.         g.drawLine(1, h-2, w-2, h-2);
  160.         g.drawLine(w-2, 0, w-2, h-3);
  161.  
  162.         g.setColor(Color.black);         // black drop shadow  __|
  163.         g.drawLine(0, h-1, w-1, h-1);
  164.         g.drawLine(w-1, h-1, w-1, 0);
  165.         }
  166.  
  167.         g.translate(-x, -y);
  168.         g.setColor(oldColor);
  169.     }
  170.     }
  171.  
  172.     public static void drawLoweredBezel(Graphics g, int x, int y, int w, int h)  {
  173.         g.setColor(controlBlack);    // inner 3D border
  174.         g.drawLine(0, 0, 0, h-1);
  175.         g.drawLine(1, 0, w-3, 0);
  176.  
  177.         g.setColor(controlShadow);
  178.         g.drawLine(1, 1, 1, h-2);
  179.         g.drawLine(1, 1, w-3, 1);
  180.  
  181.         g.setColor(controlHighlight);         
  182.         g.drawLine(0, h-1, w-1, h-1);
  183.         g.drawLine(w-1, h-1, w-1, 0);
  184.      }
  185.  
  186.  
  187.     /** Draw a string with the graphics g at location (x,y) just like g.drawString() would.
  188.      *  The first occurence of underlineChar in text will be underlined. The matching is
  189.      *  not case sensitive.
  190.      */
  191.     public static void drawString(Graphics g,String text,int underlinedChar,int x,int y) {
  192.  
  193.         char b[] = new char[1];
  194.         String s;
  195.         char lc,uc;
  196.         int index=-1,lci,uci;
  197.  
  198.         if(underlinedChar != '\0') {
  199.             b[0] = (char)underlinedChar;
  200.             s = new String(b).toUpperCase();
  201.             uc = s.charAt(0);
  202.  
  203.             s = new String(b).toLowerCase();
  204.             lc = s.charAt(0);
  205.  
  206.             uci = text.indexOf(uc);
  207.             lci = text.indexOf(lc);
  208.  
  209.             if(uci == -1)
  210.                 index = lci;
  211.             else if(lci == -1)
  212.                 index = uci;
  213.             else
  214.                 index = (lci < uci) ? lci : uci;
  215.         }
  216.  
  217.         g.drawString(text,x,y);
  218.         if(index != -1) {
  219.             FontMetrics fm = g.getFontMetrics();
  220.             Rectangle underlineRect = new Rectangle();
  221.             underlineRect.x = x + fm.stringWidth(text.substring(0,index));
  222.             underlineRect.y = y;
  223.             underlineRect.width = fm.charWidth(text.charAt(index));
  224.             underlineRect.height = 1;
  225.             g.fillRect(underlineRect.x,underlineRect.y + fm.getDescent() - 1,
  226.                        underlineRect.width,underlineRect.height);
  227.         }
  228.     }
  229.  
  230.  
  231.     public static void drawDashedRect(Graphics g,int x,int y,int width,int height) {
  232.         int vx,vy;
  233.  
  234.         // draw upper and lower horizontal dashes
  235.         for (vx = x; vx < (x + width); vx+=2) {
  236.             g.drawLine(vx, y, vx, y);
  237.             g.drawLine(vx, y + height-1, vx, y + height-1);
  238.         }
  239.  
  240.         // draw left and right vertical dashes
  241.         for (vy = y; vy < (y + height); vy+=2) {
  242.             g.drawLine(x, vy, x, vy);
  243.             g.drawLine(x+width-1, vy, x + width-1, vy);
  244.         }
  245.     }
  246.  
  247.  
  248.     public static void paintMenuItem(Graphics g, JComponent c,
  249.                      Icon checkIcon, Icon arrowIcon,
  250.                      Color background, Color foreground,
  251.                      int defaultTextIconGap) {
  252.         JMenuItem b = (JMenuItem) c;
  253.         ButtonModel model = b.getModel();
  254.  
  255.         Dimension size = b.getSize();
  256.     Insets i = c.getInsets();
  257.  
  258.         Rectangle viewRect = new Rectangle(size);
  259.  
  260.     viewRect.x += i.left;
  261.     viewRect.y += i.top;
  262.     viewRect.width -= (i.right + viewRect.x);
  263.     viewRect.height -= (i.bottom + viewRect.y);
  264.  
  265.         Rectangle iconRect = new Rectangle();
  266.         Rectangle textRect = new Rectangle();
  267.         Rectangle acceleratorRect = new Rectangle();
  268.         Rectangle checkRect = new Rectangle();
  269.         Rectangle arrowRect = new Rectangle();
  270.  
  271.     Font holdf = g.getFont();
  272.     Font f = c.getFont();
  273.     g.setFont( f );
  274.         FontMetrics fm = g.getFontMetrics( f );
  275.     FontMetrics fmAccel = g.getFontMetrics( UIManager.getFont("MenuItem.acceleratorFont") );
  276.  
  277.     // Paint background
  278.     Color holdc = g.getColor();
  279.     if(c.isOpaque()) {
  280.         if (model.isArmed()|| (c instanceof JMenu && model.isSelected())) {
  281.         g.setColor(background);
  282.         g.fillRect(0,0, size.width, size.height);
  283.         } else {
  284.         g.setColor(b.getBackground());
  285.         g.fillRect(0,0, size.width, size.height);
  286.         }
  287.         g.setColor(holdc);
  288.     }
  289.  
  290.     // get Accelerator text
  291.     KeyStroke accelerator =  b.getAccelerator();
  292.     String acceleratorText = "";
  293.     if (accelerator != null) {
  294.         int modifiers = accelerator.getModifiers();
  295.         if (modifiers > 0) {
  296.         acceleratorText = KeyEvent.getKeyModifiersText(modifiers);
  297.         acceleratorText += "+";
  298.       }
  299.         acceleratorText += KeyEvent.getKeyText(accelerator.getKeyCode());
  300.     }
  301.     
  302.     // layout the text and icon
  303.         String text = layoutMenuItem(
  304.         fm, b.getText(), fmAccel, acceleratorText, b.getIcon(),
  305.         checkIcon, arrowIcon,
  306.         b.getVerticalAlignment(), b.getHorizontalAlignment(),
  307.         b.getVerticalTextPosition(), b.getHorizontalTextPosition(),
  308.         viewRect, iconRect, textRect, acceleratorRect, 
  309.         checkRect, arrowRect,
  310.         b.getText() == null ? 0 : defaultTextIconGap,
  311.         defaultTextIconGap
  312.     );
  313.       
  314.     // Paint the Check
  315.     if (checkIcon != null) {
  316.         if(model.isArmed() || (c instanceof JMenu && model.isSelected())) {
  317.         g.setColor(foreground);
  318.         } else {
  319.         g.setColor(b.getForeground());
  320.         }
  321.         checkIcon.paintIcon(c, g, checkRect.x, checkRect.y);
  322.         g.setColor(holdc);
  323.     }
  324.  
  325.     // Paint the Icon
  326.         if(b.getIcon() != null) { 
  327.             Icon icon;
  328.             if(!model.isEnabled()) {
  329.                 icon = (Icon) b.getDisabledIcon();
  330.             } else if(model.isPressed() && model.isArmed()) {
  331.                 icon = (Icon) b.getPressedIcon();
  332.                 if(icon == null) {
  333.                     // Use default icon
  334.                     icon = (Icon) b.getIcon();
  335.                 } 
  336.             } else {
  337.                 icon = (Icon) b.getIcon();
  338.             }
  339.           
  340.            
  341.         icon.paintIcon(c, g, iconRect.x, iconRect.y);
  342.         }
  343.  
  344.     // Draw the Text
  345.         if(text != null && !text.equals("")) {
  346.             if(!model.isEnabled()) {
  347.                 // *** paint the text disabled
  348.             if ( UIManager.get("MenuItem.disabledForeground") instanceof Color )
  349.         {
  350.           g.setColor( UIManager.getColor("MenuItem.disabledForeground") );
  351.           BasicGraphicsUtils.drawString(g,text,model.getMnemonic(),
  352.                         textRect.x, textRect.y + fm.getAscent());
  353.         }
  354.         else
  355.         {
  356.           g.setColor(b.getBackground().brighter());
  357.           BasicGraphicsUtils.drawString(g,text,model.getMnemonic(),
  358.                         textRect.x, textRect.y + fm.getAscent());
  359.           g.setColor(b.getBackground().darker());
  360.           BasicGraphicsUtils.drawString(g,text,model.getMnemonic(),
  361.                         textRect.x - 1, textRect.y + fm.getAscent() - 1);
  362.         }
  363.             } else {
  364.                 // *** paint the text normally
  365.         if (model.isArmed()|| (c instanceof JMenu && model.isSelected())) {
  366.             g.setColor(foreground);
  367.         } else {
  368.             g.setColor(b.getForeground());
  369.         }
  370.                 BasicGraphicsUtils.drawString(g,text, 
  371.                           model.getMnemonic(),
  372.                                               textRect.x,
  373.                                               textRect.y + fm.getAscent());
  374.             }
  375.         }
  376.       
  377.     // Draw the Accelerator Text
  378.         if(acceleratorText != null && !acceleratorText.equals("")) {
  379.         g.setFont( UIManager.getFont("MenuItem.acceleratorFont") );
  380.             if(!model.isEnabled()) {
  381.                 // *** paint the acceleratorText disabled
  382.             if ( UIManager.get("MenuItem.disabledForeground") instanceof Color )
  383.         {
  384.           g.setColor( UIManager.getColor("MenuItem.disabledForeground") );
  385.           BasicGraphicsUtils.drawString(g,acceleratorText,model.getMnemonic(),
  386.                         acceleratorRect.x, acceleratorRect.y + fm.getAscent());
  387.         }
  388.         else
  389.         {
  390.           g.setColor(b.getBackground().brighter());
  391.           BasicGraphicsUtils.drawString(g,acceleratorText,model.getMnemonic(),
  392.                         acceleratorRect.x, acceleratorRect.y + fm.getAscent());
  393.           g.setColor(b.getBackground().darker());
  394.           BasicGraphicsUtils.drawString(g,acceleratorText,model.getMnemonic(),
  395.                         acceleratorRect.x - 1, acceleratorRect.y + fm.getAscent() - 1);
  396.         }
  397.             } else {
  398.                 // *** paint the acceleratorText normally
  399.         if (model.isArmed()|| (c instanceof JMenu && model.isSelected())) {
  400.             g.setColor( UIManager.getColor("MenuItem.acceleratorPressedForeground") );
  401.         } else {
  402.             g.setColor( UIManager.getColor("MenuItem.acceleratorForeground") );
  403.         }
  404.                 BasicGraphicsUtils.drawString(g,acceleratorText, 
  405.                           model.getMnemonic(),
  406.                                               acceleratorRect.x,
  407.                                               acceleratorRect.y + fm.getAscent());
  408.             }
  409.         }
  410.  
  411.     // Paint the Arrow
  412.     if (arrowIcon != null) {
  413.         if(model.isArmed() || (c instanceof JMenu &&model.isSelected()))
  414.         g.setColor(foreground);
  415.         if( !(b.getParent() instanceof JMenuBar) )
  416.         arrowIcon.paintIcon(c, g, arrowRect.x, arrowRect.y);
  417.     }
  418.     g.setColor(holdc);
  419.     g.setFont(holdf);
  420.     }
  421.  
  422.  
  423.     public static Dimension getPreferredButtonSize(AbstractButton b, int textIconGap)
  424.     {
  425.     if(b.getComponentCount() > 0) {
  426.         return null;
  427.     }
  428.  
  429.         Icon icon = (Icon) b.getIcon();
  430.         String text = b.getText();
  431.  
  432.         Font font = b.getFont();
  433.         FontMetrics fm = b.getToolkit().getFontMetrics(font);
  434.       
  435.         Rectangle iconR = new Rectangle();
  436.         Rectangle textR = new Rectangle();
  437.         Rectangle viewR = new Rectangle(Short.MAX_VALUE, Short.MAX_VALUE);
  438.  
  439.         SwingUtilities.layoutCompoundLabel(
  440.         fm, text, icon,
  441.         b.getVerticalAlignment(), b.getHorizontalAlignment(),
  442.         b.getVerticalTextPosition(), b.getHorizontalTextPosition(),
  443.         viewR, iconR, textR, (text == null ? 0 : textIconGap)
  444.     );
  445.  
  446.     /* The preferred size of the button is the size of 
  447.      * the text and icon rectangles plus the buttons insets.
  448.      */
  449.  
  450.         Rectangle r = iconR.union(textR);
  451.  
  452.     Insets insets = b.getInsets();
  453.     r.width += insets.left + insets.right;
  454.     r.height += insets.top + insets.bottom;
  455.  
  456.     /* Ensure that the width and height of the button is odd,
  457.      * to allow for the focus line.
  458.      */
  459.  
  460.         if(r.width % 2 == 0) { r.width += 1; }
  461.         if(r.height % 2 == 0) { r.height += 1; }
  462.  
  463.         return r.getSize();
  464.     }
  465.  
  466.  
  467.  
  468.  
  469.     /** 
  470.      * Compute and return the location of the icons origin, the 
  471.      * location of origin of the text baseline, and a possibly clipped
  472.      * version of the compound labels string.  Locations are computed
  473.      * relative to the viewR rectangle. 
  474.      */
  475.  
  476.     public static String layoutMenuItem(
  477.         FontMetrics fm,
  478.         String text,
  479.         FontMetrics fmAccel,
  480.         String acceleratorText,
  481.         Icon icon,
  482.         Icon checkIcon,
  483.         Icon arrowIcon,
  484.     int verticalAlignment,
  485.     int horizontalAlignment,
  486.     int verticalTextPosition,
  487.     int horizontalTextPosition,
  488.         Rectangle viewR, 
  489.     Rectangle iconR, 
  490.     Rectangle textR,
  491.     Rectangle acceleratorR,
  492.     Rectangle checkIconR, 
  493.     Rectangle arrowIconR, 
  494.     int textIconGap,
  495.     int menuItemGap
  496.     )
  497.     {
  498.  
  499.     SwingUtilities.layoutCompoundLabel(fm, text, icon, verticalAlignment, 
  500.                 horizontalAlignment, verticalTextPosition, 
  501.                 horizontalTextPosition, viewR, iconR, textR, 
  502.                 textIconGap);
  503.  
  504.     /* Initialize the acceelratorText bounds rectangle textR.  If a null 
  505.      * or and empty String was specified we substitute "" here 
  506.      * and use 0,0,0,0 for acceleratorTextR.
  507.      */
  508.  
  509.     boolean acceleratorTextIsEmpty = (acceleratorText == null) || 
  510.         acceleratorText.equals("");
  511.  
  512.     if (acceleratorTextIsEmpty) {
  513.         acceleratorR.width = acceleratorR.height = 0;
  514.         acceleratorText = "";
  515.     }
  516.     else {
  517.         acceleratorR.width = SwingUtilities.computeStringWidth( fmAccel, acceleratorText );
  518.         acceleratorR.height = fmAccel.getHeight();
  519.     }
  520.  
  521.     /* Initialize the checkIcon bounds rectangle checkIconR.
  522.      */
  523.  
  524.     if (checkIcon != null) {
  525.         checkIconR.width = checkIcon.getIconWidth();
  526.         checkIconR.height = checkIcon.getIconHeight();
  527.     } 
  528.     else {
  529.         checkIconR.width = checkIconR.height = 0;
  530.     }
  531.  
  532.     /* Initialize the arrowIcon bounds rectangle arrowIconR.
  533.      */
  534.  
  535.     if (arrowIcon != null) {
  536.         arrowIconR.width = arrowIcon.getIconWidth();
  537.         arrowIconR.height = arrowIcon.getIconHeight();
  538.     } 
  539.     else {
  540.         arrowIconR.width = arrowIconR.height = 0;
  541.     }
  542.     
  543.     textR.x += checkIconR.width + menuItemGap;
  544.     iconR.x += checkIconR.width + menuItemGap;
  545.  
  546.     Rectangle labelR = iconR.union(textR);
  547.  
  548.     // Position the Accelerator text rect
  549.     acceleratorR.x += (viewR.width - arrowIconR.width - 
  550.                menuItemGap - acceleratorR.width);
  551.     acceleratorR.y = viewR.y + (viewR.height/2) - (acceleratorR.height/2);
  552.  
  553.     arrowIconR.x += (viewR.width - arrowIconR.width);
  554.     arrowIconR.y = viewR.y + (labelR.height/2) - (arrowIconR.height/2);
  555.  
  556.      checkIconR.y = viewR.y + (labelR.height/2) - (checkIconR.height/2);
  557.      checkIconR.x += viewR.x;
  558.  
  559.     /*
  560.       System.out.println("Layout: v=" +viewR+"  c="+checkIconR+" i="+
  561.       iconR+" t="+textR+" acc="+acceleratorR+" a="+arrowIconR);
  562.       */
  563.     return text;
  564.     }
  565.  
  566.     public static Dimension getPreferredMenuItemSize(JComponent c,
  567.                              Icon checkIcon,
  568.                              Icon arrowIcon,
  569.                              int defaultTextIconGap) {
  570.         JMenuItem b = (JMenuItem) c;
  571.         Icon icon = (Icon) b.getIcon(); 
  572.     String text = b.getText();
  573.     KeyStroke accelerator =  b.getAccelerator();
  574.     String acceleratorText = "";
  575.  
  576.     if (accelerator != null) {
  577.         int modifiers = accelerator.getModifiers();
  578.         if (modifiers > 0) {
  579.         acceleratorText = KeyEvent.getKeyModifiersText(modifiers);
  580.         acceleratorText += "+";
  581.       }
  582.         acceleratorText += KeyEvent.getKeyText(accelerator.getKeyCode());
  583.     }
  584.  
  585.         Font font = b.getFont();
  586.     FontMetrics fm = b.getToolkit().getFontMetrics(font);
  587.     FontMetrics fmAccel = b.getToolkit().getFontMetrics( UIManager.getFont("MenuItem.acceleratorFont") );
  588.  
  589.     Rectangle iconR = new Rectangle();
  590.     Rectangle textR = new Rectangle();
  591.     Rectangle acceleratorR = new Rectangle();
  592.     Rectangle checkIconR = new Rectangle();
  593.     Rectangle arrowIconR = new Rectangle();
  594.     Rectangle viewR = new Rectangle(Short.MAX_VALUE, Short.MAX_VALUE);
  595.     
  596.     layoutMenuItem(
  597.           fm, text, fmAccel, acceleratorText, icon, checkIcon, arrowIcon,
  598.           b.getVerticalAlignment(), b.getHorizontalAlignment(),
  599.           b.getVerticalTextPosition(), b.getHorizontalTextPosition(),
  600.           viewR, iconR, textR, acceleratorR, checkIconR, arrowIconR,
  601.           text == null ? 0 : defaultTextIconGap,
  602.           defaultTextIconGap
  603.           );
  604.         // find the union of the icon and text rects
  605.         Rectangle r = iconR.union(textR);
  606.  
  607.     // Add in the accelerator
  608.     boolean acceleratorTextIsEmpty = (acceleratorText == null) || 
  609.         acceleratorText.equals("");
  610.  
  611.     if (!acceleratorTextIsEmpty) {
  612.         r.width += acceleratorR.width;
  613.         r.width += 7*defaultTextIconGap;
  614.     }
  615.  
  616.     // Add in the checkIcon
  617.     r.width += checkIconR.width;
  618.     r.width += 2*defaultTextIconGap;
  619.  
  620.     // Add in the arrowIcon
  621.     r.width += 2*defaultTextIconGap;
  622.     r.width += arrowIconR.width;
  623.     
  624.     Insets insets = b.getInsets();
  625.     r.width += insets.left + insets.right;
  626.     r.height += insets.top + insets.bottom;
  627.  
  628.         // if the width is even, bump it up one. This is critical
  629.     // for the focus dash line to draw properly
  630.         if(r.width%2 == 0) {
  631.             r.width++;
  632.         }
  633.  
  634.         // if the height is even, bump it up one. This is critical
  635.     // for the text to center properly
  636.         if(r.height%2 == 0) {
  637.             r.height++;
  638.         }
  639.      
  640.         return r.getSize();
  641.     }
  642.  
  643. }
  644.  
  645.