Save This Page
Home » openjdk-7 » javax » swing » plaf » synth » [javadoc | source]
    1   /*
    2    * Copyright (c) 2002, 2011, 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   package javax.swing.plaf.synth;
   26   
   27   import sun.swing.SwingUtilities2;
   28   import sun.swing.MenuItemLayoutHelper;
   29   
   30   import java.awt;
   31   import javax.swing;
   32   import javax.swing.plaf.basic.BasicHTML;
   33   import javax.swing.text;
   34   import sun.swing.plaf.synth;
   35   
   36   /**
   37    * Wrapper for primitive graphics calls.
   38    *
   39    * @since 1.5
   40    * @author Scott Violet
   41    */
   42   public class SynthGraphicsUtils {
   43       // These are used in the text painting code to avoid allocating a bunch of
   44       // garbage.
   45       private Rectangle paintIconR = new Rectangle();
   46       private Rectangle paintTextR = new Rectangle();
   47       private Rectangle paintViewR = new Rectangle();
   48       private Insets paintInsets = new Insets(0, 0, 0, 0);
   49   
   50       // These Rectangles/Insets are used in the text size calculation to avoid a
   51       // a bunch of garbage.
   52       private Rectangle iconR = new Rectangle();
   53       private Rectangle textR = new Rectangle();
   54       private Rectangle viewR = new Rectangle();
   55       private Insets viewSizingInsets = new Insets(0, 0, 0, 0);
   56   
   57       /**
   58        * Creates a <code>SynthGraphicsUtils</code>.
   59        */
   60       public SynthGraphicsUtils() {
   61       }
   62   
   63       /**
   64        * Draws a line between the two end points.
   65        *
   66        * @param context Identifies hosting region.
   67        * @param paintKey Identifies the portion of the component being asked
   68        *                 to paint, may be null.
   69        * @param g Graphics object to paint to
   70        * @param x1 x origin
   71        * @param y1 y origin
   72        * @param x2 x destination
   73        * @param y2 y destination
   74        */
   75       public void drawLine(SynthContext context, Object paintKey,
   76                            Graphics g, int x1, int y1, int x2, int y2) {
   77           g.drawLine(x1, y1, x2, y2);
   78       }
   79   
   80       /**
   81        * Draws a line between the two end points.
   82        * <p>This implementation supports only one line style key,
   83        * <code>"dashed"</code>. The <code>"dashed"</code> line style is applied
   84        * only to vertical and horizontal lines.
   85        * <p>Specifying <code>null</code> or any key different from
   86        * <code>"dashed"</code> will draw solid lines.
   87        *
   88        * @param context identifies hosting region
   89        * @param paintKey identifies the portion of the component being asked
   90        *                 to paint, may be null
   91        * @param g Graphics object to paint to
   92        * @param x1 x origin
   93        * @param y1 y origin
   94        * @param x2 x destination
   95        * @param y2 y destination
   96        * @param styleKey identifies the requested style of the line (e.g. "dashed")
   97        * @since 1.6
   98        */
   99       public void drawLine(SynthContext context, Object paintKey,
  100                            Graphics g, int x1, int y1, int x2, int y2,
  101                            Object styleKey) {
  102           if ("dashed".equals(styleKey)) {
  103               // draw vertical line
  104               if (x1 == x2) {
  105                   y1 += (y1 % 2);
  106   
  107                   for (int y = y1; y <= y2; y+=2) {
  108                       g.drawLine(x1, y, x2, y);
  109                   }
  110               // draw horizontal line
  111               } else if (y1 == y2) {
  112                   x1 += (x1 % 2);
  113   
  114                   for (int x = x1; x <= x2; x+=2) {
  115                       g.drawLine(x, y1, x, y2);
  116                   }
  117               // oblique lines are not supported
  118               }
  119           } else {
  120               drawLine(context, paintKey, g, x1, y1, x2, y2);
  121           }
  122       }
  123   
  124       /**
  125        * Lays out text and an icon returning, by reference, the location to
  126        * place the icon and text.
  127        *
  128        * @param ss SynthContext
  129        * @param fm FontMetrics for the Font to use, this may be ignored
  130        * @param text Text to layout
  131        * @param icon Icon to layout
  132        * @param hAlign horizontal alignment
  133        * @param vAlign vertical alignment
  134        * @param hTextPosition horizontal text position
  135        * @param vTextPosition vertical text position
  136        * @param viewR Rectangle to layout text and icon in.
  137        * @param iconR Rectangle to place icon bounds in
  138        * @param textR Rectangle to place text in
  139        * @param iconTextGap gap between icon and text
  140        */
  141       public String layoutText(SynthContext ss, FontMetrics fm,
  142                            String text, Icon icon, int hAlign,
  143                            int vAlign, int hTextPosition,
  144                            int vTextPosition, Rectangle viewR,
  145                            Rectangle iconR, Rectangle textR, int iconTextGap) {
  146           if (icon instanceof SynthIcon) {
  147               SynthIconWrapper wrapper = SynthIconWrapper.get((SynthIcon)icon,
  148                                                               ss);
  149               String formattedText = SwingUtilities.layoutCompoundLabel(
  150                         ss.getComponent(), fm, text, wrapper, vAlign, hAlign,
  151                         vTextPosition, hTextPosition, viewR, iconR, textR,
  152                         iconTextGap);
  153               SynthIconWrapper.release(wrapper);
  154               return formattedText;
  155           }
  156           return SwingUtilities.layoutCompoundLabel(
  157                         ss.getComponent(), fm, text, icon, vAlign, hAlign,
  158                         vTextPosition, hTextPosition, viewR, iconR, textR,
  159                         iconTextGap);
  160       }
  161   
  162       /**
  163        * Returns the size of the passed in string.
  164        *
  165        * @param ss SynthContext
  166        * @param font Font to use
  167        * @param metrics FontMetrics, may be ignored
  168        * @param text Text to get size of.
  169        */
  170       public int computeStringWidth(SynthContext ss, Font font,
  171                                     FontMetrics metrics, String text) {
  172           return SwingUtilities2.stringWidth(ss.getComponent(), metrics,
  173                                             text);
  174       }
  175   
  176       /**
  177        * Returns the minimum size needed to properly render an icon and text.
  178        *
  179        * @param ss SynthContext
  180        * @param font Font to use
  181        * @param text Text to layout
  182        * @param icon Icon to layout
  183        * @param hAlign horizontal alignment
  184        * @param vAlign vertical alignment
  185        * @param hTextPosition horizontal text position
  186        * @param vTextPosition vertical text position
  187        * @param iconTextGap gap between icon and text
  188        * @param mnemonicIndex Index into text to render the mnemonic at, -1
  189        *        indicates no mnemonic.
  190        */
  191       public Dimension getMinimumSize(SynthContext ss, Font font, String text,
  192                         Icon icon, int hAlign, int vAlign, int hTextPosition,
  193                         int vTextPosition, int iconTextGap, int mnemonicIndex) {
  194           JComponent c = ss.getComponent();
  195           Dimension size = getPreferredSize(ss, font, text, icon, hAlign,
  196                                             vAlign, hTextPosition, vTextPosition,
  197                                             iconTextGap, mnemonicIndex);
  198           View v = (View) c.getClientProperty(BasicHTML.propertyKey);
  199   
  200           if (v != null) {
  201               size.width -= v.getPreferredSpan(View.X_AXIS) -
  202                             v.getMinimumSpan(View.X_AXIS);
  203           }
  204           return size;
  205       }
  206   
  207       /**
  208        * Returns the maximum size needed to properly render an icon and text.
  209        *
  210        * @param ss SynthContext
  211        * @param font Font to use
  212        * @param text Text to layout
  213        * @param icon Icon to layout
  214        * @param hAlign horizontal alignment
  215        * @param vAlign vertical alignment
  216        * @param hTextPosition horizontal text position
  217        * @param vTextPosition vertical text position
  218        * @param iconTextGap gap between icon and text
  219        * @param mnemonicIndex Index into text to render the mnemonic at, -1
  220        *        indicates no mnemonic.
  221        */
  222       public Dimension getMaximumSize(SynthContext ss, Font font, String text,
  223                         Icon icon, int hAlign, int vAlign, int hTextPosition,
  224                         int vTextPosition, int iconTextGap, int mnemonicIndex) {
  225           JComponent c = ss.getComponent();
  226           Dimension size = getPreferredSize(ss, font, text, icon, hAlign,
  227                                             vAlign, hTextPosition, vTextPosition,
  228                                             iconTextGap, mnemonicIndex);
  229           View v = (View) c.getClientProperty(BasicHTML.propertyKey);
  230   
  231           if (v != null) {
  232               size.width += v.getMaximumSpan(View.X_AXIS) -
  233                             v.getPreferredSpan(View.X_AXIS);
  234           }
  235           return size;
  236       }
  237   
  238       /**
  239        * Returns the maximum height of the the Font from the passed in
  240        * SynthContext.
  241        *
  242        * @param context SynthContext used to determine font.
  243        * @return maximum height of the characters for the font from the passed
  244        *         in context.
  245        */
  246       public int getMaximumCharHeight(SynthContext context) {
  247           FontMetrics fm = context.getComponent().getFontMetrics(
  248               context.getStyle().getFont(context));
  249           return (fm.getAscent() + fm.getDescent());
  250       }
  251   
  252       /**
  253        * Returns the preferred size needed to properly render an icon and text.
  254        *
  255        * @param ss SynthContext
  256        * @param font Font to use
  257        * @param text Text to layout
  258        * @param icon Icon to layout
  259        * @param hAlign horizontal alignment
  260        * @param vAlign vertical alignment
  261        * @param hTextPosition horizontal text position
  262        * @param vTextPosition vertical text position
  263        * @param iconTextGap gap between icon and text
  264        * @param mnemonicIndex Index into text to render the mnemonic at, -1
  265        *        indicates no mnemonic.
  266        */
  267       public Dimension getPreferredSize(SynthContext ss, Font font, String text,
  268                         Icon icon, int hAlign, int vAlign, int hTextPosition,
  269                         int vTextPosition, int iconTextGap, int mnemonicIndex) {
  270           JComponent c = ss.getComponent();
  271           Insets insets = c.getInsets(viewSizingInsets);
  272           int dx = insets.left + insets.right;
  273           int dy = insets.top + insets.bottom;
  274   
  275           if (icon == null && (text == null || font == null)) {
  276               return new Dimension(dx, dy);
  277           }
  278           else if ((text == null) || ((icon != null) && (font == null))) {
  279               return new Dimension(SynthIcon.getIconWidth(icon, ss) + dx,
  280                                    SynthIcon.getIconHeight(icon, ss) + dy);
  281           }
  282           else {
  283               FontMetrics fm = c.getFontMetrics(font);
  284   
  285               iconR.x = iconR.y = iconR.width = iconR.height = 0;
  286               textR.x = textR.y = textR.width = textR.height = 0;
  287               viewR.x = dx;
  288               viewR.y = dy;
  289               viewR.width = viewR.height = Short.MAX_VALUE;
  290   
  291               layoutText(ss, fm, text, icon, hAlign, vAlign,
  292                      hTextPosition, vTextPosition, viewR, iconR, textR,
  293                      iconTextGap);
  294               int x1 = Math.min(iconR.x, textR.x);
  295               int x2 = Math.max(iconR.x + iconR.width, textR.x + textR.width);
  296               int y1 = Math.min(iconR.y, textR.y);
  297               int y2 = Math.max(iconR.y + iconR.height, textR.y + textR.height);
  298               Dimension rv = new Dimension(x2 - x1, y2 - y1);
  299   
  300               rv.width += dx;
  301               rv.height += dy;
  302               return rv;
  303           }
  304       }
  305   
  306       /**
  307        * Paints text at the specified location. This will not attempt to
  308        * render the text as html nor will it offset by the insets of the
  309        * component.
  310        *
  311        * @param ss SynthContext
  312        * @param g Graphics used to render string in.
  313        * @param text Text to render
  314        * @param bounds Bounds of the text to be drawn.
  315        * @param mnemonicIndex Index to draw string at.
  316        */
  317       public void paintText(SynthContext ss, Graphics g, String text,
  318                             Rectangle bounds, int mnemonicIndex) {
  319           paintText(ss, g, text, bounds.x, bounds.y, mnemonicIndex);
  320       }
  321   
  322       /**
  323        * Paints text at the specified location. This will not attempt to
  324        * render the text as html nor will it offset by the insets of the
  325        * component.
  326        *
  327        * @param ss SynthContext
  328        * @param g Graphics used to render string in.
  329        * @param text Text to render
  330        * @param x X location to draw text at.
  331        * @param y Upper left corner to draw text at.
  332        * @param mnemonicIndex Index to draw string at.
  333        */
  334       public void paintText(SynthContext ss, Graphics g, String text,
  335                             int x, int y, int mnemonicIndex) {
  336           if (text != null) {
  337               JComponent c = ss.getComponent();
  338               FontMetrics fm = SwingUtilities2.getFontMetrics(c, g);
  339               y += fm.getAscent();
  340               SwingUtilities2.drawStringUnderlineCharAt(c, g, text,
  341                                                         mnemonicIndex, x, y);
  342           }
  343       }
  344   
  345       /**
  346        * Paints an icon and text. This will render the text as html, if
  347        * necessary, and offset the location by the insets of the component.
  348        *
  349        * @param ss SynthContext
  350        * @param g Graphics to render string and icon into
  351        * @param text Text to layout
  352        * @param icon Icon to layout
  353        * @param hAlign horizontal alignment
  354        * @param vAlign vertical alignment
  355        * @param hTextPosition horizontal text position
  356        * @param vTextPosition vertical text position
  357        * @param iconTextGap gap between icon and text
  358        * @param mnemonicIndex Index into text to render the mnemonic at, -1
  359        *        indicates no mnemonic.
  360        * @param textOffset Amount to offset the text when painting
  361        */
  362       public void paintText(SynthContext ss, Graphics g, String text,
  363                         Icon icon, int hAlign, int vAlign, int hTextPosition,
  364                         int vTextPosition, int iconTextGap, int mnemonicIndex,
  365                         int textOffset) {
  366           if ((icon == null) && (text == null)) {
  367               return;
  368           }
  369           JComponent c = ss.getComponent();
  370           FontMetrics fm = SwingUtilities2.getFontMetrics(c, g);
  371           Insets insets = SynthLookAndFeel.getPaintingInsets(ss, paintInsets);
  372   
  373           paintViewR.x = insets.left;
  374           paintViewR.y = insets.top;
  375           paintViewR.width = c.getWidth() - (insets.left + insets.right);
  376           paintViewR.height = c.getHeight() - (insets.top + insets.bottom);
  377   
  378           paintIconR.x = paintIconR.y = paintIconR.width = paintIconR.height = 0;
  379           paintTextR.x = paintTextR.y = paintTextR.width = paintTextR.height = 0;
  380   
  381           String clippedText =
  382               layoutText(ss, fm, text, icon, hAlign, vAlign,
  383                      hTextPosition, vTextPosition, paintViewR, paintIconR,
  384                      paintTextR, iconTextGap);
  385   
  386           if (icon != null) {
  387               Color color = g.getColor();
  388   
  389               if (ss.getStyle().getBoolean(ss, "TableHeader.alignSorterArrow", false) &&
  390                   "TableHeader.renderer".equals(c.getName())) {
  391                   paintIconR.x = paintViewR.width - paintIconR.width;
  392               } else {
  393                   paintIconR.x += textOffset;
  394               }
  395               paintIconR.y += textOffset;
  396               SynthIcon.paintIcon(icon, ss, g, paintIconR.x, paintIconR.y,
  397                                   paintIconR.width, paintIconR.height);
  398               g.setColor(color);
  399           }
  400   
  401           if (text != null) {
  402               View v = (View) c.getClientProperty(BasicHTML.propertyKey);
  403   
  404               if (v != null) {
  405                   v.paint(g, paintTextR);
  406               } else {
  407                   paintTextR.x += textOffset;
  408                   paintTextR.y += textOffset;
  409   
  410                   paintText(ss, g, clippedText, paintTextR, mnemonicIndex);
  411               }
  412           }
  413       }
  414   
  415   
  416        /**
  417         * A quick note about how preferred sizes are calculated... Generally
  418         * speaking, SynthPopupMenuUI will run through the list of its children
  419         * (from top to bottom) and ask each for its preferred size.  Each menu
  420         * item will add up the max width of each element (icons, text,
  421         * accelerator spacing, accelerator text or arrow icon) encountered thus
  422         * far, so by the time all menu items have been calculated, we will
  423         * know the maximum (preferred) menu item size for that popup menu.
  424         * Later when it comes time to paint each menu item, we can use those
  425         * same accumulated max element sizes in order to layout the item.
  426         */
  427       static Dimension getPreferredMenuItemSize(SynthContext context,
  428              SynthContext accContext, JComponent c,
  429              Icon checkIcon, Icon arrowIcon, int defaultTextIconGap,
  430              String acceleratorDelimiter, boolean useCheckAndArrow,
  431              String propertyPrefix) {
  432   
  433            JMenuItem mi = (JMenuItem) c;
  434            SynthMenuItemLayoutHelper lh = new SynthMenuItemLayoutHelper(
  435                    context, accContext, mi, checkIcon, arrowIcon,
  436                    MenuItemLayoutHelper.createMaxRect(), defaultTextIconGap,
  437                    acceleratorDelimiter, SynthLookAndFeel.isLeftToRight(mi),
  438                    useCheckAndArrow, propertyPrefix);
  439   
  440            Dimension result = new Dimension();
  441   
  442            // Calculate the result width
  443            int gap = lh.getGap();
  444            result.width = 0;
  445            MenuItemLayoutHelper.addMaxWidth(lh.getCheckSize(), gap, result);
  446            MenuItemLayoutHelper.addMaxWidth(lh.getLabelSize(), gap, result);
  447            MenuItemLayoutHelper.addWidth(lh.getMaxAccOrArrowWidth(), 5 * gap, result);
  448            // The last gap is unnecessary
  449            result.width -= gap;
  450   
  451            // Calculate the result height
  452            result.height = MenuItemLayoutHelper.max(lh.getCheckSize().getHeight(),
  453                    lh.getLabelSize().getHeight(), lh.getAccSize().getHeight(),
  454                    lh.getArrowSize().getHeight());
  455   
  456            // Take into account menu item insets
  457            Insets insets = lh.getMenuItem().getInsets();
  458            if (insets != null) {
  459                result.width += insets.left + insets.right;
  460                result.height += insets.top + insets.bottom;
  461            }
  462   
  463            // if the width is even, bump it up one. This is critical
  464            // for the focus dash lhne to draw properly
  465            if (result.width % 2 == 0) {
  466                result.width++;
  467            }
  468   
  469            // if the height is even, bump it up one. This is critical
  470            // for the text to center properly
  471            if (result.height % 2 == 0) {
  472                result.height++;
  473            }
  474   
  475            return result;
  476        }
  477   
  478       static void applyInsets(Rectangle rect, Insets insets, boolean leftToRight) {
  479           if (insets != null) {
  480               rect.x += (leftToRight ? insets.left : insets.right);
  481               rect.y += insets.top;
  482               rect.width -= (leftToRight ? insets.right : insets.left) + rect.x;
  483               rect.height -= (insets.bottom + rect.y);
  484           }
  485       }
  486   
  487       static void paint(SynthContext context, SynthContext accContext, Graphics g,
  488                  Icon checkIcon, Icon arrowIcon, String acceleratorDelimiter,
  489                  int defaultTextIconGap, String propertyPrefix) {
  490           JMenuItem mi = (JMenuItem) context.getComponent();
  491           SynthStyle style = context.getStyle();
  492           g.setFont(style.getFont(context));
  493   
  494           Rectangle viewRect = new Rectangle(0, 0, mi.getWidth(), mi.getHeight());
  495           boolean leftToRight = SynthLookAndFeel.isLeftToRight(mi);
  496           applyInsets(viewRect, mi.getInsets(), leftToRight);
  497   
  498           SynthMenuItemLayoutHelper lh = new SynthMenuItemLayoutHelper(
  499                   context, accContext, mi, checkIcon, arrowIcon, viewRect,
  500                   defaultTextIconGap, acceleratorDelimiter, leftToRight,
  501                   MenuItemLayoutHelper.useCheckAndArrow(mi), propertyPrefix);
  502           MenuItemLayoutHelper.LayoutResult lr = lh.layoutMenuItem();
  503   
  504           paintMenuItem(g, lh, lr);
  505       }
  506   
  507       static void paintMenuItem(Graphics g, SynthMenuItemLayoutHelper lh,
  508                                 MenuItemLayoutHelper.LayoutResult lr) {
  509           // Save original graphics font and color
  510           Font holdf = g.getFont();
  511           Color holdc = g.getColor();
  512   
  513           paintCheckIcon(g, lh, lr);
  514           paintIcon(g, lh, lr);
  515           paintText(g, lh, lr);
  516           paintAccText(g, lh, lr);
  517           paintArrowIcon(g, lh, lr);
  518   
  519           // Restore original graphics font and color
  520           g.setColor(holdc);
  521           g.setFont(holdf);
  522       }
  523   
  524       static void paintBackground(Graphics g, SynthMenuItemLayoutHelper lh) {
  525           paintBackground(lh.getContext(), g, lh.getMenuItem());
  526       }
  527   
  528       static void paintBackground(SynthContext context, Graphics g, JComponent c) {
  529           context.getPainter().paintMenuItemBackground(context, g, 0, 0,
  530                   c.getWidth(), c.getHeight());
  531       }
  532   
  533       static void paintIcon(Graphics g, SynthMenuItemLayoutHelper lh,
  534                             MenuItemLayoutHelper.LayoutResult lr) {
  535           if (lh.getIcon() != null) {
  536               Icon icon;
  537               JMenuItem mi = lh.getMenuItem();
  538               ButtonModel model = mi.getModel();
  539               if (!model.isEnabled()) {
  540                   icon = mi.getDisabledIcon();
  541               } else if (model.isPressed() && model.isArmed()) {
  542                   icon = mi.getPressedIcon();
  543                   if (icon == null) {
  544                       // Use default icon
  545                       icon = mi.getIcon();
  546                   }
  547               } else {
  548                   icon = mi.getIcon();
  549               }
  550   
  551               if (icon != null) {
  552                   Rectangle iconRect = lr.getIconRect();
  553                   SynthIcon.paintIcon(icon, lh.getContext(), g, iconRect.x,
  554                           iconRect.y, iconRect.width, iconRect.height);
  555               }
  556           }
  557       }
  558   
  559       static void paintCheckIcon(Graphics g, SynthMenuItemLayoutHelper lh,
  560                                  MenuItemLayoutHelper.LayoutResult lr) {
  561           if (lh.getCheckIcon() != null) {
  562               Rectangle checkRect = lr.getCheckRect();
  563               SynthIcon.paintIcon(lh.getCheckIcon(), lh.getContext(), g,
  564                       checkRect.x, checkRect.y, checkRect.width, checkRect.height);
  565           }
  566       }
  567   
  568       static void paintAccText(Graphics g, SynthMenuItemLayoutHelper lh,
  569                                MenuItemLayoutHelper.LayoutResult lr) {
  570           String accText = lh.getAccText();
  571           if (accText != null && !accText.equals("")) {
  572               g.setColor(lh.getAccStyle().getColor(lh.getAccContext(),
  573                       ColorType.TEXT_FOREGROUND));
  574               g.setFont(lh.getAccStyle().getFont(lh.getAccContext()));
  575               lh.getAccGraphicsUtils().paintText(lh.getAccContext(), g, accText,
  576                       lr.getAccRect().x, lr.getAccRect().y, -1);
  577           }
  578       }
  579   
  580       static void paintText(Graphics g, SynthMenuItemLayoutHelper lh,
  581                             MenuItemLayoutHelper.LayoutResult lr) {
  582           if (!lh.getText().equals("")) {
  583               if (lh.getHtmlView() != null) {
  584                   // Text is HTML
  585                   lh.getHtmlView().paint(g, lr.getTextRect());
  586               } else {
  587                   // Text isn't HTML
  588                   g.setColor(lh.getStyle().getColor(
  589                           lh.getContext(), ColorType.TEXT_FOREGROUND));
  590                   g.setFont(lh.getStyle().getFont(lh.getContext()));
  591                   lh.getGraphicsUtils().paintText(lh.getContext(), g, lh.getText(),
  592                           lr.getTextRect().x, lr.getTextRect().y,
  593                           lh.getMenuItem().getDisplayedMnemonicIndex());
  594               }
  595           }
  596       }
  597   
  598       static void paintArrowIcon(Graphics g, SynthMenuItemLayoutHelper lh,
  599                                  MenuItemLayoutHelper.LayoutResult lr) {
  600           if (lh.getArrowIcon() != null) {
  601               Rectangle arrowRect = lr.getArrowRect();
  602               SynthIcon.paintIcon(lh.getArrowIcon(), lh.getContext(), g,
  603                       arrowRect.x, arrowRect.y, arrowRect.width, arrowRect.height);
  604           }
  605       }
  606   
  607       /**
  608        * Wraps a SynthIcon around the Icon interface, forwarding calls to
  609        * the SynthIcon with a given SynthContext.
  610        */
  611       private static class SynthIconWrapper implements Icon {
  612           private static final java.util.List<SynthIconWrapper> CACHE = new java.util.ArrayList<SynthIconWrapper>(1);
  613   
  614           private SynthIcon synthIcon;
  615           private SynthContext context;
  616   
  617           static SynthIconWrapper get(SynthIcon icon, SynthContext context) {
  618               synchronized(CACHE) {
  619                   int size = CACHE.size();
  620                   if (size > 0) {
  621                       SynthIconWrapper wrapper = CACHE.remove(size - 1);
  622                       wrapper.reset(icon, context);
  623                       return wrapper;
  624                   }
  625               }
  626               return new SynthIconWrapper(icon, context);
  627           }
  628   
  629           static void release(SynthIconWrapper wrapper) {
  630               wrapper.reset(null, null);
  631               synchronized(CACHE) {
  632                   CACHE.add(wrapper);
  633               }
  634           }
  635   
  636           SynthIconWrapper(SynthIcon icon, SynthContext context) {
  637               reset(icon, context);
  638           }
  639   
  640           void reset(SynthIcon icon, SynthContext context) {
  641               synthIcon = icon;
  642               this.context = context;
  643           }
  644   
  645           public void paintIcon(Component c, Graphics g, int x, int y) {
  646               // This is a noop as this should only be for sizing calls.
  647           }
  648   
  649           public int getIconWidth() {
  650               return synthIcon.getIconWidth(context);
  651           }
  652   
  653           public int getIconHeight() {
  654               return synthIcon.getIconHeight(context);
  655           }
  656       }
  657   }

Save This Page
Home » openjdk-7 » javax » swing » plaf » synth » [javadoc | source]