0001: /*
0002: * @(#)VsnetMenuItemUI.java
0003: *
0004: * Copyright 2002 JIDE Software Inc. All rights reserved.
0005: */
0006:
0007: package com.jidesoft.plaf.vsnet;
0008:
0009: import com.jidesoft.icons.IconsFactory;
0010: import com.jidesoft.plaf.UIDefaultsLookup;
0011: import com.jidesoft.plaf.basic.ThemePainter;
0012: import com.jidesoft.swing.ButtonStyle;
0013: import com.jidesoft.swing.JideSwingUtilities;
0014: import com.jidesoft.swing.TopLevelMenuContainer;
0015: import com.jidesoft.utils.SecurityUtils;
0016: import com.sun.java.swing.plaf.windows.WindowsGraphicsUtils;
0017: import com.sun.java.swing.plaf.windows.WindowsLookAndFeel;
0018:
0019: import javax.swing.*;
0020: import javax.swing.event.*;
0021: import javax.swing.plaf.*;
0022: import javax.swing.plaf.basic.BasicHTML;
0023: import javax.swing.text.View;
0024: import java.awt.*;
0025: import java.awt.event.ActionEvent;
0026: import java.awt.event.InputEvent;
0027: import java.awt.event.KeyEvent;
0028: import java.awt.event.MouseEvent;
0029: import java.beans.PropertyChangeEvent;
0030: import java.beans.PropertyChangeListener;
0031:
0032: /**
0033: * MenuItem UI implementation
0034: */
0035: public class VsnetMenuItemUI extends MenuItemUI {
0036: protected JMenuItem menuItem = null;
0037: protected Color selectionBackground;
0038: protected Color selectionForeground;
0039: protected Color disabledForeground;
0040: protected Color acceleratorForeground;
0041: protected Color acceleratorSelectionForeground;
0042: private String acceleratorDelimiter;
0043:
0044: protected int defaultTextIconGap;
0045: protected Font acceleratorFont;
0046:
0047: protected MouseInputListener mouseInputListener;
0048: protected MenuDragMouseListener menuDragMouseListener;
0049: protected MenuKeyListener menuKeyListener;
0050: private PropertyChangeListener propertyChangeListener;
0051:
0052: protected Icon arrowIcon = null;
0053: protected Icon checkIcon = null;
0054:
0055: protected boolean oldBorderPainted;
0056:
0057: /**
0058: * Used for accelerator binding, lazily created.
0059: */
0060: protected InputMap windowInputMap;
0061:
0062: /* diagnostic aids -- should be false for production builds. */
0063: private static final boolean DEBUG = false; // show bad params, misc.
0064:
0065: // added for VsnetMenuItemUI
0066: protected Color shadowColor;
0067: protected int defaultAccelEndGap;
0068: protected int defaultShadowWidth;
0069: protected Color borderColor;
0070: protected Color backgroundColor;
0071: // end added for VsnetMenuItemUI
0072:
0073: /* Client Property keys for text and accelerator text widths */
0074: static final String MAX_TEXT_WIDTH = "maxTextWidth";
0075: static final String MAX_ACC_WIDTH = "maxAccWidth";
0076:
0077: protected boolean _isFloatingIcon = false;
0078:
0079: private ThemePainter _painter = (ThemePainter) UIDefaultsLookup
0080: .get("Theme.painter");
0081:
0082: public static ComponentUI createUI(JComponent c) {
0083: return new VsnetMenuItemUI();
0084: }
0085:
0086: @Override
0087: public void installUI(JComponent c) {
0088: menuItem = (JMenuItem) c;
0089:
0090: installDefaults();
0091: installComponents(menuItem);
0092: installListeners();
0093: installKeyboardActions();
0094: }
0095:
0096: protected void installDefaults() {
0097: String prefix = getPropertyPrefix();
0098:
0099: acceleratorFont = UIDefaultsLookup
0100: .getFont("MenuItem.acceleratorFont");
0101:
0102: menuItem.setOpaque(true);
0103: if (menuItem.getMargin() == null
0104: || (menuItem.getMargin() instanceof UIResource)) {
0105: menuItem.setMargin(UIDefaultsLookup.getInsets(prefix
0106: + ".margin"));
0107: }
0108:
0109: // added for VsnetMenuItemUI
0110: defaultTextIconGap = UIDefaultsLookup.getInt(prefix
0111: + ".textIconGap");
0112: defaultAccelEndGap = UIDefaultsLookup
0113: .getInt("MenuItem.accelEndGap");
0114: defaultShadowWidth = UIDefaultsLookup
0115: .getInt("MenuItem.shadowWidth");
0116: // end add
0117:
0118: borderColor = UIDefaultsLookup
0119: .getColor("MenuItem.selectionBorderColor");
0120: backgroundColor = UIDefaultsLookup
0121: .getColor("MenuItem.background");
0122: shadowColor = UIDefaultsLookup.getColor("MenuItem.shadowColor");
0123:
0124: LookAndFeel.installBorder(menuItem, prefix + ".border");
0125: oldBorderPainted = menuItem.isBorderPainted();
0126: Object borderPainted = UIDefaultsLookup.get(prefix
0127: + ".borderPainted");
0128: if (borderPainted instanceof Boolean) {
0129: menuItem.setBorderPainted((Boolean) borderPainted);
0130: }
0131: LookAndFeel.installColorsAndFont(menuItem, prefix
0132: + ".background", prefix + ".foreground", prefix
0133: + ".font");
0134:
0135: // MenuItem specific defaults
0136: if (selectionBackground == null
0137: || selectionBackground instanceof UIResource) {
0138: selectionBackground = UIDefaultsLookup.getColor(prefix
0139: + ".selectionBackground");
0140: }
0141: if (selectionForeground == null
0142: || selectionForeground instanceof UIResource) {
0143: selectionForeground = UIDefaultsLookup.getColor(prefix
0144: + ".selectionForeground");
0145: }
0146: if (disabledForeground == null
0147: || disabledForeground instanceof UIResource) {
0148: disabledForeground = UIDefaultsLookup.getColor(prefix
0149: + ".disabledForeground");
0150: }
0151: if (acceleratorForeground == null
0152: || acceleratorForeground instanceof UIResource) {
0153: acceleratorForeground = UIDefaultsLookup.getColor(prefix
0154: + ".acceleratorForeground");
0155: }
0156: if (acceleratorSelectionForeground == null
0157: || acceleratorSelectionForeground instanceof UIResource) {
0158: acceleratorSelectionForeground = UIDefaultsLookup
0159: .getColor(prefix
0160: + ".acceleratorSelectionForeground");
0161: }
0162: // Get accelerator delimiter
0163: acceleratorDelimiter = UIDefaultsLookup
0164: .getString("MenuItem.acceleratorDelimiter");
0165: if (acceleratorDelimiter == null) {
0166: acceleratorDelimiter = "+";
0167: }
0168: // Icons
0169: if (arrowIcon == null || arrowIcon instanceof UIResource) {
0170: arrowIcon = UIDefaultsLookup.getIcon(prefix + ".arrowIcon");
0171: }
0172: if (checkIcon == null || checkIcon instanceof UIResource) {
0173: checkIcon = UIDefaultsLookup.getIcon(prefix + ".checkIcon");
0174: }
0175:
0176: _isFloatingIcon = UIDefaultsLookup.getBoolean("Icon.floating");
0177: }
0178:
0179: /**
0180: * @since 1.3
0181: */
0182: protected void installComponents(JMenuItem menuItem) {
0183: BasicHTML.updateRenderer(menuItem, menuItem.getText());
0184: }
0185:
0186: protected String getPropertyPrefix() {
0187: return "MenuItem";
0188: }
0189:
0190: protected void installListeners() {
0191: if ((mouseInputListener = createMouseInputListener(menuItem)) != null) {
0192: menuItem.addMouseListener(mouseInputListener);
0193: menuItem.addMouseMotionListener(mouseInputListener);
0194: }
0195: if ((menuDragMouseListener = createMenuDragMouseListener(menuItem)) != null) {
0196: menuItem.addMenuDragMouseListener(menuDragMouseListener);
0197: }
0198: if ((menuKeyListener = createMenuKeyListener(menuItem)) != null) {
0199: menuItem.addMenuKeyListener(menuKeyListener);
0200: }
0201: if ((propertyChangeListener = createPropertyChangeListener(menuItem)) != null) {
0202: menuItem.addPropertyChangeListener(propertyChangeListener);
0203: }
0204: }
0205:
0206: protected void installKeyboardActions() {
0207: ActionMap actionMap = getActionMap();
0208:
0209: SwingUtilities.replaceUIActionMap(menuItem, actionMap);
0210: updateAcceleratorBinding();
0211: }
0212:
0213: @Override
0214: public void uninstallUI(JComponent c) {
0215: menuItem = (JMenuItem) c;
0216: uninstallDefaults();
0217: uninstallComponents(menuItem);
0218: uninstallListeners();
0219: uninstallKeyboardActions();
0220:
0221: //Remove the textWidth and accWidth values from the parent's Client Properties.
0222: Container parent = menuItem.getParent();
0223: if ((parent != null && parent instanceof JComponent)
0224: && !(menuItem instanceof JMenu && ((JMenu) menuItem)
0225: .isTopLevelMenu())) {
0226: JComponent p = (JComponent) parent;
0227: p.putClientProperty(VsnetMenuItemUI.MAX_ACC_WIDTH, null);
0228: p.putClientProperty(VsnetMenuItemUI.MAX_TEXT_WIDTH, null);
0229: }
0230:
0231: menuItem = null;
0232: }
0233:
0234: protected void uninstallDefaults() {
0235: LookAndFeel.uninstallBorder(menuItem);
0236: menuItem.setBorderPainted(oldBorderPainted);
0237: if (menuItem.getMargin() instanceof UIResource)
0238: menuItem.setMargin(null);
0239: if (arrowIcon instanceof UIResource)
0240: arrowIcon = null;
0241: if (checkIcon instanceof UIResource)
0242: checkIcon = null;
0243: }
0244:
0245: /**
0246: * @since 1.3
0247: */
0248: protected void uninstallComponents(JMenuItem menuItem) {
0249: BasicHTML.updateRenderer(menuItem, "");
0250: }
0251:
0252: protected void uninstallListeners() {
0253: if (mouseInputListener != null) {
0254: menuItem.removeMouseListener(mouseInputListener);
0255: menuItem.removeMouseMotionListener(mouseInputListener);
0256: }
0257: if (menuDragMouseListener != null) {
0258: menuItem.removeMenuDragMouseListener(menuDragMouseListener);
0259: }
0260: if (menuKeyListener != null) {
0261: menuItem.removeMenuKeyListener(menuKeyListener);
0262: }
0263: if (propertyChangeListener != null) {
0264: menuItem
0265: .removePropertyChangeListener(propertyChangeListener);
0266: }
0267:
0268: mouseInputListener = null;
0269: menuDragMouseListener = null;
0270: menuKeyListener = null;
0271: propertyChangeListener = null;
0272: }
0273:
0274: protected void uninstallKeyboardActions() {
0275: SwingUtilities.replaceUIActionMap(menuItem, null);
0276: if (windowInputMap != null) {
0277: SwingUtilities.replaceUIInputMap(menuItem,
0278: JComponent.WHEN_IN_FOCUSED_WINDOW, null);
0279: windowInputMap = null;
0280: }
0281: }
0282:
0283: protected MouseInputListener createMouseInputListener(JComponent c) {
0284: return new MouseInputHandler();
0285: }
0286:
0287: protected MenuDragMouseListener createMenuDragMouseListener(
0288: JComponent c) {
0289: return new MenuDragMouseHandler();
0290: }
0291:
0292: protected MenuKeyListener createMenuKeyListener(JComponent c) {
0293: return new MenuKeyHandler();
0294: }
0295:
0296: private PropertyChangeListener createPropertyChangeListener(
0297: JComponent c) {
0298: return new PropertyChangeHandler();
0299: }
0300:
0301: ActionMap getActionMap() {
0302: String propertyPrefix = getPropertyPrefix();
0303: String uiKey = propertyPrefix + ".actionMap";
0304: ActionMap am = (ActionMap) UIDefaultsLookup.get(uiKey);
0305: if (am == null) {
0306: am = createActionMap();
0307: UIManager.getLookAndFeelDefaults().put(uiKey, am);
0308: }
0309: return am;
0310: }
0311:
0312: protected ActionMap createActionMap() {
0313: ActionMap map = new ActionMapUIResource();
0314: map.put("doClick", new ClickAction());
0315:
0316: // removed for VsnetMenuItem. it's protected method
0317: // Set the ActionMap's parent to the Auditory Feedback Action Map
0318: // BasicLookAndFeel lf = (BasicLookAndFeel) UIManager.getLookAndFeel();
0319: // ActionMap audioMap = lf.getAudioActionMap();
0320: // map.setParent(audioMap);
0321:
0322: return map;
0323: }
0324:
0325: protected InputMap createInputMap(int condition) {
0326: if (condition == JComponent.WHEN_IN_FOCUSED_WINDOW) {
0327: return new ComponentInputMapUIResource(menuItem);
0328: }
0329: return null;
0330: }
0331:
0332: void updateAcceleratorBinding() {
0333: KeyStroke accelerator = menuItem.getAccelerator();
0334:
0335: if (windowInputMap != null) {
0336: windowInputMap.clear();
0337: }
0338: if (accelerator != null) {
0339: if (windowInputMap == null) {
0340: windowInputMap = createInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
0341: SwingUtilities.replaceUIInputMap(menuItem,
0342: JComponent.WHEN_IN_FOCUSED_WINDOW,
0343: windowInputMap);
0344: }
0345: windowInputMap.put(accelerator, "doClick");
0346: }
0347: }
0348:
0349: @Override
0350: public Dimension getMinimumSize(JComponent c) {
0351: Dimension d = null;
0352: View v = (View) c.getClientProperty(BasicHTML.propertyKey);
0353: if (v != null) {
0354: d = getPreferredSize(c);
0355: d.width -= v.getPreferredSpan(View.X_AXIS)
0356: - v.getMinimumSpan(View.X_AXIS);
0357: }
0358: return d;
0359: }
0360:
0361: @Override
0362: public Dimension getPreferredSize(JComponent c) {
0363: return getPreferredMenuItemSize(c, checkIcon, arrowIcon,
0364: defaultTextIconGap);
0365: }
0366:
0367: @Override
0368: public Dimension getMaximumSize(JComponent c) {
0369: Dimension d = null;
0370: View v = (View) c.getClientProperty(BasicHTML.propertyKey);
0371: if (v != null) {
0372: d = getPreferredSize(c);
0373: d.width += v.getMaximumSpan(View.X_AXIS)
0374: - v.getPreferredSpan(View.X_AXIS);
0375: }
0376: return d;
0377: }
0378:
0379: // these rects are used for painting and preferredsize calculations.
0380: // they used to be regenerated constantly. Now they are reused.
0381: protected static Rectangle zeroRect = new Rectangle(0, 0, 0, 0);
0382: protected static Rectangle iconRect = new Rectangle();
0383: protected static Rectangle textRect = new Rectangle();
0384: protected static Rectangle acceleratorRect = new Rectangle();
0385: protected static Rectangle checkIconRect = new Rectangle();
0386: protected static Rectangle arrowIconRect = new Rectangle();
0387: protected static Rectangle viewRect = new Rectangle(
0388: Short.MAX_VALUE, Short.MAX_VALUE);
0389: static Rectangle r = new Rectangle();
0390:
0391: private void resetRects() {
0392: iconRect.setBounds(zeroRect);
0393: textRect.setBounds(zeroRect);
0394: acceleratorRect.setBounds(zeroRect);
0395: checkIconRect.setBounds(zeroRect);
0396: arrowIconRect.setBounds(zeroRect);
0397: viewRect.setBounds(0, 0, Short.MAX_VALUE, Short.MAX_VALUE);
0398: r.setBounds(zeroRect);
0399: }
0400:
0401: protected Dimension getPreferredMenuItemSize(JComponent c,
0402: Icon checkIcon, Icon arrowIcon, int textIconGap) {
0403: JMenuItem b = (JMenuItem) c;
0404: Icon icon = b.getIcon();
0405: String text = b.getText();
0406: KeyStroke accelerator = b.getAccelerator();
0407: String acceleratorText = "";
0408:
0409: if (accelerator != null) {
0410: int modifiers = accelerator.getModifiers();
0411: if (modifiers > 0) {
0412: acceleratorText = KeyEvent
0413: .getKeyModifiersText(modifiers);
0414: //acceleratorText += "-";
0415: acceleratorText += acceleratorDelimiter;
0416: }
0417: int keyCode = accelerator.getKeyCode();
0418: if (keyCode != 0) {
0419: acceleratorText += KeyEvent.getKeyText(keyCode);
0420: } else {
0421: acceleratorText += accelerator.getKeyChar();
0422: }
0423: }
0424:
0425: Font font = b.getFont();
0426: FontMetrics fm = b.getFontMetrics(font);
0427: FontMetrics fmAccel = b.getFontMetrics(acceleratorFont);
0428:
0429: resetRects();
0430:
0431: layoutMenuItem(fm, text, fmAccel, acceleratorText, icon,
0432: checkIcon, arrowIcon, b.getVerticalAlignment(), b
0433: .getHorizontalAlignment(), b
0434: .getVerticalTextPosition(), b
0435: .getHorizontalTextPosition(), viewRect,
0436: iconRect, textRect, acceleratorRect, checkIconRect,
0437: arrowIconRect, text == null ? 0 : textIconGap,
0438: defaultTextIconGap);
0439:
0440: // find the union of the icon and text rects
0441: if (text != null && text.trim().length() != 0) {
0442: r.setBounds(textRect);
0443: }
0444: if (!iconRect.isEmpty()) {
0445: r = SwingUtilities.computeUnion(iconRect.x, iconRect.y,
0446: iconRect.width, iconRect.height, r);
0447: }
0448:
0449: // To make the accelerator texts appear in a column, find the widest MenuItem text
0450: // and the widest accelerator text.
0451:
0452: //Get the parent, which stores the information.
0453: Container parent = menuItem.getParent();
0454:
0455: //Check the parent, and see that it is not a top-level menu.
0456: if (parent != null
0457: && parent instanceof JComponent
0458: && !(menuItem instanceof JMenu && ((JMenu) menuItem)
0459: .isTopLevelMenu())) {
0460: JComponent p = (JComponent) parent;
0461:
0462: //Get widest text so far from parent, if no one exists null is returned.
0463: Integer maxTextWidth = (Integer) p
0464: .getClientProperty(VsnetMenuItemUI.MAX_TEXT_WIDTH);
0465: Integer maxAccWidth = (Integer) p
0466: .getClientProperty(VsnetMenuItemUI.MAX_ACC_WIDTH);
0467:
0468: int maxTextValue = maxTextWidth != null ? maxTextWidth : 0;
0469: int maxAccValue = maxAccWidth != null ? maxAccWidth : 0;
0470:
0471: //Compare the text widths, and adjust the r.width to the widest.
0472: if (r.width < maxTextValue) {
0473: r.width = maxTextValue;
0474: } else {
0475: p.putClientProperty(VsnetMenuItemUI.MAX_TEXT_WIDTH,
0476: r.width);
0477: }
0478:
0479: //Compare the accelarator widths.
0480: if (acceleratorRect.width > maxAccValue) {
0481: maxAccValue = acceleratorRect.width;
0482: p.putClientProperty(VsnetMenuItemUI.MAX_ACC_WIDTH,
0483: acceleratorRect.width);
0484: }
0485:
0486: r.width += maxAccValue;
0487: r.width += textIconGap;
0488: r.width += defaultAccelEndGap;
0489: }
0490:
0491: if (text != null && text.trim().length() != 0) {
0492: if (icon != null) {
0493: r.width += textIconGap;
0494: }
0495: }
0496:
0497: Insets insets = b.getInsets();
0498:
0499: if (useCheckAndArrow()) {
0500: insets.left = 0;
0501: insets.right = 0;
0502: r.width += 5;
0503: }
0504:
0505: if (isDownArrowVisible(parent)) {
0506: insets.left = 0;
0507: insets.right = 0;
0508: r.width += 7;
0509: }
0510:
0511: if (insets != null) {
0512: r.width += insets.left + insets.right;
0513: r.height += insets.top + insets.bottom;
0514: }
0515:
0516: // if the width is even, bump it up one. This is critical
0517: // for the focus dash line to draw properly
0518: if (r.width % 2 == 0) {
0519: r.width++;
0520: }
0521:
0522: // if the height is even, bump it up one. This is critical
0523: // for the text to center properly
0524: // if (r.height % 2 == 0) {
0525: // r.height++;
0526: // }
0527:
0528: if (JideSwingUtilities.getOrientationOf(menuItem) == SwingConstants.HORIZONTAL) {
0529: return r.getSize();
0530: } else {
0531: return new Dimension(r.height, r.width);
0532: }
0533: }
0534:
0535: /**
0536: * We draw the background in paintMenuItem()
0537: * so override update (which fills the background of opaque
0538: * components by default) to just call paint().
0539: */
0540: @Override
0541: public void update(Graphics g, JComponent c) {
0542: paint(g, c);
0543: }
0544:
0545: @Override
0546: public void paint(Graphics g, JComponent c) {
0547: paintMenuItem(g, c, checkIcon, arrowIcon, selectionBackground,
0548: selectionForeground, defaultTextIconGap);
0549: }
0550:
0551: protected void paintMenuItem(Graphics g, JComponent c,
0552: Icon checkIcon, Icon arrowIcon, Color background,
0553: Color foreground, int defaultTextIconGap) {
0554: JMenuItem b = (JMenuItem) c;
0555: ButtonModel model = b.getModel();
0556:
0557: int menuWidth = 0;
0558: int menuHeight = 0;
0559:
0560: if (JideSwingUtilities.getOrientationOf(menuItem) == SwingConstants.HORIZONTAL) {
0561: menuWidth = b.getWidth();
0562: menuHeight = b.getHeight();
0563: } else {
0564: // Dimension size = b.getSize();
0565: menuWidth = b.getHeight();
0566: menuHeight = b.getWidth();
0567: Graphics2D g2d = (Graphics2D) g;
0568: g2d.rotate(Math.PI / 2);
0569: g2d.translate(0, -menuHeight + 1);
0570: }
0571:
0572: Insets i = c.getInsets();
0573:
0574: resetRects();
0575:
0576: viewRect.setBounds(0, 0, menuWidth, menuHeight);
0577:
0578: if (isDownArrowVisible(b.getParent())) {
0579: viewRect.x += 3;
0580: viewRect.width -= 7;
0581: } else {
0582: viewRect.x += i.left;
0583: viewRect.width -= (i.right + viewRect.x);
0584: }
0585: viewRect.y += i.top;
0586: viewRect.height -= (i.bottom + viewRect.y);
0587:
0588: Font holdf = g.getFont();
0589: Font f = c.getFont();
0590: g.setFont(f);
0591: FontMetrics fm = g.getFontMetrics(f);
0592: FontMetrics fmAccel = g.getFontMetrics(acceleratorFont);
0593:
0594: // get Accelerator text
0595: KeyStroke accelerator = b.getAccelerator();
0596: String acceleratorText = "";
0597: if (accelerator != null) {
0598: int modifiers = accelerator.getModifiers();
0599: if (modifiers > 0) {
0600: acceleratorText = KeyEvent
0601: .getKeyModifiersText(modifiers);
0602: //acceleratorText += "-";
0603: acceleratorText += acceleratorDelimiter;
0604: }
0605:
0606: int keyCode = accelerator.getKeyCode();
0607: if (keyCode != 0) {
0608: acceleratorText += KeyEvent.getKeyText(keyCode);
0609: } else {
0610: acceleratorText += accelerator.getKeyChar();
0611: }
0612: }
0613:
0614: // layout the text and icon
0615: String text = layoutMenuItem(fm, b.getText(), fmAccel,
0616: acceleratorText, b.getIcon(), checkIcon, arrowIcon, b
0617: .getVerticalAlignment(), b
0618: .getHorizontalAlignment(), b
0619: .getVerticalTextPosition(), b
0620: .getHorizontalTextPosition(), viewRect,
0621: iconRect, textRect, acceleratorRect, checkIconRect,
0622: arrowIconRect, b.getText() == null ? 0
0623: : defaultTextIconGap, defaultTextIconGap);
0624:
0625: // Paint background
0626: paintBackground(g, b, background);
0627:
0628: Color holdc = g.getColor();
0629:
0630: // Paint the Check
0631: if ((c.getUIClassID().indexOf("CheckBoxMenu") >= 0 || c
0632: .getUIClassID().indexOf("RadioButtonMenu") >= 0)
0633: && checkIcon != null) {
0634: paintCheckBox(b, g, checkIcon);
0635: g.setColor(holdc);
0636: }
0637:
0638: // rotate back since we don't want to paint icon in rotated way.
0639: if (JideSwingUtilities.getOrientationOf(menuItem) == SwingConstants.VERTICAL) {
0640: // Dimension size = b.getSize();
0641: Graphics2D g2d = (Graphics2D) g;
0642: g2d.rotate(-Math.PI / 2);
0643: g2d.translate(-menuHeight + 1, 0);
0644: }
0645:
0646: paintIcon(b, g);
0647:
0648: if (JideSwingUtilities.getOrientationOf(menuItem) == SwingConstants.VERTICAL) {
0649: // Dimension size = b.getSize();
0650: Graphics2D g2d = (Graphics2D) g;
0651: g2d.rotate(Math.PI / 2);
0652: g2d.translate(0, -menuHeight + 1);
0653: }
0654:
0655: // Draw the Text
0656: if (text != null) {
0657: View v = (View) c.getClientProperty(BasicHTML.propertyKey);
0658: if (v != null) {
0659: v.paint(g, textRect);
0660: } else {
0661: paintText(g, b, textRect, text);
0662: }
0663: }
0664:
0665: // Draw the Accelerator Text
0666: if (acceleratorText != null && !acceleratorText.equals("")) {
0667:
0668: //Get the maxAccWidth from the parent to calculate the offset.
0669: int accOffset = 0;
0670: Container parent = menuItem.getParent();
0671: if (parent != null && parent instanceof JComponent) {
0672: JComponent p = (JComponent) parent;
0673: Integer maxValueInt = (Integer) p
0674: .getClientProperty(VsnetMenuItemUI.MAX_ACC_WIDTH);
0675: int maxValue = maxValueInt != null ? maxValueInt
0676: : acceleratorRect.width;
0677:
0678: //Calculate the offset, with which the accelerator texts will be drawn with.
0679: accOffset = maxValue - acceleratorRect.width;
0680: }
0681:
0682: g.setFont(acceleratorFont);
0683: if (!model.isEnabled()) {
0684: // *** paint the acceleratorText disabled
0685: if (disabledForeground != null) {
0686: g.setColor(disabledForeground);
0687: JideSwingUtilities.drawString(menuItem, g,
0688: acceleratorText, acceleratorRect.x
0689: - accOffset, acceleratorRect.y
0690: + fmAccel.getAscent());
0691: } else {
0692: g.setColor(b.getBackground().brighter());
0693: JideSwingUtilities.drawString(menuItem, g,
0694: acceleratorText, acceleratorRect.x
0695: - accOffset, acceleratorRect.y
0696: + fmAccel.getAscent());
0697: g.setColor(b.getBackground().darker());
0698: JideSwingUtilities.drawString(menuItem, g,
0699: acceleratorText, acceleratorRect.x
0700: - accOffset - 1, acceleratorRect.y
0701: + fmAccel.getAscent() - 1);
0702: }
0703: } else {
0704: // *** paint the acceleratorText normally
0705: if (model.isArmed()
0706: || (c instanceof JMenu && model.isSelected())) {
0707: g.setColor(acceleratorSelectionForeground);
0708: } else {
0709: g.setColor(acceleratorForeground);
0710: }
0711: JideSwingUtilities.drawString(menuItem, g,
0712: acceleratorText, acceleratorRect.x - accOffset,
0713: acceleratorRect.y + fmAccel.getAscent());
0714: }
0715: }
0716:
0717: // Paint the Arrow
0718: if (arrowIcon != null) {
0719: if (model.isArmed()
0720: || (c instanceof JMenu && model.isSelected()))
0721: g.setColor(foreground);
0722: if (useCheckAndArrow())
0723: arrowIcon.paintIcon(c, g, arrowIconRect.x,
0724: arrowIconRect.y);
0725: }
0726: g.setColor(holdc);
0727: g.setFont(holdf);
0728: }
0729:
0730: protected void paintCheckBox(JMenuItem b, Graphics g, Icon checkIcon) {
0731: ButtonModel model = b.getModel();
0732: boolean isSelected = false;
0733: if (b instanceof JCheckBoxMenuItem)
0734: isSelected = ((JCheckBoxMenuItem) b).isSelected();
0735: else if (b instanceof JRadioButtonMenuItem)
0736: isSelected = ((JRadioButtonMenuItem) b).isSelected();
0737: if (isSelected) {
0738: if (model.isArmed()
0739: || (b instanceof JMenu && model.isSelected())) {
0740: getPainter().paintMenuItemBackground(b, g,
0741: checkIconRect, SwingConstants.HORIZONTAL,
0742: ThemePainter.STATE_PRESSED);
0743: if (b.getIcon() == null) {
0744: checkIcon.paintIcon(b, g, checkIconRect.x,
0745: checkIconRect.y);
0746: }
0747: } else {
0748: getPainter().paintMenuItemBackground(b, g,
0749: checkIconRect, SwingConstants.HORIZONTAL,
0750: ThemePainter.STATE_SELECTED);
0751: if (b.getIcon() == null) {
0752: checkIcon.paintIcon(b, g, checkIconRect.x,
0753: checkIconRect.y);
0754: }
0755: }
0756: }
0757: }
0758:
0759: protected void paintIcon(JMenuItem b, Graphics g) {
0760: if (b.getIcon() != null) {
0761: Icon icon = getIcon(b);
0762:
0763: ButtonModel model = b.getModel();
0764: if (icon != null) {
0765: if (isFloatingIcon()) {
0766: if (model.isArmed()
0767: || (b instanceof JMenu && model
0768: .isSelected())) {
0769: if (icon instanceof ImageIcon) {
0770: ImageIcon shadow = IconsFactory
0771: .createGrayImage(((ImageIcon) icon)
0772: .getImage());
0773: shadow.paintIcon(b, g, iconRect.x + 1,
0774: iconRect.y + 1);
0775: } else {
0776: ImageIcon shadow = IconsFactory
0777: .createGrayImage(b, icon);
0778: shadow.paintIcon(b, g, iconRect.x + 1,
0779: iconRect.y + 1);
0780: }
0781: icon.paintIcon(b, g, iconRect.x - 1,
0782: iconRect.y - 1);
0783: } else {
0784: icon.paintIcon(b, g, iconRect.x, iconRect.y);
0785: }
0786: } else {
0787: icon.paintIcon(b, g, iconRect.x, iconRect.y);
0788: }
0789: }
0790: }
0791: }
0792:
0793: /**
0794: * Draws the background of the menu item.
0795: *
0796: * @param g the paint graphics
0797: * @param menuItem menu item to be painted
0798: * @param bgColor selection background color
0799: * @since 1.4
0800: */
0801: protected void paintBackground(Graphics g, JMenuItem menuItem,
0802: Color bgColor) {
0803: ButtonModel model = menuItem.getModel();
0804: Color oldColor = g.getColor();
0805: int menuWidth = 0;
0806: int menuHeight = 0;
0807: if (JideSwingUtilities.getOrientationOf(menuItem) == SwingConstants.HORIZONTAL) {
0808: menuWidth = menuItem.getWidth();
0809: menuHeight = menuItem.getHeight();
0810: } else {
0811: menuWidth = menuItem.getHeight();
0812: menuHeight = menuItem.getWidth();
0813: }
0814:
0815: if (menuItem.isOpaque()) {
0816: if (menuItem.getComponentOrientation().isLeftToRight()) {
0817: getPainter().paintMenuShadow(
0818: menuItem,
0819: g,
0820: new Rectangle(0, 0, defaultShadowWidth,
0821: menuHeight), SwingConstants.HORIZONTAL,
0822: ThemePainter.STATE_DEFAULT);
0823: if (menuItem.getBackground() instanceof UIResource) {
0824: g.setColor(getPainter().getMenuItemBackground());
0825: } else {
0826: g.setColor(menuItem.getBackground());
0827: }
0828: g.fillRect(defaultShadowWidth, 0, menuWidth
0829: - defaultShadowWidth, menuHeight);
0830:
0831: if (model.isArmed()
0832: || (menuItem instanceof JMenu && model
0833: .isSelected())) {
0834: getPainter().paintMenuItemBackground(
0835: menuItem,
0836: g,
0837: new Rectangle(1, 0, menuWidth - 2,
0838: menuHeight),
0839: SwingConstants.HORIZONTAL,
0840: ThemePainter.STATE_ROLLOVER);
0841: }
0842:
0843: if ("true".equals(SecurityUtils.getProperty(
0844: "shadingtheme", "false"))) {
0845: JideSwingUtilities.fillSingleGradient(g,
0846: new Rectangle(0, 0, defaultShadowWidth,
0847: menuHeight), SwingConstants.EAST,
0848: 255);
0849: }
0850:
0851: g.setColor(oldColor);
0852: } else {
0853: g.setColor(shadowColor);
0854: g.fillRect(menuWidth - defaultShadowWidth, 0,
0855: defaultShadowWidth, menuHeight);
0856: if (menuItem.getBackground() instanceof UIResource) {
0857: g.setColor(getPainter().getMenuItemBackground());
0858: } else {
0859: g.setColor(menuItem.getBackground());
0860: }
0861: g.fillRect(0, 0, menuWidth - defaultShadowWidth,
0862: menuHeight);
0863:
0864: if (model.isArmed()
0865: || (menuItem instanceof JMenu && model
0866: .isSelected())) {
0867: getPainter().paintMenuItemBackground(menuItem, g,
0868: new Rectangle(0, 0, menuWidth, menuHeight),
0869: SwingConstants.HORIZONTAL,
0870: ThemePainter.STATE_ROLLOVER);
0871: }
0872:
0873: if ("true".equals(SecurityUtils.getProperty(
0874: "shadingtheme", "false"))) {
0875: JideSwingUtilities.fillSingleGradient(g,
0876: new Rectangle(menuWidth
0877: - defaultShadowWidth, 0,
0878: defaultShadowWidth, menuHeight),
0879: SwingConstants.WEST, 255);
0880: }
0881:
0882: g.setColor(oldColor);
0883: }
0884: }
0885: }
0886:
0887: /**
0888: * Method which renders the text of the current menu item.
0889: * <p/>
0890: *
0891: * @param g Graphics context
0892: * @param menuItem Current menu item to render
0893: * @param textRect Bounding rectangle to render the text.
0894: * @param text String to render
0895: */
0896: protected void paintText(Graphics g, JMenuItem menuItem,
0897: Rectangle textRect, String text) {
0898: // Note: This method is almost identical to the same method in WindowsMenuUI
0899: ButtonModel model = menuItem.getModel();
0900:
0901: FontMetrics fm = g.getFontMetrics();
0902:
0903: if (!model.isEnabled()) {
0904: // *** paint the text disabled
0905: WindowsGraphicsUtils.paintText(g, menuItem, textRect, text,
0906: 0);
0907: } else {
0908: int mnemonicIndex = menuItem.getDisplayedMnemonicIndex();
0909: // W2K Feature: Check to see if the Underscore should be rendered.
0910: if (WindowsLookAndFeel.isMnemonicHidden() == true) {
0911: mnemonicIndex = -1;
0912: }
0913:
0914: Color oldColor = g.getColor();
0915:
0916: // *** paint the text normally
0917: if (model.isArmed()
0918: || (menuItem instanceof JMenu && model.isSelected())) {
0919: g.setColor(selectionForeground); // Uses protected field.
0920: }
0921: JideSwingUtilities.drawStringUnderlineCharAt(menuItem, g,
0922: text, mnemonicIndex, textRect.x, textRect.y
0923: + fm.getAscent());
0924: g.setColor(oldColor);
0925: }
0926: }
0927:
0928: /**
0929: * Compute and return the location of the icons origin, the
0930: * location of origin of the text baseline, and a possibly clipped
0931: * version of the compound labels string. Locations are computed
0932: * relative to the viewRect rectangle.
0933: */
0934:
0935: private String layoutMenuItem(FontMetrics fm, String text,
0936: FontMetrics fmAccel, String acceleratorText, Icon icon,
0937: Icon checkIcon, Icon arrowIcon, int verticalAlignment,
0938: int horizontalAlignment, int verticalTextPosition,
0939: int horizontalTextPosition, Rectangle viewRect,
0940: Rectangle iconRect, Rectangle textRect,
0941: Rectangle acceleratorRect, Rectangle checkIconRect,
0942: Rectangle arrowIconRect, int textIconGap, int menuItemGap) {
0943: if (icon != null)
0944: if ((icon.getIconHeight() == 0)
0945: || (icon.getIconWidth() == 0))
0946: icon = null; // An exception may occur in case of zero sized icons
0947:
0948: viewRect.width -= getRightMargin(); // this line is mainly for JideSplitButton
0949: String newText = SwingUtilities.layoutCompoundLabel(menuItem,
0950: fm, text, icon, verticalAlignment, horizontalAlignment,
0951: verticalTextPosition, horizontalTextPosition, viewRect,
0952: iconRect, textRect, textIconGap);
0953: // only do it for split menu
0954: if (getRightMargin() > 0) {
0955: text = newText;
0956: }
0957: viewRect.width += getRightMargin(); // this line is mainly for JideSplitButton
0958:
0959: // get viewRect which is the bounds of menuitem
0960: viewRect.x = viewRect.y = 0;
0961: if (JideSwingUtilities.getOrientationOf(menuItem) == SwingConstants.HORIZONTAL) {
0962: // Dimension size = b.getSize();
0963: viewRect.height = menuItem.getHeight();
0964: viewRect.width = menuItem.getWidth();
0965: } else {
0966: // Dimension size = b.getSize();
0967: viewRect.height = menuItem.getWidth();
0968: viewRect.width = menuItem.getHeight();
0969: }
0970:
0971: // in the middle of setOrientation, the height and width are swapped.
0972: if (viewRect.height > viewRect.width) {
0973: int old = viewRect.height;
0974: viewRect.height = viewRect.width;
0975: viewRect.width = old;
0976: }
0977:
0978: /* Initialize the acceelratorText bounds rectangle textRect. If a null
0979: * or and empty String was specified we substitute "" here
0980: * and use 0,0,0,0 for acceleratorTextRect.
0981: */
0982: if ((acceleratorText == null) || acceleratorText.equals("")) {
0983: acceleratorRect.width = acceleratorRect.height = 0;
0984: acceleratorText = "";
0985: } else {
0986: acceleratorRect.width = SwingUtilities.computeStringWidth(
0987: fmAccel, acceleratorText);
0988: acceleratorRect.height = fmAccel.getHeight();
0989: }
0990:
0991: if ((text == null) || text.equals("")) {
0992: textRect.width = textRect.height = 0;
0993: text = "";
0994: } else {
0995: View v = null;
0996: v = (menuItem != null) ? (View) menuItem
0997: .getClientProperty("html") : null;
0998: if (v != null) {
0999: textRect.width = (int) v.getPreferredSpan(View.X_AXIS);
1000: textRect.height = (int) v.getPreferredSpan(View.Y_AXIS);
1001: } else {
1002: textRect.width = SwingUtilities.computeStringWidth(fm,
1003: text);
1004: textRect.height = fm.getHeight();
1005: }
1006: }
1007:
1008: if (icon == null) {
1009: if (useCheckAndArrow())
1010: iconRect.width = iconRect.height = 16;
1011: else
1012: iconRect.width = iconRect.height = 0;
1013: } else {
1014: iconRect.width = icon.getIconWidth();
1015: iconRect.height = icon.getIconHeight();
1016: }
1017:
1018: if (arrowIcon == null) {
1019: arrowIconRect.width = arrowIconRect.height = 0;
1020: } else {
1021: arrowIconRect.width = arrowIcon.getIconWidth();
1022: arrowIconRect.height = arrowIcon.getIconHeight();
1023: }
1024:
1025: if (checkIcon == null) {
1026: checkIconRect.width = checkIconRect.height = 0;
1027: } else {
1028: checkIconRect.width = checkIcon.getIconWidth();
1029: checkIconRect.height = checkIcon.getIconHeight();
1030: }
1031:
1032: if (menuItem.getComponentOrientation().isLeftToRight()) {
1033: // left a shadow for non-top level menu
1034: if (useCheckAndArrow()) {
1035: iconRect.x = (defaultShadowWidth - iconRect.width) >> 1;
1036: if (text != null && !text.equals("")) {
1037: textRect.x = defaultShadowWidth + textIconGap;
1038: }
1039: } else {
1040: // if (icon != null) {
1041: // if (isDownArrowVisible(menuItem.getParent())) {
1042: // iconRect.x = 3;
1043: // }
1044: // else {
1045: // iconRect.x = menuItem.getInsets().left;
1046: // }
1047: // if (text != null && !text.equals("")) {
1048: // textRect.x = iconRect.x + iconRect.width + textIconGap;
1049: // }
1050: // }
1051: // else {
1052: // if (text != null && !text.equals("")) {
1053: // if (isDownArrowVisible(menuItem.getParent())) {
1054: // textRect.x = 3;
1055: // }
1056: // else {
1057: // textRect.x = menuItem.getInsets().left;
1058: // }
1059: // }
1060: // }
1061: }
1062:
1063: // Position the Accelerator text rect
1064: acceleratorRect.x = viewRect.x + viewRect.width
1065: - menuItemGap - acceleratorRect.width;
1066:
1067: // Position the Check and Arrow Icons
1068: if (useCheckAndArrow()) {
1069: checkIconRect.x = (defaultShadowWidth - checkIconRect.width) >> 1;
1070: arrowIconRect.x = viewRect.x + viewRect.width
1071: - menuItemGap - 5 - arrowIconRect.width;
1072: }
1073: } else {
1074: // left a shadow for non-top level menu
1075: if (text != null && !text.equals("")) {
1076: textRect.x -= (useCheckAndArrow() ? defaultShadowWidth
1077: + textIconGap
1078: : (viewRect.width - textRect.width) >> 1);
1079: }
1080: iconRect.x -= (defaultShadowWidth - iconRect.width) >> 1;
1081:
1082: // Position the Accelerator text rect
1083: // acceleratorRect.x = 20;
1084:
1085: // Position the Check and Arrow Icons
1086: if (useCheckAndArrow()) {
1087: checkIconRect.x = viewRect.x
1088: + viewRect.width
1089: - ((defaultShadowWidth + checkIconRect.width) >> 1);
1090: arrowIconRect.x = viewRect.x + menuItemGap;
1091: }
1092: }
1093:
1094: if (verticalTextPosition == SwingConstants.CENTER) {
1095: // put it in the middle
1096: if (text != null && !text.equals("")) {
1097: textRect.y = ((viewRect.height - textRect.height) >> 1);
1098: }
1099: iconRect.y = ((viewRect.height - iconRect.height) >> 1);
1100: }
1101:
1102: Rectangle labelRect = iconRect.union(textRect);
1103:
1104: // Align the accelertor text and the check and arrow icons vertically
1105: // with the center of the label rect.
1106: acceleratorRect.y = labelRect.y + (labelRect.height >> 1)
1107: - (acceleratorRect.height >> 1);
1108:
1109: if (useCheckAndArrow()) {
1110: arrowIconRect.y = ((viewRect.height - arrowIconRect.height) >> 1);//
1111: checkIconRect.y = ((viewRect.height - checkIconRect.height) >> 1);//labelRect.y + (labelRect.height / 2) - (checkIconRect.height / 2);
1112: }
1113: //
1114:
1115: // System.out.println("Layout: text=" + menuItem.getText() + "\n\tv="
1116: // + viewRect + "\n\tc=" + checkIconRect + "\n\ti="
1117: // + iconRect + "\n\tt=" + textRect + "\n\tacc="
1118: // + acceleratorRect + "\n\ta=" + arrowIconRect + "\n");
1119:
1120: return text;
1121: }
1122:
1123: /*
1124: * Returns false if the component is a JMenu and it is a top
1125: * level menu (on the menubar).
1126: */
1127: protected boolean useCheckAndArrow() {
1128: boolean b = true;
1129: if ((menuItem instanceof JMenu)
1130: && (((JMenu) menuItem).isTopLevelMenu())) {
1131: b = false;
1132: }
1133: return b;
1134: }
1135:
1136: public MenuElement[] getPath() {
1137: MenuSelectionManager m = MenuSelectionManager.defaultManager();
1138: MenuElement oldPath[] = m.getSelectedPath();
1139: MenuElement newPath[];
1140: int i = oldPath.length;
1141: if (i == 0)
1142: return new MenuElement[0];
1143: Component parent = menuItem.getParent();
1144: if (oldPath[i - 1].getComponent() == parent) {
1145: // The parent popup menu is the last so far
1146: newPath = new MenuElement[i + 1];
1147: System.arraycopy(oldPath, 0, newPath, 0, i);
1148: newPath[i] = menuItem;
1149: } else {
1150: // A sibling menuitem is the current selection
1151: //
1152: // This probably needs to handle 'exit submenu into
1153: // a menu item. Search backwards along the current
1154: // selection until you find the parent popup menu,
1155: // then copy up to that and add yourself...
1156: int j;
1157: for (j = oldPath.length - 1; j >= 0; j--) {
1158: if (oldPath[j].getComponent() == parent)
1159: break;
1160: }
1161: newPath = new MenuElement[j + 2];
1162: System.arraycopy(oldPath, 0, newPath, 0, j + 1);
1163: newPath[j + 1] = menuItem;
1164: /*
1165: System.out.println("Sibling condition -- ");
1166: System.out.println("Old array : ");
1167: printMenuElementArray(oldPath, false);
1168: System.out.println("New array : ");
1169: printMenuElementArray(newPath, false);
1170: */
1171: }
1172: return newPath;
1173: }
1174:
1175: /*
1176: void printMenuElementArray(MenuElement path[], boolean dumpStack) {
1177: System.out.println("Path is(");
1178: int i, j;
1179: for (i = 0, j = path.length; i < j; i++) {
1180: for (int k = 0; k <= i; k++)
1181: System.out.print(" ");
1182: MenuElement me = (MenuElement) path[i];
1183: if (me instanceof JMenuItem)
1184: System.out.println(((JMenuItem) me).getText() + ", ");
1185: else if (me == null)
1186: System.out.println("NULL , ");
1187: else
1188: System.out.println("" + me + ", ");
1189: }
1190: System.out.println(")");
1191:
1192: if (dumpStack == true)
1193: Thread.dumpStack();
1194: }
1195:
1196: */
1197:
1198: protected class MouseInputHandler implements MouseInputListener {
1199: public void mouseClicked(MouseEvent e) {
1200: }
1201:
1202: public void mousePressed(MouseEvent e) {
1203: }
1204:
1205: public void mouseReleased(MouseEvent e) {
1206: if (!SwingUtilities.isLeftMouseButton(e)) {
1207: return;
1208: }
1209:
1210: MenuSelectionManager manager = MenuSelectionManager
1211: .defaultManager();
1212: Point p = e.getPoint();
1213: if (p.x >= 0 && p.x < menuItem.getWidth() && p.y >= 0
1214: && p.y < menuItem.getHeight()) {
1215: doClick(manager);
1216: } else {
1217: manager.processMouseEvent(e);
1218: }
1219: }
1220:
1221: public void mouseEntered(MouseEvent e) {
1222: MenuSelectionManager manager = MenuSelectionManager
1223: .defaultManager();
1224: int modifiers = e.getModifiers();
1225: // 4188027: drag enter/exit added in JDK 1.1.7A, JDK1.2
1226: if ((modifiers & (InputEvent.BUTTON1_MASK
1227: | InputEvent.BUTTON2_MASK | InputEvent.BUTTON3_MASK)) != 0) {
1228: MenuSelectionManager.defaultManager()
1229: .processMouseEvent(e);
1230: } else {
1231: manager.setSelectedPath(getPath());
1232: }
1233: }
1234:
1235: public void mouseExited(MouseEvent e) {
1236: MenuSelectionManager manager = MenuSelectionManager
1237: .defaultManager();
1238:
1239: int modifiers = e.getModifiers();
1240: // 4188027: drag enter/exit added in JDK 1.1.7A, JDK1.2
1241: if ((modifiers & (InputEvent.BUTTON1_MASK
1242: | InputEvent.BUTTON2_MASK | InputEvent.BUTTON3_MASK)) != 0) {
1243: MenuSelectionManager.defaultManager()
1244: .processMouseEvent(e);
1245: } else {
1246:
1247: MenuElement path[] = manager.getSelectedPath();
1248: if (path.length > 1) {
1249: MenuElement newPath[] = new MenuElement[path.length - 1];
1250: int i, c;
1251: for (i = 0, c = path.length - 1; i < c; i++)
1252: newPath[i] = path[i];
1253: manager.setSelectedPath(newPath);
1254: }
1255: }
1256: }
1257:
1258: public void mouseDragged(MouseEvent e) {
1259: MenuSelectionManager.defaultManager().processMouseEvent(e);
1260: }
1261:
1262: public void mouseMoved(MouseEvent e) {
1263: }
1264: }
1265:
1266: private class MenuDragMouseHandler implements MenuDragMouseListener {
1267: public void menuDragMouseEntered(MenuDragMouseEvent e) {
1268: }
1269:
1270: public void menuDragMouseDragged(MenuDragMouseEvent e) {
1271: MenuSelectionManager manager = e.getMenuSelectionManager();
1272: MenuElement path[] = e.getPath();
1273: manager.setSelectedPath(path);
1274: }
1275:
1276: public void menuDragMouseExited(MenuDragMouseEvent e) {
1277: }
1278:
1279: public void menuDragMouseReleased(MenuDragMouseEvent e) {
1280: MenuSelectionManager manager = e.getMenuSelectionManager();
1281: Point p = e.getPoint();
1282: if (p.x >= 0 && p.x < menuItem.getWidth() && p.y >= 0
1283: && p.y < menuItem.getHeight()) {
1284: doClick(manager);
1285: } else {
1286: manager.clearSelectedPath();
1287: }
1288: }
1289: }
1290:
1291: private class MenuKeyHandler implements MenuKeyListener {
1292:
1293: /**
1294: * Handles the mnemonic key typed in the MenuItem if this menuItem is in
1295: * a standalone popup menu. This invocation normally
1296: * handled in BasicMenuUI.MenuKeyHandler.menuKeyPressed. Ideally, the
1297: * MenuKeyHandlers for both BasicMenuItemUI and BasicMenuUI can be consolidated
1298: * into BasicPopupMenuUI but that would require an semantic change. This
1299: * would result in a performance win since we can shortcut a lot of the needless
1300: * processing from MenuSelectionManager.processKeyEvent(). See 4670831.
1301: */
1302: public void menuKeyTyped(MenuKeyEvent e) {
1303: if (DEBUG) {
1304: System.out
1305: .println("in VsnetMenuItemUI.menuKeyTyped for "
1306: + menuItem.getText());
1307: }
1308: int key = menuItem.getMnemonic();
1309: if (key == 0 || e.getPath().length != 2) // Hack! Only proceed if in a JPopupMenu
1310: return;
1311: if (lower((char) key) == lower(e.getKeyChar())) {
1312: MenuSelectionManager manager = e
1313: .getMenuSelectionManager();
1314: doClick(manager);
1315: e.consume();
1316: }
1317: }
1318:
1319: public void menuKeyPressed(MenuKeyEvent e) {
1320: if (DEBUG) {
1321: System.out
1322: .println("in VsnetMenuItemUI.menuKeyPressed for "
1323: + menuItem.getText());
1324: }
1325: }
1326:
1327: public void menuKeyReleased(MenuKeyEvent e) {
1328: }
1329:
1330: private char lower(char keyChar) {
1331: return Character.toLowerCase(keyChar);
1332: }
1333: }
1334:
1335: private class PropertyChangeHandler implements
1336: PropertyChangeListener {
1337: public void propertyChange(PropertyChangeEvent e) {
1338: String name = e.getPropertyName();
1339:
1340: if (name.equals("labelFor")
1341: || name.equals("displayedMnemonic")
1342: || name.equals("accelerator")) {
1343: updateAcceleratorBinding();
1344: } else if (ButtonStyle.BUTTON_STYLE_PROPERTY.equals(name)
1345: || "opaque".equals(name)
1346: || AbstractButton.CONTENT_AREA_FILLED_CHANGED_PROPERTY
1347: .equals(name)) {
1348: JMenuItem lbl = ((JMenuItem) e.getSource());
1349: lbl.repaint();
1350: } else if (name.equals("orientation")) {
1351: JMenuItem lbl = ((JMenuItem) e.getSource());
1352: lbl.invalidate();
1353: lbl.repaint();
1354: } else if (name.equals("text") || "font".equals(name)
1355: || "foreground".equals(name)) {
1356: // remove the old html view client property if one
1357: // existed, and install a new one if the text installed
1358: // into the JLabel is html source.
1359: JMenuItem lbl = ((JMenuItem) e.getSource());
1360: String text = lbl.getText();
1361: BasicHTML.updateRenderer(lbl, text);
1362: }
1363: }
1364: }
1365:
1366: private static class ClickAction extends AbstractAction {
1367: public void actionPerformed(ActionEvent e) {
1368: JMenuItem mi = (JMenuItem) e.getSource();
1369: MenuSelectionManager.defaultManager().clearSelectedPath();
1370: mi.doClick();
1371: }
1372: }
1373:
1374: /**
1375: * Call this method when a menu item is to be activated.
1376: * This method handles some of the details of menu item activation
1377: * such as clearing the selected path and messaging the
1378: * JMenuItem's doClick() method.
1379: *
1380: * @param msm A MenuSelectionManager. The visual feedback and
1381: * internal bookkeeping tasks are delegated to
1382: * this MenuSelectionManager. If <code>null</code> is
1383: * passed as this argument, the
1384: * <code>MenuSelectionManager.defaultManager</code> is
1385: * used.
1386: * @see MenuSelectionManager
1387: * @see JMenuItem#doClick(int)
1388: * @since 1.4
1389: */
1390: protected void doClick(MenuSelectionManager msm) {
1391: // Auditory cue
1392: // if (!isInternalFrameSystemMenu()) {
1393: // ActionMap map = menuItem.getActionMap();
1394: // if (map != null) {
1395: // Action audioAction = map.get(getPropertyPrefix() +
1396: // ".commandSound");
1397: // if (audioAction != null) {
1398: // pass off firing the Action to a utility method
1399: // BasicLookAndFeel lf = (BasicLookAndFeel)
1400: // UIManager.getLookAndFeel();
1401: // lf.playSound(audioAction);
1402: // }
1403: // }
1404: // }
1405: // // Visual feedback
1406: if (msm == null) {
1407: msm = MenuSelectionManager.defaultManager();
1408: }
1409: msm.clearSelectedPath();
1410: menuItem.doClick(0);
1411: }
1412:
1413: protected ThemePainter getPainter() {
1414: return _painter;
1415: }
1416:
1417: protected boolean isDownArrowVisible(Container c) {
1418: if (c instanceof TopLevelMenuContainer
1419: && ((TopLevelMenuContainer) c).isMenuBar()) {
1420: return false;
1421: } else if (c instanceof TopLevelMenuContainer
1422: && !((TopLevelMenuContainer) c).isMenuBar()) {
1423: return true;
1424: } else if (c instanceof JMenuBar) {
1425: return false;
1426: } else {
1427: return true;
1428: }
1429: }
1430:
1431: protected boolean isFloatingIcon() {
1432: return _isFloatingIcon;
1433: }
1434:
1435: protected Icon getIcon(AbstractButton b) {
1436: ButtonModel model = b.getModel();
1437: Icon icon = b.getIcon();
1438: Icon tmpIcon = null;
1439: if (!model.isEnabled()) {
1440: if (model.isSelected()) {
1441: tmpIcon = (Icon) b.getDisabledSelectedIcon();
1442: } else {
1443: tmpIcon = (Icon) b.getDisabledIcon();
1444: }
1445:
1446: // create default diabled icon
1447: if (tmpIcon == null) {
1448: if (icon instanceof ImageIcon) {
1449: icon = IconsFactory
1450: .createGrayImage(((ImageIcon) icon)
1451: .getImage());
1452: } else {
1453: icon = IconsFactory.createGrayImage(b, icon);
1454: }
1455: }
1456: } else if (model.isPressed() && model.isArmed()) {
1457: tmpIcon = (Icon) b.getPressedIcon();
1458: if (tmpIcon != null) {
1459: }
1460: } else if (b.isRolloverEnabled() && model.isRollover()) {
1461: if (model.isSelected()) {
1462: tmpIcon = (Icon) b.getRolloverSelectedIcon();
1463: } else {
1464: tmpIcon = (Icon) b.getRolloverIcon();
1465: }
1466: } else if (model.isSelected()) {
1467: tmpIcon = (Icon) b.getSelectedIcon();
1468: }
1469:
1470: if (tmpIcon != null) {
1471: icon = tmpIcon;
1472: }
1473: return icon;
1474: }
1475:
1476: protected int getRightMargin() {
1477: return 0;
1478: }
1479: }
|