Source Code Cross Referenced for MenuUtilities.java in  » Swing-Library » substance-look-feel » org » jvnet » substance » utils » menu » Java Source Code / Java DocumentationJava Source Code and Java Documentation

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 geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Swing Library » substance look feel » org.jvnet.substance.utils.menu 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright (c) 2005-2008 Substance Kirill Grouchnikov. All Rights Reserved.
0003:         *
0004:         * Redistribution and use in source and binary forms, with or without 
0005:         * modification, are permitted provided that the following conditions are met:
0006:         * 
0007:         *  o Redistributions of source code must retain the above copyright notice, 
0008:         *    this list of conditions and the following disclaimer. 
0009:         *     
0010:         *  o Redistributions in binary form must reproduce the above copyright notice, 
0011:         *    this list of conditions and the following disclaimer in the documentation 
0012:         *    and/or other materials provided with the distribution. 
0013:         *     
0014:         *  o Neither the name of Substance Kirill Grouchnikov nor the names of 
0015:         *    its contributors may be used to endorse or promote products derived 
0016:         *    from this software without specific prior written permission. 
0017:         *     
0018:         * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
0019:         * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
0020:         * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
0021:         * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
0022:         * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
0023:         * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
0024:         * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
0025:         * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
0026:         * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
0027:         * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
0028:         * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
0029:         */
0030:        package org.jvnet.substance.utils.menu;
0031:
0032:        import java.awt.*;
0033:        import java.awt.event.KeyEvent;
0034:        import java.awt.geom.Area;
0035:        import java.beans.PropertyChangeEvent;
0036:        import java.beans.PropertyChangeListener;
0037:
0038:        import javax.swing.*;
0039:        import javax.swing.plaf.ButtonUI;
0040:        import javax.swing.plaf.basic.BasicHTML;
0041:        import javax.swing.text.View;
0042:
0043:        import org.jvnet.lafwidget.layout.TransitionLayout;
0044:        import org.jvnet.substance.*;
0045:        import org.jvnet.substance.painter.text.SubstanceTextPainter;
0046:        import org.jvnet.substance.utils.SubstanceCoreUtilities;
0047:        import org.jvnet.substance.utils.SubstanceConstants.MenuGutterFillKind;
0048:
0049:        /**
0050:         * A collection of ugly finctions from
0051:         * {@link javax.swing.plaf.basic.BasicMenuItemUI} since they are private. This
0052:         * class is <b>for internal use only</b>.
0053:         * 
0054:         * @author Kirill Grouchnikov
0055:         */
0056:        public class MenuUtilities {
0057:            /**
0058:             * Delegate for painting the background.
0059:             */
0060:            private static SubstanceMenuBackgroundDelegate backgroundDelegate = new SubstanceMenuBackgroundDelegate(
0061:                    0.4f);
0062:
0063:            public static final String LAYOUT_METRICS = "substancelaf.internal.menus.layoutMetrics";
0064:
0065:            public static final String GUTTER_X = "substancelaf.internal.menus.gutterX";
0066:
0067:            public static class MenuPropertyListener implements 
0068:                    PropertyChangeListener {
0069:                protected JMenuItem menuItem;
0070:
0071:                public MenuPropertyListener(JMenuItem menuItem) {
0072:                    this .menuItem = menuItem;
0073:                }
0074:
0075:                public void install() {
0076:                    this .menuItem.addPropertyChangeListener(this );
0077:                }
0078:
0079:                public void uninstall() {
0080:                    this .menuItem.removePropertyChangeListener(this );
0081:                }
0082:
0083:                public void propertyChange(PropertyChangeEvent evt) {
0084:                    // if (!evt.getPropertyName().equals(
0085:                    // SubstanceMenu.SINGLE_MENU_TEXT_OFFSET))
0086:                    // SwingUtilities.invokeLater(new Runnable() {
0087:                    // public void run() {
0088:                    // menuItem.putClientProperty(
0089:                    // SubstanceMenu.SINGLE_MENU_TEXT_OFFSET, null);
0090:                    // if (menuItem.getParent() instanceof JPopupMenu) {
0091:                    // JPopupMenu parent = (JPopupMenu) menuItem
0092:                    // .getParent();
0093:                    // parent
0094:                    // .putClientProperty(
0095:                    // SubstanceMenu.SINGLE_MENU_TEXT_OFFSET,
0096:                    // null);
0097:                    // }
0098:                    // }
0099:                    // });
0100:                    if (!evt.getPropertyName().equals(
0101:                            MenuUtilities.LAYOUT_METRICS)) {
0102:                        SwingUtilities.invokeLater(new Runnable() {
0103:                            public void run() {
0104:                                MenuUtilities.cleanPopupLayoutMetrics(menuItem);
0105:                            }
0106:                        });
0107:                    }
0108:                }
0109:
0110:            }
0111:
0112:            public static class MenuLayoutInfo {
0113:                public Rectangle viewRect;
0114:                public Rectangle iconRect;
0115:                public Rectangle checkIconRect;
0116:                public Rectangle textRect;
0117:                public Rectangle acceleratorRect;
0118:                public Rectangle arrowIconRect;
0119:                public String text;
0120:            }
0121:
0122:            public static class MenuLayoutMetrics {
0123:                public int maxIconWidth;
0124:                public int maxCheckIconWidth;
0125:                public int maxTextWidth;
0126:                public int maxAcceleratorWidth;
0127:                public int maxArrowIconWidth;
0128:                public int maxGap;
0129:            }
0130:
0131:            /* Client Property keys for the icon and text maximal offsets */
0132:            // static final StringBuffer MAX_ICON_OFFSET = new StringBuffer(
0133:            // "maxIconOffset");
0134:            //
0135:            // static final StringBuffer MAX_TEXT_OFFSET = new StringBuffer(
0136:            // "maxTextOffset");
0137:            //
0138:            // public static int getTextOffset(Component menuItemParent) {
0139:            // if (!(menuItemParent instanceof JPopupMenu)) {
0140:            // return 0;
0141:            // }
0142:            //
0143:            // return getTextOffset(null, menuItemParent);
0144:            // }
0145:            // private static int getSingleItemTextOffset(JMenuItem menuItem) {
0146:            // // Check if we have this property on the menu item.
0147:            // Object prop = menuItem
0148:            // .getClientProperty(SubstanceMenu.SINGLE_MENU_TEXT_OFFSET);
0149:            // if (prop instanceof Integer) {
0150:            // // This property is reset on every property change
0151:            // // to the menu item. If the property exists, nothing
0152:            // // has changed since the last time it was computed.
0153:            // return (Integer) prop;
0154:            // }
0155:            //
0156:            // SubstanceMenu ui = (SubstanceMenu) menuItem.getUI();
0157:            // int result = MenuUtilities.getTextOffset(menuItem, ui
0158:            // .getAcceleratorFont(), ui.getCheckIcon(), ui.getArrowIcon(), ui
0159:            // .getDefaultTextIconGap());
0160:            // // Now that the offset has been computed, set it on the menu item.
0161:            // menuItem.putClientProperty(SubstanceMenu.SINGLE_MENU_TEXT_OFFSET,
0162:            // result);
0163:            // return result;
0164:            // }
0165:            // public static int getTextOffset(JMenuItem menuItem) {
0166:            // return getTextOffset(menuItem, menuItem.getParent());
0167:            // }
0168:            //
0169:            // public static int getTextOffset(JMenuItem menuItem, Component parent) {
0170:            // if (!(parent instanceof JPopupMenu)) {
0171:            // return getSingleItemTextOffset(menuItem);
0172:            // }
0173:            //
0174:            // // test if there's a computed property on the parent
0175:            // JPopupMenu popupMenu = (JPopupMenu) parent;
0176:            // Object prop = popupMenu
0177:            // .getClientProperty(SubstanceMenu.SINGLE_MENU_TEXT_OFFSET);
0178:            // if (prop instanceof Integer) {
0179:            // // This property is reset on every change to both the
0180:            // // popup (adding / removing child menu component) and
0181:            // // and each child component (on any property change).
0182:            // // So, if this property exists on the popup menu, nothing
0183:            // // has changed since the last time the offset was computed.
0184:            // return (Integer) prop;
0185:            // }
0186:            // int maxTextOffset = -1;
0187:            // int maxIconWidth = 0;
0188:            // int maxIconX = 0;
0189:            // int maxCheckIconX = 0;
0190:            // int maxCheckIconWidth = 0;
0191:            // // int maxViewRect = 0;
0192:            // for (int i = 0; i < popupMenu.getComponentCount(); i++) {
0193:            // Component comp = popupMenu.getComponent(i);
0194:            // if (comp instanceof JMenuItem) {
0195:            // JMenuItem childMenuItem = (JMenuItem) comp;
0196:            // ButtonUI bui = childMenuItem.getUI();
0197:            // if (!(bui instanceof SubstanceMenu))
0198:            // continue;
0199:            // SubstanceMenu ui = (SubstanceMenu) bui;
0200:            // MenuLayoutInfo mli = MenuUtilities.getMenuLayoutInfo(
0201:            // childMenuItem, ui.getAcceleratorFont(), ui
0202:            // .getCheckIcon(), ui.getArrowIcon(), ui
0203:            // .getDefaultTextIconGap());
0204:            //
0205:            // if (popupMenu.getComponentOrientation().isLeftToRight()) {
0206:            // if (mli.textRect != null) {
0207:            // maxTextOffset = Math.max(maxTextOffset, mli.textRect.x);
0208:            // }
0209:            // if (mli.iconRect != null) {
0210:            // maxIconWidth = Math
0211:            // .max(maxIconWidth, mli.iconRect.width
0212:            // + ui.getDefaultTextIconGap());
0213:            // maxIconX = Math.max(maxIconX, mli.iconRect.x);
0214:            // }
0215:            // if (mli.checkIconRect != null) {
0216:            // maxCheckIconWidth = Math.max(maxCheckIconWidth,
0217:            // mli.checkIconRect.width + 2
0218:            // * ui.getDefaultTextIconGap());
0219:            // maxCheckIconX = Math.max(maxCheckIconX,
0220:            // mli.checkIconRect.x);
0221:            // }
0222:            // } else {
0223:            // if (mli.textRect != null) {
0224:            // maxTextOffset = Math.max(maxTextOffset, mli.viewRect.x
0225:            // + mli.viewRect.width
0226:            // - (mli.textRect.x + mli.textRect.width));
0227:            // }
0228:            // if (mli.iconRect != null) {
0229:            // maxIconWidth = Math.max(maxIconWidth,
0230:            // mli.iconRect.width + 2
0231:            // * ui.getDefaultTextIconGap());
0232:            // maxIconX = Math.max(maxIconX, mli.iconRect.x
0233:            // + mli.iconRect.width);
0234:            // }
0235:            // if (mli.checkIconRect != null) {
0236:            // maxCheckIconWidth = Math.max(maxCheckIconWidth,
0237:            // mli.checkIconRect.width
0238:            // + ui.getDefaultTextIconGap());
0239:            // maxCheckIconX = Math.max(maxCheckIconX,
0240:            // mli.checkIconRect.x + mli.checkIconRect.width);
0241:            // }
0242:            // // maxViewRect = Math.max(maxViewRect, mli.viewRect.x
0243:            // // + mli.viewRect.width);
0244:            // }
0245:            //
0246:            // //
0247:            // // int childResult = MenuUtilities.getTextOffset(g,
0248:            // // childMenuItem,
0249:            // // ui.getAcceleratorFont(), ui.getCheckIcon(), ui
0250:            // // .getArrowIcon(), ui.getDefaultTextIconGap());
0251:            // // if (maxOffset < childResult)
0252:            // // maxOffset = childResult;
0253:            // }
0254:            // }
0255:            // // Now that the offset is computed, store it on the
0256:            // // popup menu.
0257:            // int maxOffset = Math.max(maxTextOffset, maxIconWidth
0258:            // + maxCheckIconWidth);
0259:            // if (popupMenu.getComponentOrientation().isLeftToRight()) {
0260:            // maxOffset = Math.max(maxOffset, maxIconX + maxIconWidth);
0261:            // maxOffset = Math.max(maxOffset, maxCheckIconX + maxCheckIconWidth);
0262:            // } else {
0263:            // // maxOffset = Math.max(maxOffset, maxViewRect
0264:            // // - (maxIconX - maxIconWidth));
0265:            // }
0266:            // popupMenu.putClientProperty(SubstanceMenu.SINGLE_MENU_TEXT_OFFSET,
0267:            // maxOffset);
0268:            // return maxOffset;
0269:            // }
0270:            //
0271:            // public static int getTextOffset(JMenuItem menuItem, Font acceleratorFont,
0272:            // Icon checkIcon, Icon arrowIcon, int defaultTextIconGap) {
0273:            //
0274:            // // Dimension size = b.getSize();
0275:            // // int menuWidth = menuItem.getWidth();
0276:            // // int menuHeight = menuItem.getHeight();
0277:            // Insets i = menuItem.getInsets();
0278:            //
0279:            // Rectangle iconRect = new Rectangle();
0280:            // Rectangle textRect = new Rectangle();
0281:            // Rectangle acceleratorRect = new Rectangle();
0282:            // Rectangle checkIconRect = new Rectangle();
0283:            // Rectangle arrowIconRect = new Rectangle();
0284:            // Rectangle viewRect = new Rectangle(Short.MAX_VALUE, Short.MAX_VALUE);
0285:            //
0286:            // int menuWidth = menuItem.getWidth();
0287:            // int menuHeight = menuItem.getHeight();
0288:            // if ((menuWidth > 0) && (menuHeight > 0))
0289:            // viewRect.setBounds(0, 0, menuWidth, menuHeight);
0290:            //
0291:            // // fix for defect 108 - failed on b62 of Mustang and later on Hebrew
0292:            // // localized menu strings.
0293:            // // viewRect.setBounds(0, 0, menuWidth, menuHeight);
0294:            //
0295:            // viewRect.x += i.left;
0296:            // viewRect.y += i.top;
0297:            // viewRect.width -= (i.right + viewRect.x);
0298:            // viewRect.height -= (i.bottom + viewRect.y);
0299:            //
0300:            // FontMetrics fm = menuItem.getFontMetrics(menuItem.getFont());
0301:            // FontMetrics fmAccel = menuItem.getFontMetrics(acceleratorFont);
0302:            //
0303:            // // get Accelerator text
0304:            // KeyStroke accelerator = menuItem.getAccelerator();
0305:            // String acceleratorText = "";
0306:            // if (accelerator != null) {
0307:            // int modifiers = accelerator.getModifiers();
0308:            // if (modifiers > 0) {
0309:            // acceleratorText = KeyEvent.getKeyModifiersText(modifiers);
0310:            // // acceleratorText += "-";
0311:            // acceleratorText += UIManager
0312:            // .getString("MenuItem.acceleratorDelimiter");
0313:            // }
0314:            //
0315:            // int keyCode = accelerator.getKeyCode();
0316:            // if (keyCode != 0) {
0317:            // acceleratorText += KeyEvent.getKeyText(keyCode);
0318:            // } else {
0319:            // acceleratorText += accelerator.getKeyChar();
0320:            // }
0321:            // }
0322:            //
0323:            // // layout the text and icon
0324:            // layoutMenuItem(menuItem, fm, menuItem.getText(), fmAccel,
0325:            // acceleratorText, menuItem.getIcon(), checkIcon, arrowIcon,
0326:            // menuItem.getVerticalAlignment(), menuItem
0327:            // .getHorizontalAlignment(), menuItem
0328:            // .getVerticalTextPosition(), menuItem
0329:            // .getHorizontalTextPosition(), viewRect, iconRect,
0330:            // textRect, acceleratorRect, checkIconRect, arrowIconRect,
0331:            // menuItem.getText() == null ? 0 : defaultTextIconGap,
0332:            // defaultTextIconGap);
0333:            //
0334:            // if (menuItem.getComponentOrientation().isLeftToRight()) {
0335:            // return textRect.x;
0336:            // } else {
0337:            // // int result = viewRect.x + viewRect.width;
0338:            // // if (iconRect.width != 0) {
0339:            // // result -= (iconRect.x + defaultTextIconGap);
0340:            // // }
0341:            // // else {
0342:            // // if (checkIconRect.width != 0) {
0343:            // // result -= (checkIconRect.x + defaultTextIconGap);
0344:            // // }
0345:            // // }
0346:            // return viewRect.x + viewRect.width - iconRect.x
0347:            // - ((iconRect.width != 0) ? 0 : defaultTextIconGap);
0348:            // }
0349:            // }
0350:            public static MenuLayoutInfo getMenuLayoutInfo(
0351:                    // Graphics g,
0352:                    JMenuItem menuItem, Font acceleratorFont, Icon checkIcon,
0353:                    Icon arrowIcon, int defaultTextIconGap) {
0354:
0355:                // Dimension size = b.getSize();
0356:                // int menuWidth = menuItem.getWidth();
0357:                // int menuHeight = menuItem.getHeight();
0358:                Insets i = menuItem.getInsets();
0359:
0360:                Rectangle iconRect = new Rectangle(0, 0, 0, 0);
0361:                Rectangle textRect = new Rectangle(0, 0, 0, 0);
0362:                Rectangle acceleratorRect = new Rectangle(0, 0, 0, 0);
0363:                Rectangle checkIconRect = new Rectangle(0, 0, 0, 0);
0364:                Rectangle arrowIconRect = new Rectangle(0, 0, 0, 0);
0365:                Rectangle viewRect = new Rectangle(Short.MAX_VALUE,
0366:                        Short.MAX_VALUE);
0367:
0368:                int menuWidth = menuItem.getWidth();
0369:                int menuHeight = menuItem.getHeight();
0370:                if ((menuWidth > 0) && (menuHeight > 0))
0371:                    viewRect.setBounds(0, 0, menuWidth, menuHeight);
0372:
0373:                // fix for defect 108 - failed on b62 of Mustang and later on Hebrew
0374:                // localized menu strings.
0375:                // viewRect.setBounds(0, 0, menuWidth, menuHeight);
0376:
0377:                viewRect.x += i.left;
0378:                viewRect.y += i.top;
0379:                viewRect.width -= (i.right + viewRect.x);
0380:                viewRect.height -= (i.bottom + viewRect.y);
0381:
0382:                // Font f = menuItem.getFont();
0383:                // g.setFont(f);
0384:                FontMetrics fm = menuItem.getFontMetrics(menuItem.getFont());
0385:                FontMetrics fmAccel = menuItem.getFontMetrics(acceleratorFont);
0386:
0387:                // get Accelerator text
0388:                KeyStroke accelerator = menuItem.getAccelerator();
0389:                String acceleratorText = "";
0390:                if (accelerator != null) {
0391:                    int modifiers = accelerator.getModifiers();
0392:                    if (modifiers > 0) {
0393:                        acceleratorText = KeyEvent
0394:                                .getKeyModifiersText(modifiers);
0395:                        // acceleratorText += "-";
0396:                        acceleratorText += UIManager
0397:                                .getString("MenuItem.acceleratorDelimiter");
0398:                    }
0399:
0400:                    int keyCode = accelerator.getKeyCode();
0401:                    if (keyCode != 0) {
0402:                        acceleratorText += KeyEvent.getKeyText(keyCode);
0403:                    } else {
0404:                        acceleratorText += accelerator.getKeyChar();
0405:                    }
0406:                }
0407:
0408:                // layout the text and icon
0409:                String text = layoutMenuItem(menuItem, fm, menuItem.getText(),
0410:                        fmAccel, acceleratorText, menuItem.getIcon(),
0411:                        checkIcon, arrowIcon, menuItem.getVerticalAlignment(),
0412:                        menuItem.getHorizontalAlignment(), menuItem
0413:                                .getVerticalTextPosition(), menuItem
0414:                                .getHorizontalTextPosition(), viewRect,
0415:                        iconRect, textRect, acceleratorRect, checkIconRect,
0416:                        arrowIconRect, menuItem.getText() == null ? 0
0417:                                : defaultTextIconGap, defaultTextIconGap);
0418:
0419:                MenuLayoutInfo mlInfo = new MenuLayoutInfo();
0420:                // mlInfo.checkIconRect = (checkIconRect.width > 0) ? checkIconRect :
0421:                // null;
0422:                // mlInfo.iconRect = (iconRect.width > 0) ? iconRect : null;
0423:                // mlInfo.textRect = (textRect.width > 0) ? textRect : null;
0424:                // mlInfo.viewRect = (viewRect.width > 0) ? viewRect : null;
0425:                mlInfo.checkIconRect = checkIconRect;
0426:                mlInfo.iconRect = iconRect;
0427:                mlInfo.textRect = textRect;
0428:                mlInfo.viewRect = viewRect;
0429:                mlInfo.acceleratorRect = acceleratorRect;
0430:                mlInfo.arrowIconRect = arrowIconRect;
0431:                mlInfo.text = text;
0432:
0433:                return mlInfo;
0434:                //		
0435:                // if (menuItem.getComponentOrientation().isLeftToRight()) {
0436:                // return textRect.x;
0437:                // } else {
0438:                // // int result = viewRect.x + viewRect.width;
0439:                // // if (iconRect.width != 0) {
0440:                // // result -= (iconRect.x + defaultTextIconGap);
0441:                // // }
0442:                // // else {
0443:                // // if (checkIconRect.width != 0) {
0444:                // // result -= (checkIconRect.x + defaultTextIconGap);
0445:                // // }
0446:                // // }
0447:                // return viewRect.x + viewRect.width - iconRect.x
0448:                // - ((iconRect.width != 0) ? 0 : defaultTextIconGap);
0449:                // }
0450:            }
0451:
0452:            /**
0453:             * Compute and return the location of the icons origin, the location of
0454:             * origin of the text baseline, and a possibly clipped version of the
0455:             * compound labels string. Locations are computed relative to the viewRect
0456:             * rectangle.
0457:             */
0458:            private static String layoutMenuItem(JMenuItem menuItem,
0459:                    FontMetrics fm, String text, FontMetrics fmAccel,
0460:                    String acceleratorText, Icon icon, Icon checkIcon,
0461:                    Icon arrowIcon, int verticalAlignment,
0462:                    int horizontalAlignment, int verticalTextPosition,
0463:                    int horizontalTextPosition, Rectangle viewRect,
0464:                    Rectangle iconRect, Rectangle textRect,
0465:                    Rectangle acceleratorRect, Rectangle checkIconRect,
0466:                    Rectangle arrowIconRect, int textIconGap, int menuItemGap) {
0467:
0468:                SwingUtilities.layoutCompoundLabel(menuItem, fm, text, icon,
0469:                        verticalAlignment, horizontalAlignment,
0470:                        verticalTextPosition, horizontalTextPosition, viewRect,
0471:                        iconRect, textRect, textIconGap);
0472:
0473:                /*
0474:                 * Initialize the acceelratorText bounds rectangle textRect. If a null
0475:                 * or and empty String was specified we substitute "" here and use
0476:                 * 0,0,0,0 for acceleratorTextRect.
0477:                 */
0478:                if ((acceleratorText == null) || acceleratorText.equals("")) {
0479:                    acceleratorRect.width = acceleratorRect.height = 0;
0480:                    acceleratorText = "";
0481:                } else {
0482:                    acceleratorRect.width = fmAccel
0483:                            .stringWidth(acceleratorText);
0484:                    acceleratorRect.height = fmAccel.getHeight();
0485:                }
0486:
0487:                /*
0488:                 * Initialize the checkIcon bounds rectangle's width & height.
0489:                 */
0490:
0491:                if (useCheckAndArrow(menuItem)) {
0492:                    if (checkIcon != null) {
0493:                        checkIconRect.width = checkIcon.getIconWidth();
0494:                        checkIconRect.height = checkIcon.getIconHeight();
0495:                    } else {
0496:                        checkIconRect.width = checkIconRect.height = 0;
0497:                    }
0498:
0499:                    /*
0500:                     * Initialize the arrowIcon bounds rectangle width & height.
0501:                     */
0502:
0503:                    if (arrowIcon != null) {
0504:                        arrowIconRect.width = arrowIcon.getIconWidth();
0505:                        arrowIconRect.height = arrowIcon.getIconHeight();
0506:                    } else {
0507:                        arrowIconRect.width = arrowIconRect.height = 0;
0508:                    }
0509:                }
0510:
0511:                Rectangle labelRect = iconRect.union(textRect);
0512:                if (menuItem.getComponentOrientation().isLeftToRight()) {
0513:                    textRect.x += menuItemGap;
0514:                    iconRect.x += menuItemGap;
0515:
0516:                    // Position the Accelerator text rect
0517:                    acceleratorRect.x = viewRect.x + viewRect.width
0518:                            - arrowIconRect.width - menuItemGap
0519:                            - acceleratorRect.width;
0520:
0521:                    // Position the Check and Arrow Icons
0522:                    if (useCheckAndArrow(menuItem)) {
0523:                        checkIconRect.x = viewRect.x + menuItemGap;
0524:                        textRect.x += menuItemGap + checkIconRect.width;
0525:                        iconRect.x += menuItemGap + checkIconRect.width;
0526:                        arrowIconRect.x = viewRect.x + viewRect.width
0527:                                - menuItemGap - arrowIconRect.width;
0528:                    }
0529:                } else {
0530:                    textRect.x -= menuItemGap;
0531:                    iconRect.x -= menuItemGap;
0532:
0533:                    // Position the Accelerator text rect
0534:                    acceleratorRect.x = viewRect.x + arrowIconRect.width
0535:                            + menuItemGap;
0536:
0537:                    // Position the Check and Arrow Icons
0538:                    if (useCheckAndArrow(menuItem)) {
0539:                        checkIconRect.x = viewRect.x + viewRect.width
0540:                                - menuItemGap - checkIconRect.width;
0541:                        textRect.x -= menuItemGap + checkIconRect.width;
0542:                        iconRect.x -= menuItemGap + checkIconRect.width;
0543:                        arrowIconRect.x = viewRect.x + menuItemGap;
0544:                    }
0545:                }
0546:
0547:                // Align the accelertor text and the check and arrow icons vertically
0548:                // with the center of the label rect.
0549:                acceleratorRect.y = labelRect.y + (labelRect.height / 2)
0550:                        - (acceleratorRect.height / 2);
0551:                if (useCheckAndArrow(menuItem)) {
0552:                    arrowIconRect.y = labelRect.y + (labelRect.height / 2)
0553:                            - (arrowIconRect.height / 2);
0554:                    checkIconRect.y = labelRect.y + (labelRect.height / 2)
0555:                            - (checkIconRect.height / 2);
0556:                }
0557:
0558:                /*
0559:                 * System.out.println("Layout: text="+menuItem.getText()+"\n\tv="
0560:                 * +viewRect+"\n\tc="+checkIconRect+"\n\ti="
0561:                 * +iconRect+"\n\tt="+textRect+"\n\tacc="
0562:                 * +acceleratorRect+"\n\ta="+arrowIconRect+"\n");
0563:                 */
0564:
0565:                return text;
0566:            }
0567:
0568:            /*
0569:             * Returns false if the component is a JMenu and it is a top level menu (on
0570:             * the menubar).
0571:             */
0572:            private static boolean useCheckAndArrow(JMenuItem menuItem) {
0573:                boolean b = true;
0574:                if ((menuItem instanceof  JMenu)
0575:                        && (((JMenu) menuItem).isTopLevelMenu())) {
0576:                    b = false;
0577:                }
0578:                return b;
0579:            }
0580:
0581:            private static JComponent getMenuItemParent(JMenuItem mi) {
0582:                Container parent = mi.getParent();
0583:                if ((parent instanceof  JComponent)
0584:                        && (!(mi instanceof  JMenu) || !((JMenu) mi)
0585:                                .isTopLevelMenu())) {
0586:                    return (JComponent) parent;
0587:                } else {
0588:                    return null;
0589:                }
0590:            }
0591:
0592:            // public static void lineupTextRectangle(JMenuItem menuItem,
0593:            // Rectangle textRect, Font acceleratorFont, Icon checkIcon,
0594:            // Icon arrowIcon, int defaultTextIconGap) {
0595:            // if (textRect == null)
0596:            // return;
0597:            // int textOffset = MenuUtilities.getTextOffset(menuItem);
0598:            // // System.out.println()
0599:            // if (menuItem.getComponentOrientation().isLeftToRight()) {
0600:            // textRect.setLocation(textOffset, textRect.y);
0601:            // } else {
0602:            // int loc = menuItem.getWidth() - textOffset - textRect.width
0603:            // - defaultTextIconGap;
0604:            // textRect.setLocation(loc, textRect.y);
0605:            // }
0606:            //
0607:            // }
0608:
0609:            public static void paintMenuItem(Graphics g, JMenuItem menuItem,
0610:                    Icon checkIcon, Icon arrowIcon, int defaultTextIconGap) {
0611:                Graphics2D g2d = (Graphics2D) g.create();
0612:
0613:                // special handling of menu items covered by lightweight popups
0614:                // for the defect 297
0615:                if (Boolean.TRUE
0616:                        .equals(menuItem
0617:                                .getClientProperty(SubstanceCoreUtilities.IS_COVERED_BY_LIGHTWEIGHT_POPUPS))) {
0618:                    JRootPane rootPane = SwingUtilities.getRootPane(menuItem);
0619:                    if (rootPane != null) {
0620:                        Component[] popups = rootPane.getLayeredPane()
0621:                                .getComponentsInLayer(JLayeredPane.POPUP_LAYER);
0622:                        if (popups != null) {
0623:                            int popupIndexToStartWith = SubstanceCoreUtilities
0624:                                    .getPopupParentIndexOf(menuItem, popups) - 1;
0625:                            Area clip = new Area(g2d.getClip());
0626:                            for (int i = popupIndexToStartWith; i >= 0; i--) {
0627:                                Component popup = popups[i];
0628:                                // convert the popup bounds to the menu item coordinate
0629:                                // system
0630:                                Rectangle popupArea = SwingUtilities
0631:                                        .convertRectangle(rootPane
0632:                                                .getLayeredPane(), popup
0633:                                                .getBounds(), menuItem);
0634:                                // and subtract this area from the clip
0635:                                clip.subtract(new Area(popupArea));
0636:                            }
0637:                            // at this point we have the original clip minus
0638:                            // all the overlapping lightweight popups that are painted
0639:                            // after this menu item
0640:                            g2d.setClip(clip);
0641:                        }
0642:                    }
0643:                }
0644:
0645:                ButtonModel model = menuItem.getModel();
0646:                SubstanceMenu menuUi = (SubstanceMenu) menuItem.getUI();
0647:
0648:                Font f = menuItem.getFont();
0649:                g2d.setFont(f);
0650:
0651:                // get Accelerator text
0652:                KeyStroke accelerator = menuItem.getAccelerator();
0653:                String acceleratorText = "";
0654:                if (accelerator != null) {
0655:                    int modifiers = accelerator.getModifiers();
0656:                    if (modifiers > 0) {
0657:                        acceleratorText = KeyEvent
0658:                                .getKeyModifiersText(modifiers);
0659:                        acceleratorText += UIManager
0660:                                .getString("MenuItem.acceleratorDelimiter");
0661:                    }
0662:
0663:                    int keyCode = accelerator.getKeyCode();
0664:                    if (keyCode != 0) {
0665:                        acceleratorText += KeyEvent.getKeyText(keyCode);
0666:                    } else {
0667:                        acceleratorText += accelerator.getKeyChar();
0668:                    }
0669:                }
0670:                Icon icon = menuItem.getIcon();
0671:                // MenuLayoutInfo mli = MenuUtilities.getMenuLayoutInfo(menuItem, menuUi
0672:                // .getAcceleratorFont(), menuUi.getCheckIcon(), menuUi
0673:                // .getArrowIcon(), menuUi.getDefaultTextIconGap());
0674:
0675:                MenuLayoutInfo mli = MenuUtilities.getMenuLayoutInfo(menuItem,
0676:                        menuUi.getAcceleratorFont(), menuUi.getCheckIcon(),
0677:                        menuUi.getArrowIcon(), menuUi.getDefaultTextIconGap());
0678:                MenuLayoutMetrics popupMetrics = MenuUtilities
0679:                        .getPopupLayoutMetrics(menuItem);
0680:                Insets i = menuItem.getInsets();
0681:                // FontMetrics fm = menuItem.getFontMetrics(menuItem.getFont());
0682:                // int fontHeight = fm.getHeight();
0683:                if (popupMetrics != null) {
0684:                    MenuGutterFillKind gutterFillKind = SubstanceCoreUtilities
0685:                            .getMenuGutterFillKind();
0686:                    boolean needExtraIconTextGap = (gutterFillKind != null)
0687:                            && (gutterFillKind != MenuGutterFillKind.NONE);
0688:                    int gap = popupMetrics.maxGap;
0689:                    if (menuItem.getComponentOrientation().isLeftToRight()) {
0690:                        int currX = i.left + gap / 2;
0691:                        if (checkIcon != null) {
0692:                            mli.checkIconRect = new Rectangle(currX, i.top,
0693:                                    checkIcon.getIconWidth(), checkIcon
0694:                                            .getIconHeight());
0695:                            int bump = (popupMetrics.maxCheckIconWidth - checkIcon
0696:                                    .getIconWidth()) / 2;
0697:                            mli.checkIconRect.x += bump;
0698:                        }
0699:                        if (popupMetrics.maxCheckIconWidth > 0) {
0700:                            currX += (popupMetrics.maxCheckIconWidth + gap);
0701:                        }
0702:                        if (icon != null) {
0703:                            mli.iconRect = new Rectangle(currX, i.top, icon
0704:                                    .getIconWidth(), icon.getIconHeight());
0705:                            int bump = (popupMetrics.maxIconWidth - icon
0706:                                    .getIconWidth()) / 2;
0707:                            mli.iconRect.x += bump;
0708:                        }
0709:                        if (popupMetrics.maxIconWidth > 0) {
0710:                            currX += (popupMetrics.maxIconWidth + gap);
0711:                        }
0712:                        menuItem.putClientProperty(GUTTER_X, currX + gap / 2);
0713:                        if (needExtraIconTextGap)
0714:                            currX += gap;
0715:                        if (menuItem.getText() != null) {
0716:                            mli.textRect = new Rectangle(currX, mli.textRect.y,
0717:                                    popupMetrics.maxTextWidth,
0718:                                    mli.textRect.height);
0719:                            mli.text = menuItem.getText();
0720:                        }
0721:                        currX += (popupMetrics.maxTextWidth + gap);
0722:                        if (popupMetrics.maxAcceleratorWidth > 0) {
0723:                            currX += 5 * gap;
0724:                            // accelerator text is right-aligned
0725:                            mli.acceleratorRect = new Rectangle(currX
0726:                                    + popupMetrics.maxAcceleratorWidth
0727:                                    - mli.acceleratorRect.width,
0728:                                    mli.textRect.y, mli.acceleratorRect.width,
0729:                                    mli.textRect.height);
0730:                        }
0731:                        if (popupMetrics.maxAcceleratorWidth > 0) {
0732:                            currX += (popupMetrics.maxAcceleratorWidth + gap);
0733:                        }
0734:
0735:                        if (arrowIcon != null) {
0736:                            mli.arrowIconRect = new Rectangle(currX, i.top,
0737:                                    popupMetrics.maxArrowIconWidth, arrowIcon
0738:                                            .getIconHeight());
0739:                        }
0740:
0741:                        Rectangle labelRect = new Rectangle(0, 0, menuItem
0742:                                .getWidth(), menuItem.getHeight());
0743:                        // if (mli.iconRect != null)
0744:                        // labelRect = labelRect.union(mli.iconRect);
0745:                        if (mli.textRect != null)
0746:                            labelRect = mli.textRect;
0747:                        // // Align the accelerator text and the check and arrow icons
0748:                        // // vertically with the center of the label rect.
0749:                        // if (mli.acceleratorRect != null) {
0750:                        // mli.acceleratorRect.y = labelRect.y;
0751:                        // //+ (labelRect.height / 2)
0752:                        // //- (mli.acceleratorRect.height / 2);
0753:                        // }
0754:                        if (mli.iconRect != null) {
0755:                            mli.iconRect.y = labelRect.y
0756:                                    + (labelRect.height / 2)
0757:                                    - (mli.iconRect.height / 2);
0758:                        }
0759:                        if (mli.arrowIconRect != null) {
0760:                            mli.arrowIconRect.y = labelRect.y
0761:                                    + (labelRect.height / 2)
0762:                                    - (mli.arrowIconRect.height / 2);
0763:                        }
0764:                        if (mli.checkIconRect != null) {
0765:                            mli.checkIconRect.y = labelRect.y
0766:                                    + (labelRect.height / 2)
0767:                                    - (mli.checkIconRect.height / 2);
0768:                        }
0769:                    } else {
0770:                        int currX = menuItem.getWidth() - i.right - gap / 2;
0771:                        if (checkIcon != null) {
0772:                            mli.checkIconRect = new Rectangle(currX
0773:                                    - popupMetrics.maxCheckIconWidth, i.top,
0774:                                    checkIcon.getIconWidth(), checkIcon
0775:                                            .getIconHeight());
0776:                            int bump = (popupMetrics.maxCheckIconWidth - checkIcon
0777:                                    .getIconWidth()) / 2;
0778:                            mli.checkIconRect.x += bump;
0779:                        }
0780:                        if (popupMetrics.maxCheckIconWidth > 0) {
0781:                            currX -= (popupMetrics.maxCheckIconWidth + gap);
0782:                        }
0783:                        if (icon != null) {
0784:                            // icons are center-aligned
0785:                            mli.iconRect = new Rectangle(currX
0786:                                    - popupMetrics.maxIconWidth, i.top, icon
0787:                                    .getIconWidth(), icon.getIconHeight());
0788:                            int bump = (popupMetrics.maxIconWidth - icon
0789:                                    .getIconWidth()) / 2;
0790:                            mli.iconRect.x += bump;
0791:                        }
0792:                        if (popupMetrics.maxIconWidth > 0) {
0793:                            currX -= (popupMetrics.maxIconWidth + gap);
0794:                        }
0795:                        menuItem.putClientProperty(GUTTER_X, currX + gap / 2);
0796:                        if (needExtraIconTextGap)
0797:                            currX -= gap;
0798:                        if (menuItem.getText() != null) {
0799:                            // text is right-aligned
0800:                            mli.textRect = new Rectangle(currX
0801:                                    - mli.textRect.width, mli.textRect.y,
0802:                                    popupMetrics.maxTextWidth,
0803:                                    mli.textRect.height);
0804:                            mli.text = menuItem.getText();
0805:                        }
0806:                        currX -= (popupMetrics.maxTextWidth + gap);
0807:                        if (popupMetrics.maxAcceleratorWidth > 0) {
0808:                            currX -= 5 * gap;
0809:                            // accelerator text is left-aligned
0810:                            mli.acceleratorRect = new Rectangle(currX
0811:                                    - popupMetrics.maxAcceleratorWidth,
0812:                                    mli.textRect.y, mli.acceleratorRect.width,
0813:                                    mli.textRect.height);
0814:                        }
0815:                        if (popupMetrics.maxAcceleratorWidth > 0) {
0816:                            currX -= (popupMetrics.maxAcceleratorWidth + gap);
0817:                        }
0818:
0819:                        if (arrowIcon != null) {
0820:                            mli.arrowIconRect = new Rectangle(currX
0821:                                    - popupMetrics.maxArrowIconWidth, i.top,
0822:                                    popupMetrics.maxArrowIconWidth, arrowIcon
0823:                                            .getIconHeight());
0824:                        }
0825:
0826:                        Rectangle labelRect = new Rectangle(0, 0, menuItem
0827:                                .getWidth(), menuItem.getHeight());
0828:                        // if (mli.iconRect != null)
0829:                        // labelRect = labelRect.union(mli.iconRect);
0830:                        if (mli.textRect != null)
0831:                            labelRect = mli.textRect;
0832:                        // // Align the accelerator text and the check and arrow icons
0833:                        // // vertically with the center of the label rect.
0834:                        // if (mli.acceleratorRect != null) {
0835:                        // mli.acceleratorRect.y = labelRect.y;
0836:                        // //+ (labelRect.height / 2)
0837:                        // //- (mli.acceleratorRect.height / 2);
0838:                        // }
0839:                        if (mli.iconRect != null) {
0840:                            mli.iconRect.y = labelRect.y
0841:                                    + (labelRect.height / 2)
0842:                                    - (mli.iconRect.height / 2);
0843:                        }
0844:                        if (mli.arrowIconRect != null) {
0845:                            mli.arrowIconRect.y = labelRect.y
0846:                                    + (labelRect.height / 2)
0847:                                    - (mli.arrowIconRect.height / 2);
0848:                        }
0849:                        if (mli.checkIconRect != null) {
0850:                            mli.checkIconRect.y = labelRect.y
0851:                                    + (labelRect.height / 2)
0852:                                    - (mli.checkIconRect.height / 2);
0853:                        }
0854:                    }
0855:                }
0856:                Component parent = menuItem.getParent();
0857:                if (parent instanceof  JPopupMenu) {
0858:                    ((JPopupMenu) parent).putClientProperty(GUTTER_X, menuItem
0859:                            .getClientProperty(GUTTER_X));
0860:                }
0861:
0862:                // MenuUtilities.lineupTextRectangle(menuItem, mli.textRect, menuUi
0863:                // .getAcceleratorFont(), menuUi.getCheckIcon(), menuUi
0864:                // .getArrowIcon(), menuUi.getDefaultTextIconGap());
0865:
0866:                SubstanceTextPainter textPainter = SubstanceLookAndFeel
0867:                        .getCurrentTextPainter();
0868:                textPainter.init(menuItem, null, true);
0869:                if (textPainter.needsBackgroundImage()) {
0870:                    // This is a workaround for disabled menu items. Since
0871:                    // SWT (native) pipeline doesn't support painting translucent
0872:                    // texts, we need a way to have the background painted in
0873:                    // full opacity, but the texts (and highlights) painted with
0874:                    // custom translucency. Here, we cheat and first paint the
0875:                    // background fill (with watermark) with full opacity. Since
0876:                    // there can be no highlights on disabled menu items, we don't
0877:                    // need to worry about hightlights. Then, the painting will be done
0878:                    // once again, overlaying the background, highlights and
0879:                    // text with custom alpha factor.
0880:                    paintBackground(g2d, menuItem);
0881:                }
0882:                textPainter.renderSurface(g2d);
0883:
0884:                // Paint background
0885:                textPainter.init(menuItem, null, true);
0886:                paintBackground(g2d, menuItem);
0887:                paintHighlights(g2d, menuItem);
0888:
0889:                float textAlpha = 1.0f;
0890:                if (mli.text != null) {
0891:                    View v = (View) menuItem
0892:                            .getClientProperty(BasicHTML.propertyKey);
0893:                    if (v != null) {
0894:                        v.paint(g2d, mli.textRect);
0895:                    } else {
0896:                        textAlpha = SubstanceCoreUtilities.paintText(menuItem,
0897:                                mli.textRect, mli.text, menuItem
0898:                                        .getDisplayedMnemonicIndex());
0899:                    }
0900:                }
0901:
0902:                // Draw the Accelerator Text
0903:                if (acceleratorText != null && !acceleratorText.equals("")) {
0904:                    SubstanceCoreUtilities.paintText(menuItem,
0905:                            mli.acceleratorRect, acceleratorText, -1);
0906:                }
0907:
0908:                Graphics2D graphics = (Graphics2D) g2d.create();
0909:                graphics.setComposite(TransitionLayout.getAlphaComposite(
0910:                        menuItem, textAlpha, g2d));
0911:
0912:                textPainter.renderSurface(graphics);
0913:                graphics.dispose();
0914:
0915:                // Paint the Check
0916:                if (checkIcon != null) {
0917:                    if (useCheckAndArrow(menuItem))
0918:                        checkIcon.paintIcon(menuItem, g2d, mli.checkIconRect.x,
0919:                                mli.checkIconRect.y);
0920:                }
0921:
0922:                // Paint the Icon
0923:                if (icon != null) {
0924:                    if (!model.isEnabled()) {
0925:                        icon = menuItem.getDisabledIcon();
0926:                    } else if (model.isPressed() && model.isArmed()) {
0927:                        icon = menuItem.getPressedIcon();
0928:                        if (icon == null) {
0929:                            // Use default icon
0930:                            icon = menuItem.getIcon();
0931:                        }
0932:                    } else {
0933:                        icon = menuItem.getIcon();
0934:                    }
0935:
0936:                    if (icon != null) {
0937:                        icon.paintIcon(menuItem, g2d, mli.iconRect.x,
0938:                                mli.iconRect.y);
0939:                    }
0940:                }
0941:
0942:                // Paint the Arrow
0943:                if (arrowIcon != null) {
0944:                    if (useCheckAndArrow(menuItem))
0945:                        arrowIcon.paintIcon(menuItem, g2d, mli.arrowIconRect.x,
0946:                                mli.arrowIconRect.y);
0947:                }
0948:
0949:                // g2d.setColor(Color.red);
0950:                // if (mli.iconRect != null)
0951:                // g2d.draw(mli.iconRect);
0952:                // if (mli.checkIconRect != null)
0953:                // g2d.draw(mli.checkIconRect);
0954:                // if (mli.textRect != null)
0955:                // g2d.draw(mli.textRect);
0956:
0957:                // g2d.setColor(Color.red);
0958:                // g2d.drawRect(mli.checkIconRect.x, mli.checkIconRect.y,
0959:                // mli.checkIconRect.width, mli.checkIconRect.height);
0960:                // g2d.drawRect(mli.iconRect.x, mli.iconRect.y, mli.iconRect.width,
0961:                // mli.iconRect.height);
0962:                // g2d.drawRect(mli.textRect.x, mli.textRect.y, mli.textRect.width,
0963:                // mli.textRect.height);
0964:                // g2d.drawRect(mli.arrowIconRect.x, mli.arrowIconRect.y,
0965:                // mli.arrowIconRect.width, mli.arrowIconRect.height);
0966:                // g2d.drawRect(mli.acceleratorRect.x, mli.acceleratorRect.y,
0967:                // mli.acceleratorRect.width, mli.acceleratorRect.height);
0968:
0969:                g2d.dispose();
0970:            }
0971:
0972:            protected static void paintBackground(Graphics g,
0973:                    final JMenuItem menuItem) {
0974:                int textOffset = MenuUtilities.getTextOffset(menuItem, menuItem
0975:                        .getParent());
0976:                // System.out.println(menuItem.getText() + ":" + textOffset);
0977:                SubstanceTextPainter textPainter = SubstanceLookAndFeel
0978:                        .getCurrentTextPainter();
0979:                final Color bgColor = SubstanceCoreUtilities
0980:                        .getBackgroundFillColor(menuItem);
0981:                final int finalTextOffset = textOffset;
0982:                SubstanceTextPainter.BackgroundPaintingCallback callback = new SubstanceTextPainter.BackgroundPaintingCallback() {
0983:                    public void paintBackground(Graphics g) {
0984:                        Graphics2D g2d = (Graphics2D) g.create();
0985:                        backgroundDelegate.paintBackground(g, menuItem,
0986:                                bgColor, 0.5f, finalTextOffset);
0987:                        g2d.dispose();
0988:                    }
0989:                };
0990:                if (textPainter.needsBackgroundImage()) {
0991:                    textPainter
0992:                            .setBackgroundFill(menuItem, bgColor, true, 0, 0);
0993:                    textPainter.attachCallback(callback);
0994:                } else {
0995:                    callback.paintBackground(g);
0996:                }
0997:            }
0998:
0999:            protected static void paintHighlights(Graphics g,
1000:                    final JMenuItem menuItem) {
1001:                SubstanceTextPainter textPainter = SubstanceLookAndFeel
1002:                        .getCurrentTextPainter();
1003:                SubstanceTextPainter.BackgroundPaintingCallback callback = new SubstanceTextPainter.BackgroundPaintingCallback() {
1004:                    public void paintBackground(Graphics g) {
1005:                        Graphics2D g2d = (Graphics2D) g.create();
1006:                        SubstanceMenuBackgroundDelegate.paintHighlights(g,
1007:                                menuItem, 0.5f);
1008:                        g2d.dispose();
1009:                    }
1010:                };
1011:                if (textPainter.needsBackgroundImage()) {
1012:                    textPainter.attachCallback(callback);
1013:                } else {
1014:                    callback.paintBackground(g);
1015:                }
1016:            }
1017:
1018:            protected static MenuLayoutMetrics getMetrics(JPopupMenu popupMenu) {
1019:                MenuLayoutMetrics metrics = new MenuLayoutMetrics();
1020:                for (int i = 0; i < popupMenu.getComponentCount(); i++) {
1021:                    Component comp = popupMenu.getComponent(i);
1022:                    if (comp instanceof  JMenuItem) {
1023:                        JMenuItem childMenuItem = (JMenuItem) comp;
1024:                        ButtonUI bui = childMenuItem.getUI();
1025:                        if (!(bui instanceof  SubstanceMenu))
1026:                            continue;
1027:                        SubstanceMenu ui = (SubstanceMenu) bui;
1028:                        MenuLayoutInfo mli = MenuUtilities.getMenuLayoutInfo(
1029:                                childMenuItem, ui.getAcceleratorFont(), ui
1030:                                        .getCheckIcon(), ui.getArrowIcon(), ui
1031:                                        .getDefaultTextIconGap());
1032:                        metrics.maxIconWidth = Math.max(metrics.maxIconWidth,
1033:                                mli.iconRect.width);
1034:                        metrics.maxCheckIconWidth = Math.max(
1035:                                metrics.maxCheckIconWidth,
1036:                                mli.checkIconRect.width);
1037:                        metrics.maxTextWidth = Math.max(metrics.maxTextWidth,
1038:                                mli.textRect.width);
1039:                        metrics.maxAcceleratorWidth = Math.max(
1040:                                metrics.maxAcceleratorWidth,
1041:                                mli.acceleratorRect.width);
1042:                        metrics.maxArrowIconWidth = Math.max(
1043:                                metrics.maxArrowIconWidth,
1044:                                mli.arrowIconRect.width);
1045:                        metrics.maxGap = Math.max(metrics.maxGap, ui
1046:                                .getDefaultTextIconGap());
1047:                    }
1048:                }
1049:                return metrics;
1050:            }
1051:
1052:            public static MenuLayoutMetrics getPopupLayoutMetrics(
1053:                    JMenuItem menuItem) {
1054:                Component comp = menuItem.getParent();
1055:                if (comp instanceof  JPopupMenu) {
1056:                    JPopupMenu popupMenu = (JPopupMenu) comp;
1057:                    Object prop = popupMenu.getClientProperty(LAYOUT_METRICS);
1058:                    if (prop instanceof  MenuLayoutMetrics) {
1059:                        return (MenuLayoutMetrics) prop;
1060:                    }
1061:                    MenuLayoutMetrics metrics = getMetrics(popupMenu);
1062:                    popupMenu.putClientProperty(LAYOUT_METRICS, metrics);
1063:                    return metrics;
1064:                }
1065:                // If here, the parent is not popup menu - this is a top-level menu
1066:                // in a menu bar. No need to align the different rectangles
1067:                return null;
1068:            }
1069:
1070:            public static void cleanPopupLayoutMetrics(JMenuItem menuItem) {
1071:                Component comp = menuItem.getParent();
1072:                if (comp instanceof  JPopupMenu) {
1073:                    JPopupMenu popupMenu = (JPopupMenu) comp;
1074:                    cleanPopupLayoutMetrics(popupMenu);
1075:                }
1076:            }
1077:
1078:            public static void cleanPopupLayoutMetrics(JPopupMenu popupMenu) {
1079:                if (popupMenu != null) {
1080:                    popupMenu.putClientProperty(LAYOUT_METRICS, null);
1081:                }
1082:            }
1083:
1084:            public static int getPreferredWidth(JMenuItem menuItem) {
1085:                Insets ins = menuItem.getInsets();
1086:                MenuLayoutMetrics popupMetrics = MenuUtilities
1087:                        .getPopupLayoutMetrics(menuItem);
1088:
1089:                int width = popupMetrics.maxCheckIconWidth
1090:                        + popupMetrics.maxIconWidth + popupMetrics.maxTextWidth
1091:                        + popupMetrics.maxAcceleratorWidth
1092:                        + popupMetrics.maxArrowIconWidth + ins.left + ins.right;
1093:
1094:                int gapsToAdd = 0;
1095:                if (popupMetrics.maxCheckIconWidth > 0)
1096:                    gapsToAdd++;
1097:                if (popupMetrics.maxIconWidth > 0)
1098:                    gapsToAdd++;
1099:                if (popupMetrics.maxAcceleratorWidth > 0)
1100:                    gapsToAdd++;
1101:                if (popupMetrics.maxArrowIconWidth > 0)
1102:                    gapsToAdd++;
1103:
1104:                int gap = popupMetrics.maxGap;
1105:                width += ((1 + gapsToAdd) * gap);
1106:
1107:                if (popupMetrics.maxAcceleratorWidth > 0) {
1108:                    // at least one menu item has accelerator text
1109:                    width += 5 * gap;
1110:                }
1111:
1112:                MenuGutterFillKind gutterFillKind = SubstanceCoreUtilities
1113:                        .getMenuGutterFillKind();
1114:                boolean needExtraIconTextGap = (gutterFillKind != null)
1115:                        && (gutterFillKind != MenuGutterFillKind.NONE);
1116:                if (needExtraIconTextGap)
1117:                    width += gap;
1118:
1119:                return width;
1120:            }
1121:
1122:            public static int getTextOffset(JComponent menuItem,
1123:                    Component menuItemParent) {
1124:                if (!(menuItemParent instanceof  JPopupMenu)) {
1125:                    return 0;
1126:                }
1127:
1128:                Object itemProp = menuItem.getClientProperty(GUTTER_X);
1129:                if (itemProp instanceof  Integer) {
1130:                    return (Integer) itemProp;
1131:                }
1132:
1133:                JPopupMenu popupMenu = (JPopupMenu) menuItemParent;
1134:                Object parentProp = popupMenu.getClientProperty(GUTTER_X);
1135:                if (parentProp instanceof  Integer) {
1136:                    return (Integer) parentProp;
1137:                }
1138:                return 0;
1139:                // MenuLayoutMetrics metrics = getMetrics(popupMenu);
1140:                // if (popupMenu.getComponentOrientation().isLeftToRight()) {
1141:                // return SubstanceSizeUtils.getMenuItemMargin(SubstanceSizeUtils
1142:                // .getComponentFontSize(menuItem))
1143:                // + popupMenu.getInsets().left
1144:                // + metrics.maxCheckIconWidth
1145:                // + metrics.maxIconWidth
1146:                // + (int) (2.5 * SubstanceSizeUtils
1147:                // .getMenuTextIconGap(SubstanceSizeUtils
1148:                // .getComponentFontSize(popupMenu)));
1149:                // } else {
1150:                // return 0;
1151:                // }
1152:            }
1153:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.