001: /*
002: * Copyright (c) 2001-2007 JGoodies Karsten Lentzsch. All Rights Reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions are met:
006: *
007: * o Redistributions of source code must retain the above copyright notice,
008: * this list of conditions and the following disclaimer.
009: *
010: * o Redistributions in binary form must reproduce the above copyright notice,
011: * this list of conditions and the following disclaimer in the documentation
012: * and/or other materials provided with the distribution.
013: *
014: * o Neither the name of JGoodies Karsten Lentzsch nor the names of
015: * its contributors may be used to endorse or promote products derived
016: * from this software without specific prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
020: * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
021: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
022: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
023: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
024: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
025: * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
026: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
027: * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
028: * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029: */
030:
031: package com.jgoodies.looks.windows;
032:
033: import java.awt.Color;
034: import java.awt.Dimension;
035: import java.awt.Graphics;
036:
037: import javax.swing.ButtonModel;
038: import javax.swing.Icon;
039: import javax.swing.JComponent;
040: import javax.swing.JMenu;
041: import javax.swing.JMenuItem;
042: import javax.swing.UIManager;
043: import javax.swing.plaf.ComponentUI;
044: import javax.swing.plaf.UIResource;
045:
046: import com.jgoodies.looks.common.MenuItemRenderer;
047:
048: /**
049: * The JGoodies Windows XP look&feel implementation of <code>MenuUI</code>.<p>
050: *
051: * It differs from the superclass in that it uses an overhauled menu
052: * rendering an aligmnent system. Furthermore, you can set a client property
053: * <tt>Options.NO_ICONS_KEY</tt> to indicate that this menu has no icons.
054: *
055: * @author Karsten Lentzsch
056: * @version $Revision: 1.3 $
057: *
058: * @see com.jgoodies.looks.Options
059: */
060:
061: public final class WindowsXPMenuUI extends
062: com.sun.java.swing.plaf.windows.WindowsMenuUI {
063:
064: private static final String MENU_PROPERTY_PREFIX = "Menu";
065: private static final String SUBMENU_PROPERTY_PREFIX = "MenuItem";
066:
067: // May be changed to SUBMENU_PROPERTY_PREFIX later
068: private String propertyPrefix = MENU_PROPERTY_PREFIX;
069:
070: private MenuItemRenderer renderer;
071:
072: public static ComponentUI createUI(JComponent b) {
073: return new WindowsXPMenuUI();
074: }
075:
076: // Install and Uninstall **************************************************
077:
078: protected void installDefaults() {
079: super .installDefaults();
080: if (arrowIcon == null || arrowIcon instanceof UIResource) {
081: arrowIcon = UIManager.getIcon("Menu.arrowIcon");
082: }
083: renderer = new MenuItemRenderer(menuItem, false,
084: acceleratorFont, selectionForeground,
085: disabledForeground, acceleratorForeground,
086: acceleratorSelectionForeground);
087: Integer gap = (Integer) UIManager.get(getPropertyPrefix()
088: + ".textIconGap");
089: defaultTextIconGap = gap != null ? gap.intValue() : 2;
090: }
091:
092: protected void uninstallDefaults() {
093: super .uninstallDefaults();
094: renderer = null;
095: }
096:
097: protected String getPropertyPrefix() {
098: return propertyPrefix;
099: }
100:
101: protected Dimension getPreferredMenuItemSize(JComponent c,
102: Icon aCheckIcon, Icon anArrowIcon, int textIconGap) {
103:
104: if (isSubMenu(menuItem)) {
105: ensureSubMenuInstalled();
106: return renderer.getPreferredMenuItemSize(c, aCheckIcon,
107: anArrowIcon, textIconGap);
108: } else {
109: Dimension size = super .getPreferredMenuItemSize(c,
110: aCheckIcon, anArrowIcon, textIconGap);
111: int width = size.width;
112: int height = size.height;
113: if (height % 2 == 1)
114: height--;
115: return new Dimension(width, height);
116: }
117: }
118:
119: protected void paintMenuItem(Graphics g, JComponent c,
120: Icon aCheckIcon, Icon anArrowIcon, Color background,
121: Color foreground, int textIconGap) {
122: if (isSubMenu(menuItem)) {
123: renderer.paintMenuItem(g, c, aCheckIcon, anArrowIcon,
124: background, foreground, textIconGap);
125: } else {
126: super .paintMenuItem(g, c, aCheckIcon, anArrowIcon,
127: background, foreground, textIconGap);
128: }
129: }
130:
131: /**
132: * Checks if we have already detected the correct menu type,
133: * menu in menu bar vs. sub menu; reinstalls if necessary.
134: */
135: private void ensureSubMenuInstalled() {
136: if (propertyPrefix.equals(SUBMENU_PROPERTY_PREFIX))
137: return;
138:
139: ButtonModel model = menuItem.getModel();
140:
141: //save values of armed and selected properties.
142: //they will be resetted in #ununinstallDefaults().
143: boolean oldArmed = model.isArmed();
144: boolean oldSelected = model.isSelected();
145:
146: uninstallDefaults();
147: propertyPrefix = SUBMENU_PROPERTY_PREFIX;
148: installDefaults();
149:
150: //restore values of armed and selected properties
151: model.setArmed(oldArmed);
152: model.setSelected(oldSelected);
153: }
154:
155: // Helper Code **********************************************************
156:
157: private boolean isSubMenu(JMenuItem aMenuItem) {
158: return !((JMenu) aMenuItem).isTopLevelMenu();
159: }
160:
161: }
|