Source Code Cross Referenced for SynthMenuItemUI.java in  » 6.0-JDK-Core » swing » javax » swing » plaf » synth » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » swing » javax.swing.plaf.synth 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001        /*
002         * Copyright 2002-2006 Sun Microsystems, Inc.  All Rights Reserved.
003         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004         *
005         * This code is free software; you can redistribute it and/or modify it
006         * under the terms of the GNU General Public License version 2 only, as
007         * published by the Free Software Foundation.  Sun designates this
008         * particular file as subject to the "Classpath" exception as provided
009         * by Sun in the LICENSE file that accompanied this code.
010         *
011         * This code is distributed in the hope that it will be useful, but WITHOUT
012         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014         * version 2 for more details (a copy is included in the LICENSE file that
015         * accompanied this code).
016         *
017         * You should have received a copy of the GNU General Public License version
018         * 2 along with this work; if not, write to the Free Software Foundation,
019         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020         *
021         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022         * CA 95054 USA or visit www.sun.com if you need additional information or
023         * have any questions.
024         */
025        package javax.swing.plaf.synth;
026
027        import javax.swing.plaf.basic.BasicHTML;
028        import java.awt.*;
029        import java.awt.event.*;
030        import java.beans.PropertyChangeEvent;
031        import java.beans.PropertyChangeListener;
032
033        import javax.swing.*;
034        import javax.swing.event.*;
035        import javax.swing.border.*;
036        import javax.swing.plaf.*;
037        import javax.swing.plaf.basic.*;
038        import javax.swing.text.View;
039        import sun.swing.plaf.synth.*;
040        import sun.swing.SwingUtilities2;
041
042        /**
043         * Synth's MenuItemUI.
044         *
045         * @version 1.25, 01/25/05
046         * @author Georges Saab
047         * @author David Karlton
048         * @author Arnaud Weber
049         * @author Fredrik Lagerblad
050         */
051        class SynthMenuItemUI extends BasicMenuItemUI implements 
052                PropertyChangeListener, SynthUI {
053            private SynthStyle style;
054            private SynthStyle accStyle;
055
056            private String acceleratorDelimiter;
057
058            public static ComponentUI createUI(JComponent c) {
059                return new SynthMenuItemUI();
060            }
061
062            //
063            // The next handful of static methods are used by both SynthMenuUI
064            // and SynthMenuItemUI. This is necessitated by SynthMenuUI not
065            // extending SynthMenuItemUI.
066            //
067
068            /*
069             * All JMenuItems (and JMenus) include enough space for the insets
070             * plus one or more elements.  When we say "icon(s)" below, we mean
071             * "check/radio indicator and/or user icon."  If both are defined for
072             * a given menu item, then in a LTR orientation the check/radio indicator
073             * is on the left side followed by the user icon to the right; it is
074             * just the opposite in a RTL orientation.
075             *
076             * Cases to consider for SynthMenuItemUI (visualized here in a
077             * LTR orientation; the RTL case would be reversed):
078             *                text
079             *      icon(s) + text
080             *      icon(s) + text + accelerator
081             *                text + accelerator
082             *
083             * Cases to consider for SynthMenuUI (again visualized here in a
084             * LTR orientation):
085             *                text       + arrow
086             *   (user)icon + text       + arrow
087             *
088             * Note that in the above scenarios, accelerator and arrow icon are
089             * mutually exclusive.  This means that if a popup menu contains a mix
090             * of JMenus and JMenuItems, we only need to allow enough space for
091             * max(maxAccelerator, maxArrow), and both accelerators and arrow icons
092             * can occupy the same "column" of space in the menu.
093             *
094             * A quick note about how preferred sizes are calculated... Generally
095             * speaking, SynthPopupMenuUI will run through the list of its children
096             * (from top to bottom) and ask each for its preferred size.  Each menu
097             * item will add up the max width of each element (icons, text,
098             * accelerator spacing, accelerator text or arrow icon) encountered thus
099             * far, so by the time all menu items have been calculated, we will
100             * know the maximum (preferred) menu item size for that popup menu.
101             * Later when it comes time to paint each menu item, we can use those
102             * same accumulated max element sizes in order to layout the item.
103             */
104            static Dimension getPreferredMenuItemSize(SynthContext context,
105                    SynthContext accContext, JComponent c, Icon checkIcon,
106                    Icon arrowIcon, int defaultTextIconGap,
107                    String acceleratorDelimiter) {
108                JMenuItem b = (JMenuItem) c;
109                Icon icon = (Icon) b.getIcon();
110                String text = b.getText();
111                KeyStroke accelerator = b.getAccelerator();
112                String acceleratorText = "";
113
114                if (accelerator != null) {
115                    int modifiers = accelerator.getModifiers();
116                    if (modifiers > 0) {
117                        acceleratorText = KeyEvent
118                                .getKeyModifiersText(modifiers);
119                        acceleratorText += acceleratorDelimiter;
120                    }
121                    int keyCode = accelerator.getKeyCode();
122                    if (keyCode != 0) {
123                        acceleratorText += KeyEvent.getKeyText(keyCode);
124                    } else {
125                        acceleratorText += accelerator.getKeyChar();
126                    }
127                }
128
129                Font font = context.getStyle().getFont(context);
130                FontMetrics fm = b.getFontMetrics(font);
131                FontMetrics fmAccel = b.getFontMetrics(accContext.getStyle()
132                        .getFont(accContext));
133
134                resetRects();
135
136                layoutMenuItem(context, fm, accContext, text, fmAccel,
137                        acceleratorText, icon, checkIcon, arrowIcon, b
138                                .getVerticalAlignment(), b
139                                .getHorizontalAlignment(), b
140                                .getVerticalTextPosition(), b
141                                .getHorizontalTextPosition(), viewRect,
142                        iconRect, textRect, acceleratorRect, checkIconRect,
143                        arrowIconRect, text == null ? 0 : defaultTextIconGap,
144                        defaultTextIconGap);
145
146                r.setBounds(textRect);
147
148                int totalIconWidth = 0;
149                int maxIconHeight = 0;
150                if (icon != null) {
151                    // Add in the user icon
152                    totalIconWidth += iconRect.width;
153                    if (textRect.width > 0) {
154                        // Allow for some room between the user icon and the text
155                        totalIconWidth += defaultTextIconGap;
156                    }
157                    maxIconHeight = Math.max(iconRect.height, maxIconHeight);
158                }
159                if (checkIcon != null) {
160                    // Add in the checkIcon
161                    totalIconWidth += checkIconRect.width;
162                    if (textRect.width > 0 || icon != null) {
163                        // Allow for some room between the check/radio indicator
164                        // and the text (or user icon, if both are specified)
165                        totalIconWidth += defaultTextIconGap;
166                    }
167                    maxIconHeight = Math.max(checkIconRect.height,
168                            maxIconHeight);
169                }
170
171                int arrowWidth = 0;
172                if (arrowIcon != null) {
173                    // Add in the arrowIcon
174                    arrowWidth += defaultTextIconGap;
175                    arrowWidth += arrowIconRect.width;
176                    maxIconHeight = Math.max(arrowIconRect.height,
177                            maxIconHeight);
178                }
179
180                int accelSpacing = 0;
181                if (acceleratorRect.width > 0) {
182                    // Allow for some room between the text and the accelerator
183                    accelSpacing += 4 * defaultTextIconGap;
184                }
185
186                // Take text and all icons into account when determining height
187                r.height = Math.max(r.height, maxIconHeight);
188
189                // To make the accelerator texts appear in a column,
190                // find the widest MenuItem text and the widest accelerator text.
191
192                // Get the parent, which stores the information.
193                Container parent = b.getParent();
194
195                if (parent instanceof  JPopupMenu) {
196                    SynthPopupMenuUI popupUI = (SynthPopupMenuUI) SynthLookAndFeel
197                            .getUIOfType(((JPopupMenu) parent).getUI(),
198                                    SynthPopupMenuUI.class);
199
200                    if (popupUI != null) {
201                        // This gives us the widest MenuItem text encountered thus
202                        // far in the parent JPopupMenu
203                        r.width = popupUI.adjustTextWidth(r.width);
204
205                        // Add in the widest icon (includes both user and
206                        // check/radio icons) encountered thus far
207                        r.width += popupUI.adjustIconWidth(totalIconWidth);
208
209                        // Add in the widest text/accelerator spacing
210                        // encountered thus far
211                        r.width += popupUI
212                                .adjustAccelSpacingWidth(accelSpacing);
213
214                        // Add in the widest accelerator text (or arrow)
215                        // encountered thus far (at least one of these values
216                        // will always be zero, so we combine them here to
217                        // avoid double counting)
218                        int totalAccelOrArrow = acceleratorRect.width
219                                + arrowWidth;
220                        r.width += popupUI
221                                .adjustAcceleratorWidth(totalAccelOrArrow);
222                    }
223                } else if (parent != null
224                        && !(b instanceof  JMenu && ((JMenu) b).isTopLevelMenu())) {
225                    r.width += totalIconWidth + accelSpacing
226                            + acceleratorRect.width + arrowWidth;
227                }
228
229                Insets insets = b.getInsets();
230                if (insets != null) {
231                    r.width += insets.left + insets.right;
232                    r.height += insets.top + insets.bottom;
233                }
234
235                // if the width is even, bump it up one. This is critical
236                // for the focus dash line to draw properly
237                if (r.width % 2 == 0) {
238                    r.width++;
239                }
240
241                // if the height is even, bump it up one. This is critical
242                // for the text to center properly
243                if (r.height % 2 == 0) {
244                    r.height++;
245                }
246                return r.getSize();
247            }
248
249            static void paint(SynthContext context, SynthContext accContext,
250                    Graphics g, Icon checkIcon, Icon arrowIcon,
251                    String acceleratorDelimiter, int defaultTextIconGap) {
252                JComponent c = context.getComponent();
253                JMenuItem b = (JMenuItem) c;
254                ButtonModel model = b.getModel();
255                Insets i = b.getInsets();
256
257                resetRects();
258
259                viewRect.setBounds(0, 0, b.getWidth(), b.getHeight());
260
261                viewRect.x += i.left;
262                viewRect.y += i.top;
263                viewRect.width -= (i.right + viewRect.x);
264                viewRect.height -= (i.bottom + viewRect.y);
265
266                SynthStyle style = context.getStyle();
267                Font f = style.getFont(context);
268                g.setFont(f);
269                FontMetrics fm = SwingUtilities2.getFontMetrics(c, g, f);
270                FontMetrics accFM = SwingUtilities2.getFontMetrics(c, g,
271                        accContext.getStyle().getFont(accContext));
272
273                // get Accelerator text
274                KeyStroke accelerator = b.getAccelerator();
275                String acceleratorText = "";
276                if (accelerator != null) {
277                    int modifiers = accelerator.getModifiers();
278                    if (modifiers > 0) {
279                        acceleratorText = KeyEvent
280                                .getKeyModifiersText(modifiers);
281                        acceleratorText += acceleratorDelimiter;
282                    }
283
284                    int keyCode = accelerator.getKeyCode();
285                    if (keyCode != 0) {
286                        acceleratorText += KeyEvent.getKeyText(keyCode);
287                    } else {
288                        acceleratorText += accelerator.getKeyChar();
289                    }
290                }
291
292                // Layout the text and icon
293                String text = layoutMenuItem(context, fm, accContext, b
294                        .getText(), accFM, acceleratorText, b.getIcon(),
295                        checkIcon, arrowIcon, b.getVerticalAlignment(), b
296                                .getHorizontalAlignment(), b
297                                .getVerticalTextPosition(), b
298                                .getHorizontalTextPosition(), viewRect,
299                        iconRect, textRect, acceleratorRect, checkIconRect,
300                        arrowIconRect, b.getText() == null ? 0
301                                : defaultTextIconGap, defaultTextIconGap);
302
303                // Paint the Check
304                if (checkIcon != null) {
305                    SynthIcon.paintIcon(checkIcon, context, g, checkIconRect.x,
306                            checkIconRect.y, checkIconRect.width,
307                            checkIconRect.height);
308                }
309
310                // Paint the Icon
311                if (b.getIcon() != null) {
312                    Icon icon;
313                    if (!model.isEnabled()) {
314                        icon = (Icon) b.getDisabledIcon();
315                    } else if (model.isPressed() && model.isArmed()) {
316                        icon = (Icon) b.getPressedIcon();
317                        if (icon == null) {
318                            // Use default icon
319                            icon = (Icon) b.getIcon();
320                        }
321                    } else {
322                        icon = (Icon) b.getIcon();
323                    }
324
325                    if (icon != null) {
326                        SynthIcon.paintIcon(icon, context, g, iconRect.x,
327                                iconRect.y, iconRect.width, iconRect.height);
328                    }
329                }
330
331                // Draw the Text
332                if (text != null) {
333                    View v = (View) c.getClientProperty(BasicHTML.propertyKey);
334                    if (v != null) {
335                        v.paint(g, textRect);
336                    } else {
337                        g.setColor(style.getColor(context,
338                                ColorType.TEXT_FOREGROUND));
339                        g.setFont(style.getFont(context));
340                        style.getGraphicsUtils(context).paintText(context, g,
341                                text, textRect.x, textRect.y,
342                                b.getDisplayedMnemonicIndex());
343                    }
344                }
345
346                // Draw the Accelerator Text
347                if (acceleratorText != null && !acceleratorText.equals("")) {
348                    // Get the maxAccWidth from the parent to calculate the offset.
349                    int accOffset = 0;
350                    Container parent = b.getParent();
351                    if (parent != null && parent instanceof  JPopupMenu) {
352                        SynthPopupMenuUI popupUI = (SynthPopupMenuUI) ((JPopupMenu) parent)
353                                .getUI();
354
355                        // Note that we can only get here for SynthMenuItemUI
356                        // (not SynthMenuUI) since acceleratorText is defined,
357                        // so this cast should be safe
358                        SynthMenuItemUI miUI = (SynthMenuItemUI) SynthLookAndFeel
359                                .getUIOfType(b.getUI(), SynthMenuItemUI.class);
360
361                        if (popupUI != null && miUI != null) {
362                            String prop = miUI.getPropertyPrefix()
363                                    + ".alignAcceleratorText";
364                            boolean align = style.getBoolean(context, prop,
365                                    true);
366
367                            // Calculate the offset, with which the accelerator texts
368                            // will be drawn.
369                            if (align) {
370                                // When align==true and we're in the LTR case,
371                                // we add an offset here so that all accelerators
372                                // will be left-justified in their own column.
373                                int max = popupUI.getMaxAcceleratorWidth();
374                                if (max > 0) {
375                                    accOffset = max - acceleratorRect.width;
376                                    if (!SynthLookAndFeel.isLeftToRight(c)) {
377                                        // In the RTL, flip the sign so that all
378                                        // accelerators will be right-justified.
379                                        accOffset = -accOffset;
380                                    }
381                                }
382                            } //else {
383                            // Don't need to do anything special here; in the
384                            // LTR case, the accelerator is already justified
385                            // against the right edge of the menu (and against
386                            // the left edge in the RTL case).
387                            //}
388                        }
389                    }
390
391                    SynthStyle accStyle = accContext.getStyle();
392
393                    g.setColor(accStyle.getColor(accContext,
394                            ColorType.TEXT_FOREGROUND));
395                    g.setFont(accStyle.getFont(accContext));
396                    accStyle.getGraphicsUtils(accContext).paintText(accContext,
397                            g, acceleratorText, acceleratorRect.x - accOffset,
398                            acceleratorRect.y, -1);
399                }
400
401                // Paint the Arrow
402                if (arrowIcon != null) {
403                    SynthIcon.paintIcon(arrowIcon, context, g, arrowIconRect.x,
404                            arrowIconRect.y, arrowIconRect.width,
405                            arrowIconRect.height);
406                }
407            }
408
409            /** 
410             * Compute and return the location of the icons origin, the 
411             * location of origin of the text baseline, and a possibly clipped
412             * version of the compound labels string.  Locations are computed
413             * relative to the viewRect rectangle. 
414             */
415
416            private static String layoutMenuItem(SynthContext context,
417                    FontMetrics fm, SynthContext accContext, String text,
418                    FontMetrics fmAccel, String acceleratorText, Icon icon,
419                    Icon checkIcon, Icon arrowIcon, int verticalAlignment,
420                    int horizontalAlignment, int verticalTextPosition,
421                    int horizontalTextPosition, Rectangle viewRect,
422                    Rectangle iconRect, Rectangle textRect,
423                    Rectangle acceleratorRect, Rectangle checkIconRect,
424                    Rectangle arrowIconRect, int textIconGap, int menuItemGap) {
425                // If parent is JPopupMenu, get and store it's UI
426                SynthPopupMenuUI popupUI = null;
427                JComponent b = context.getComponent();
428                Container parent = b.getParent();
429                if (parent instanceof  JPopupMenu) {
430                    popupUI = (SynthPopupMenuUI) SynthLookAndFeel.getUIOfType(
431                            ((JPopupMenu) parent).getUI(),
432                            SynthPopupMenuUI.class);
433                }
434
435                context.getStyle().getGraphicsUtils(context).layoutText(
436                        context, fm, text, icon, horizontalAlignment,
437                        verticalAlignment, horizontalTextPosition,
438                        verticalTextPosition, viewRect, iconRect, textRect,
439                        textIconGap);
440
441                /* Initialize the acceleratorText bounds rectangle textRect.  If a null
442                 * or and empty String was specified we substitute "" here 
443                 * and use 0,0,0,0 for acceleratorTextRect.
444                 */
445                if ((acceleratorText == null) || acceleratorText.equals("")) {
446                    acceleratorRect.width = acceleratorRect.height = 0;
447                    acceleratorText = "";
448                } else {
449                    SynthStyle style = accContext.getStyle();
450                    acceleratorRect.width = style.getGraphicsUtils(accContext)
451                            .computeStringWidth(accContext, fmAccel.getFont(),
452                                    fmAccel, acceleratorText);
453                    acceleratorRect.height = fmAccel.getHeight();
454                }
455
456                // Initialize the checkIcon bounds rectangle width & height.
457                if (checkIcon != null) {
458                    checkIconRect.width = SynthIcon.getIconWidth(checkIcon,
459                            context);
460                    checkIconRect.height = SynthIcon.getIconHeight(checkIcon,
461                            context);
462                } else {
463                    checkIconRect.width = checkIconRect.height = 0;
464                }
465
466                // Initialize the arrowIcon bounds rectangle width & height.
467                if (arrowIcon != null) {
468                    arrowIconRect.width = SynthIcon.getIconWidth(arrowIcon,
469                            context);
470                    arrowIconRect.height = SynthIcon.getIconHeight(arrowIcon,
471                            context);
472                } else {
473                    arrowIconRect.width = arrowIconRect.height = 0;
474                }
475
476                // Note: layoutText() has already left room for
477                // the user icon, so no need to adjust textRect below
478                // to account for the user icon.  However, we do have to
479                // reposition textRect when the check icon is visible.
480
481                Rectangle labelRect = iconRect.union(textRect);
482                if (SynthLookAndFeel.isLeftToRight(context.getComponent())) {
483                    // Position the check and user icons 
484                    iconRect.x = viewRect.x;
485                    if (checkIcon != null) {
486                        checkIconRect.x = viewRect.x;
487                        iconRect.x += menuItemGap + checkIconRect.width;
488                        textRect.x += menuItemGap + checkIconRect.width;
489                    }
490
491                    // Position the arrow icon
492                    arrowIconRect.x = viewRect.x + viewRect.width
493                            - arrowIconRect.width;
494
495                    // Position the accelerator text rect
496                    acceleratorRect.x = viewRect.x + viewRect.width
497                            - acceleratorRect.width;
498
499                    /* Align icons and text horizontally */
500                    if (popupUI != null) {
501                        int this TextOffset = popupUI
502                                .adjustTextOffset(textRect.x - viewRect.x);
503                        textRect.x = this TextOffset + viewRect.x;
504
505                        if (icon != null) {
506                            // REMIND: The following code currently assumes the
507                            // default (TRAILING) horizontalTextPosition, which means
508                            // it will always place the icon to the left of the text.
509                            // Other values of horizontalTextPosition aren't very
510                            // useful for menu items, so we ignore them for now, but
511                            // someday we might want to fix this situation.
512                            int this IconOffset = popupUI
513                                    .adjustIconOffset(iconRect.x - viewRect.x);
514                            iconRect.x = this IconOffset + viewRect.x;
515                        }
516                    }
517                } else {
518                    // Position the accelerator text rect
519                    acceleratorRect.x = viewRect.x;
520
521                    // Position the arrow icon
522                    arrowIconRect.x = viewRect.x;
523
524                    // Position the check and user icons
525                    iconRect.x = viewRect.x + viewRect.width - iconRect.width;
526                    if (checkIcon != null) {
527                        checkIconRect.x = viewRect.x + viewRect.width
528                                - checkIconRect.width;
529                        textRect.x -= menuItemGap + checkIconRect.width;
530                        iconRect.x -= menuItemGap + checkIconRect.width;
531                    }
532
533                    /* Align icons and text horizontally */
534                    if (popupUI != null) {
535                        int this TextOffset = viewRect.x + viewRect.width
536                                - textRect.x - textRect.width;
537                        this TextOffset = popupUI
538                                .adjustTextOffset(this TextOffset);
539                        textRect.x = viewRect.x + viewRect.width
540                                - this TextOffset - textRect.width;
541                        if (icon != null) {
542                            // REMIND: The following code currently assumes the
543                            // default (TRAILING) horizontalTextPosition, which means
544                            // it will always place the icon to the right of the text.
545                            // Other values of horizontalTextPosition aren't very
546                            // useful for menu items, so we ignore them for now, but
547                            // someday we might want to fix this situation.
548                            int this IconOffset = viewRect.x + viewRect.width
549                                    - iconRect.x - iconRect.width;
550                            this IconOffset = popupUI
551                                    .adjustIconOffset(this IconOffset);
552                            iconRect.x = viewRect.x + viewRect.width
553                                    - this IconOffset - iconRect.width;
554                        }
555                    }
556                }
557
558                // Align the accelerator text and all icons vertically
559                // with the center of the label rect.  
560                int midY = labelRect.y + (labelRect.height / 2);
561                iconRect.y = midY - (iconRect.height / 2);
562                acceleratorRect.y = midY - (acceleratorRect.height / 2);
563                arrowIconRect.y = midY - (arrowIconRect.height / 2);
564                checkIconRect.y = midY - (checkIconRect.height / 2);
565
566                return text;
567            }
568
569            // these rects are used for painting and preferredsize calculations.
570            // they used to be regenerated constantly.  Now they are reused.
571            static Rectangle iconRect = new Rectangle();
572            static Rectangle textRect = new Rectangle();
573            static Rectangle acceleratorRect = new Rectangle();
574            static Rectangle checkIconRect = new Rectangle();
575            static Rectangle arrowIconRect = new Rectangle();
576            static Rectangle viewRect = new Rectangle(Short.MAX_VALUE,
577                    Short.MAX_VALUE);
578            static Rectangle r = new Rectangle();
579
580            private static void resetRects() {
581                iconRect.setBounds(0, 0, 0, 0);
582                textRect.setBounds(0, 0, 0, 0);
583                acceleratorRect.setBounds(0, 0, 0, 0);
584                checkIconRect.setBounds(0, 0, 0, 0);
585                arrowIconRect.setBounds(0, 0, 0, 0);
586                viewRect.setBounds(0, 0, Short.MAX_VALUE, Short.MAX_VALUE);
587                r.setBounds(0, 0, 0, 0);
588            }
589
590            protected void installDefaults() {
591                updateStyle(menuItem);
592            }
593
594            protected void installListeners() {
595                super .installListeners();
596                menuItem.addPropertyChangeListener(this );
597            }
598
599            private void updateStyle(JMenuItem mi) {
600                SynthContext context = getContext(mi, ENABLED);
601                SynthStyle oldStyle = style;
602
603                style = SynthLookAndFeel.updateStyle(context, this );
604                if (oldStyle != style) {
605                    String prefix = getPropertyPrefix();
606
607                    Object value = style.get(context, prefix + ".textIconGap");
608                    if (value != null) {
609                        LookAndFeel.installProperty(mi, "iconTextGap", value);
610                    }
611                    defaultTextIconGap = mi.getIconTextGap();
612
613                    if (menuItem.getMargin() == null
614                            || (menuItem.getMargin() instanceof  UIResource)) {
615                        Insets insets = (Insets) style.get(context, prefix
616                                + ".margin");
617
618                        if (insets == null) {
619                            // Some places assume margins are non-null.
620                            insets = SynthLookAndFeel.EMPTY_UIRESOURCE_INSETS;
621                        }
622                        menuItem.setMargin(insets);
623                    }
624                    acceleratorDelimiter = style.getString(context, prefix
625                            + ".acceleratorDelimiter", "+");
626
627                    arrowIcon = style.getIcon(context, prefix + ".arrowIcon");
628
629                    checkIcon = style.getIcon(context, prefix + ".checkIcon");
630                    if (oldStyle != null) {
631                        uninstallKeyboardActions();
632                        installKeyboardActions();
633                    }
634                }
635                context.dispose();
636
637                SynthContext accContext = getContext(mi,
638                        Region.MENU_ITEM_ACCELERATOR, ENABLED);
639
640                accStyle = SynthLookAndFeel.updateStyle(accContext, this );
641                accContext.dispose();
642            }
643
644            protected void uninstallDefaults() {
645                SynthContext context = getContext(menuItem, ENABLED);
646                style.uninstallDefaults(context);
647                context.dispose();
648                style = null;
649
650                SynthContext accContext = getContext(menuItem,
651                        Region.MENU_ITEM_ACCELERATOR, ENABLED);
652                accStyle.uninstallDefaults(accContext);
653                accContext.dispose();
654                accStyle = null;
655
656                super .uninstallDefaults();
657            }
658
659            protected void uninstallListeners() {
660                super .uninstallListeners();
661                menuItem.removePropertyChangeListener(this );
662            }
663
664            public SynthContext getContext(JComponent c) {
665                return getContext(c, getComponentState(c));
666            }
667
668            SynthContext getContext(JComponent c, int state) {
669                return SynthContext.getContext(SynthContext.class, c,
670                        SynthLookAndFeel.getRegion(c), style, state);
671            }
672
673            public SynthContext getContext(JComponent c, Region region) {
674                return getContext(c, region, getComponentState(c, region));
675            }
676
677            private SynthContext getContext(JComponent c, Region region,
678                    int state) {
679                return SynthContext.getContext(SynthContext.class, c, region,
680                        accStyle, state);
681            }
682
683            private Region getRegion(JComponent c) {
684                return SynthLookAndFeel.getRegion(c);
685            }
686
687            private int getComponentState(JComponent c) {
688                int state;
689
690                if (!c.isEnabled()) {
691                    state = DISABLED;
692                } else if (menuItem.isArmed()) {
693                    state = MOUSE_OVER;
694                } else {
695                    state = SynthLookAndFeel.getComponentState(c);
696                }
697                if (menuItem.isSelected()) {
698                    state |= SELECTED;
699                }
700                return state;
701            }
702
703            private int getComponentState(JComponent c, Region region) {
704                return getComponentState(c);
705            }
706
707            protected Dimension getPreferredMenuItemSize(JComponent c,
708                    Icon checkIcon, Icon arrowIcon, int defaultTextIconGap) {
709                SynthContext context = getContext(c);
710                SynthContext accContext = getContext(c,
711                        Region.MENU_ITEM_ACCELERATOR);
712                Dimension value = getPreferredMenuItemSize(context, accContext,
713                        c, checkIcon, arrowIcon, defaultTextIconGap,
714                        acceleratorDelimiter);
715                context.dispose();
716                accContext.dispose();
717                return value;
718            }
719
720            public void update(Graphics g, JComponent c) {
721                SynthContext context = getContext(c);
722
723                SynthLookAndFeel.update(context, g);
724                paintBackground(context, g, c);
725                paint(context, g);
726                context.dispose();
727            }
728
729            public void paint(Graphics g, JComponent c) {
730                SynthContext context = getContext(c);
731
732                paint(context, g);
733                context.dispose();
734            }
735
736            protected void paint(SynthContext context, Graphics g) {
737                SynthContext accContext = getContext(menuItem,
738                        Region.MENU_ITEM_ACCELERATOR);
739
740                // Refetch the appropriate check indicator for the current state
741                String prefix = getPropertyPrefix();
742                Icon checkIcon = style.getIcon(context, prefix + ".checkIcon");
743                Icon arrowIcon = style.getIcon(context, prefix + ".arrowIcon");
744                paint(context, accContext, g, checkIcon, arrowIcon,
745                        acceleratorDelimiter, defaultTextIconGap);
746                accContext.dispose();
747            }
748
749            void paintBackground(SynthContext context, Graphics g, JComponent c) {
750                context.getPainter().paintMenuItemBackground(context, g, 0, 0,
751                        c.getWidth(), c.getHeight());
752            }
753
754            public void paintBorder(SynthContext context, Graphics g, int x,
755                    int y, int w, int h) {
756                context.getPainter()
757                        .paintMenuItemBorder(context, g, x, y, w, h);
758            }
759
760            public void propertyChange(PropertyChangeEvent e) {
761                if (SynthLookAndFeel.shouldUpdateStyle(e)) {
762                    updateStyle((JMenuItem) e.getSource());
763                }
764            }
765        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.