- /*
- * @(#)SynthMenuItemUI.java 1.18 03/04/10
- *
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
- * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
- */
- package com.sun.java.swing.plaf.gtk;
-
- import javax.swing.plaf.basic.BasicHTML;
- import java.awt.*;
- import java.awt.event.*;
- import java.beans.PropertyChangeEvent;
- import java.beans.PropertyChangeListener;
-
- import javax.swing.*;
- import javax.swing.event.*;
- import javax.swing.border.*;
- import javax.swing.plaf.*;
- import javax.swing.text.View;
-
-
- /**
- * BasicMenuItem implementation
- *
- * @version 1.18, 04/10/03 (based on BasicMenuItemUI v 1.116)
- * @author Georges Saab
- * @author David Karlton
- * @author Arnaud Weber
- * @author Fredrik Lagerblad
- */
- class SynthMenuItemUI extends MenuItemUI implements SynthUI {
- static final String MAX_TEXT_WIDTH = "maxTextWidth";
- static final String MAX_ACC_WIDTH = "maxAccWidth";
-
- private SynthStyle style;
- private SynthStyle accStyle;
- protected JMenuItem menuItem = null;
- private String acceleratorDelimiter;
-
- protected int defaultTextIconGap;
-
- protected MouseInputListener mouseInputListener;
- protected MenuDragMouseListener menuDragMouseListener;
- protected MenuKeyListener menuKeyListener;
- private PropertyChangeListener propertyChangeListener;
-
- protected Icon arrowIcon = null;
- protected Icon checkIcon = null;
-
- /** Used for accelerator binding, lazily created. */
- InputMap windowInputMap;
-
- /* diagnostic aids -- should be false for production builds. */
- private static final boolean TRACE = false; // trace creates and disposes
-
- private static final boolean VERBOSE = false; // show reuse hits/misses
- private static final boolean DEBUG = false; // show bad params, misc.
-
- public static ComponentUI createUI(JComponent c) {
- return new SynthMenuItemUI();
- }
-
- public static void loadActionMap(ActionMap map) {
- // NOTE: this needs to remain static. If you have a need to
- // have Actions that reference the UI in the ActionMap,
- // then you'll also need to change the registeration of the
- // ActionMap.
- map.put("doClick", new ClickAction());
- }
-
- public void installUI(JComponent c) {
- menuItem = (JMenuItem) c;
-
- installDefaults();
- installComponents(menuItem);
- installListeners();
- installKeyboardActions();
- }
-
-
- protected void installDefaults() {
- fetchStyle(menuItem);
- }
-
- private void fetchStyle(JMenuItem mi) {
- SynthContext context = getContext(mi, ENABLED);
- SynthStyle oldStyle = style;
-
- style = SynthLookAndFeel.updateStyle(context, this);
- if (oldStyle != style) {
- String prefix = getPropertyPrefix();
- defaultTextIconGap = style.getInt(
- context, prefix + ".textIconGap", 4);
- if (menuItem.getMargin() == null ||
- (menuItem.getMargin() instanceof UIResource)) {
- Insets insets = (Insets)style.get(context, prefix + ".margin");
-
- if (insets == null) {
- // Some places assume margins are non-null.
- insets = SynthLookAndFeel.EMPTY_UIRESOURCE_INSETS;
- }
- menuItem.setMargin(insets);
- }
- acceleratorDelimiter = style.getString(context, prefix +
- ".acceleratorDelimiter", "+");
-
- arrowIcon = style.getIcon(context, prefix + ".arrowIcon");
-
- checkIcon = style.getIcon(context, prefix + ".checkIcon");
- }
- context.dispose();
-
- SynthContext accContext = getContext(mi, Region.MENU_ITEM_ACCELERATOR,
- ENABLED);
-
- accStyle = SynthLookAndFeel.updateStyle(accContext, this);
- accContext.dispose();
- }
-
- /**
- * @since 1.3
- */
- protected void installComponents(JMenuItem menuItem){
- BasicHTML.updateRenderer(menuItem, menuItem.getText());
- }
-
- protected String getPropertyPrefix() {
- return "MenuItem";
- }
-
- protected void installListeners() {
- if ((mouseInputListener = createMouseInputListener(menuItem)) != null) {
- menuItem.addMouseListener(mouseInputListener);
- menuItem.addMouseMotionListener(mouseInputListener);
- }
- if ((menuDragMouseListener = createMenuDragMouseListener(menuItem)) != null) {
- menuItem.addMenuDragMouseListener(menuDragMouseListener);
- }
- if ((menuKeyListener = createMenuKeyListener(menuItem)) != null) {
- menuItem.addMenuKeyListener(menuKeyListener);
- }
- if ((propertyChangeListener = createPropertyChangeListener(menuItem)) != null) {
- menuItem.addPropertyChangeListener(propertyChangeListener);
- }
- }
-
- protected void installKeyboardActions() {
- registerActionMap();
- updateAcceleratorBinding();
- }
-
- public void uninstallUI(JComponent c) {
- menuItem = (JMenuItem)c;
- uninstallDefaults();
- uninstallComponents(menuItem);
- uninstallListeners();
- uninstallKeyboardActions();
-
- menuItem = null;
- }
-
-
- protected void uninstallDefaults() {
- if (menuItem.getMargin() instanceof UIResource)
- menuItem.setMargin(null);
- if (arrowIcon instanceof UIResource)
- arrowIcon = null;
- if (checkIcon instanceof UIResource)
- checkIcon = null;
-
- SynthContext context = getContext(menuItem, ENABLED);
- style.uninstallDefaults(context);
- context.dispose();
- style = null;
-
- SynthContext accContext = getContext(menuItem,
- Region.MENU_ITEM_ACCELERATOR, ENABLED);
- accStyle.uninstallDefaults(accContext);
- accContext.dispose();
- accStyle = null;
- }
-
- /**
- * @since 1.3
- */
- protected void uninstallComponents(JMenuItem menuItem){
- BasicHTML.updateRenderer(menuItem, "");
- }
-
- protected void uninstallListeners() {
- if (mouseInputListener != null) {
- menuItem.removeMouseListener(mouseInputListener);
- menuItem.removeMouseMotionListener(mouseInputListener);
- }
- if (menuDragMouseListener != null) {
- menuItem.removeMenuDragMouseListener(menuDragMouseListener);
- }
- if (menuKeyListener != null) {
- menuItem.removeMenuKeyListener(menuKeyListener);
- }
- if (propertyChangeListener != null) {
- menuItem.removePropertyChangeListener(propertyChangeListener);
- }
-
- mouseInputListener = null;
- menuDragMouseListener = null;
- menuKeyListener = null;
- propertyChangeListener = null;
- }
-
- protected void uninstallKeyboardActions() {
- SwingUtilities.replaceUIActionMap(menuItem, null);
- if (windowInputMap != null) {
- SwingUtilities.replaceUIInputMap(menuItem, JComponent.
- WHEN_IN_FOCUSED_WINDOW, null);
- windowInputMap = null;
- }
- }
-
- protected MouseInputListener createMouseInputListener(JComponent c) {
- return new MouseInputHandler();
- }
-
- protected MenuDragMouseListener createMenuDragMouseListener(JComponent c) {
- return new MenuDragMouseHandler();
- }
-
- protected MenuKeyListener createMenuKeyListener(JComponent c) {
- return new MenuKeyHandler();
- }
-
- private PropertyChangeListener createPropertyChangeListener(JComponent c) {
- return new PropertyChangeHandler();
- }
-
- public SynthContext getContext(JComponent c) {
- return getContext(c, getComponentState(c));
- }
-
- SynthContext getContext(JComponent c, int state) {
- return SynthContext.getContext(SynthContext.class, c,
- SynthLookAndFeel.getRegion(c), style, state);
- }
-
- public SynthContext getContext(JComponent c, Region region) {
- return getContext(c, region, getComponentState(c, region));
- }
-
- private SynthContext getContext(JComponent c, Region region, int state) {
- return SynthContext.getContext(SynthContext.class, c,
- region, accStyle, state);
- }
-
- private Region getRegion(JComponent c) {
- return SynthLookAndFeel.getRegion(c);
- }
-
- private int getComponentState(JComponent c) {
- int state;
-
- if (!c.isEnabled()) {
- return DISABLED;
- }
- if (menuItem.isArmed()) {
- state = MOUSE_OVER;
- }
- else {
- state = SynthLookAndFeel.getComponentState(c);
- }
- if (menuItem.isSelected()) {
- state |= SELECTED;
- }
- return state;
- }
-
- private int getComponentState(JComponent c, Region region) {
- return getComponentState(c);
- }
-
- void registerActionMap() {
- LazyActionMap.installLazyActionMap(menuItem, SynthMenuItemUI.class,
- "MenuItem.actionMap");
- }
-
- InputMap createInputMap(int condition) {
- if (condition == JComponent.WHEN_IN_FOCUSED_WINDOW) {
- return new ComponentInputMapUIResource(menuItem);
- }
- return null;
- }
-
- void updateAcceleratorBinding() {
- KeyStroke accelerator = menuItem.getAccelerator();
-
- if (windowInputMap != null) {
- windowInputMap.clear();
- }
- if (accelerator != null) {
- if (windowInputMap == null) {
- windowInputMap = createInputMap(JComponent.
- WHEN_IN_FOCUSED_WINDOW);
- SwingUtilities.replaceUIInputMap(menuItem,
- JComponent.WHEN_IN_FOCUSED_WINDOW, windowInputMap);
- }
- windowInputMap.put(accelerator, "doClick");
- }
- }
-
- public Dimension getMinimumSize(JComponent c) {
- Dimension d = null;
- View v = (View) c.getClientProperty(BasicHTML.propertyKey);
- if (v != null) {
- d = getPreferredSize(c);
- d.width -= v.getPreferredSpan(View.X_AXIS) - v.getMinimumSpan(View.X_AXIS);
- }
- return d;
- }
-
- public Dimension getPreferredSize(JComponent c) {
- return getPreferredMenuItemSize(c,
- checkIcon,
- arrowIcon,
- defaultTextIconGap);
- }
-
- public Dimension getMaximumSize(JComponent c) {
- Dimension d = null;
- View v = (View) c.getClientProperty(BasicHTML.propertyKey);
- if (v != null) {
- d = getPreferredSize(c);
- d.width += v.getMaximumSpan(View.X_AXIS) - v.getPreferredSpan(View.X_AXIS);
- }
- return d;
- }
-
- // these rects are used for painting and preferredsize calculations.
- // they used to be regenerated constantly. Now they are reused.
- static Rectangle iconRect = new Rectangle();
- static Rectangle textRect = new Rectangle();
- static Rectangle acceleratorRect = new Rectangle();
- static Rectangle checkIconRect = new Rectangle();
- static Rectangle arrowIconRect = new Rectangle();
- static Rectangle viewRect = new Rectangle(Short.MAX_VALUE, Short.MAX_VALUE);
- static Rectangle r = new Rectangle();
-
- private void resetRects() {
- iconRect.setBounds(0, 0, 0, 0);
- textRect.setBounds(0, 0, 0, 0);
- acceleratorRect.setBounds(0, 0, 0, 0);
- checkIconRect.setBounds(0, 0, 0, 0);
- arrowIconRect.setBounds(0, 0, 0, 0);
- viewRect.setBounds(0,0,Short.MAX_VALUE, Short.MAX_VALUE);
- r.setBounds(0, 0, 0, 0);
- }
-
- protected Dimension getPreferredMenuItemSize(JComponent c,
- Icon checkIcon,
- Icon arrowIcon,
- int defaultTextIconGap) {
- JMenuItem b = (JMenuItem) c;
- Icon icon = (Icon) b.getIcon();
- String text = b.getText();
- KeyStroke accelerator = b.getAccelerator();
- String acceleratorText = "";
-
- if (accelerator != null) {
- int modifiers = accelerator.getModifiers();
- if (modifiers > 0) {
- acceleratorText = KeyEvent.getKeyModifiersText(modifiers);
- //acceleratorText += "-";
- acceleratorText += acceleratorDelimiter;
- }
- int keyCode = accelerator.getKeyCode();
- if (keyCode != 0) {
- acceleratorText += KeyEvent.getKeyText(keyCode);
- } else {
- acceleratorText += accelerator.getKeyChar();
- }
- }
-
- SynthContext context = getContext(c);
- SynthContext accContext = getContext(c, Region.MENU_ITEM_ACCELERATOR);
- Font font = context.getStyle().getFont(context);
- FontMetrics fm = b.getToolkit().getFontMetrics(font);
- FontMetrics fmAccel = b.getToolkit().getFontMetrics(
- accContext.getStyle().getFont(accContext));
-
- resetRects();
-
- layoutMenuItem(
- context, fm, accContext, text, fmAccel, acceleratorText,
- icon, checkIcon, arrowIcon, b.getVerticalAlignment(),
- b.getHorizontalAlignment(), b.getVerticalTextPosition(),
- b.getHorizontalTextPosition(), viewRect, iconRect, textRect,
- acceleratorRect, checkIconRect, arrowIconRect,
- text == null ? 0 : defaultTextIconGap, defaultTextIconGap
- );
- // find the union of the icon and text rects
- r.setBounds(textRect);
- r = SwingUtilities.computeUnion(iconRect.x,
- iconRect.y,
- iconRect.width,
- iconRect.height,
- r);
-
- // To make the accelerator texts appear in a column,
- // find the widest MenuItem text and the widest accelerator text.
-
- // Get the parent, which stores the information.
- Container parent = menuItem.getParent();
-
- if (parent instanceof JPopupMenu) {
- JPopupMenu popup = (JPopupMenu)parent;
- ComponentUI ui = popup.getUI();
- if (ui instanceof SynthPopupMenuUI) {
- SynthPopupMenuUI popupUI = (SynthPopupMenuUI)ui;
-
- r.width = popupUI.adjustTextWidth(r.width);
-
- popupUI.adjustAcceleratorWidth(acceleratorRect.width);
-
- r.width += popupUI.getMaxAcceleratorWidth();
- }
- else {
- // We don't have a SynthPopupMenuUI, fallback to storing the
- // values in the client properties of the JPopupMenu.
- //Get widest text so far from parent, if no one exists null is returned.
- Integer maxTextWidth = (Integer)popup.getClientProperty(
- MAX_TEXT_WIDTH);
- Integer maxAccWidth = (Integer)popup.
- getClientProperty(MAX_ACC_WIDTH);
- int maxTextValue = maxTextWidth!=null ?
- maxTextWidth.intValue() : 0;
- int maxAccValue = maxAccWidth!=null ?
- maxAccWidth.intValue() : 0;
-
- // Compare the text widths, and adjust the r.width to the
- // widest.
- if (r.width < maxTextValue) {
- r.width = maxTextValue;
- } else {
- popup.putClientProperty(MAX_TEXT_WIDTH,
- new Integer(r.width));
- }
-
- // Compare the accelarator widths.
- if (acceleratorRect.width > maxAccValue) {
- maxAccValue = acceleratorRect.width;
- popup.putClientProperty(MAX_ACC_WIDTH, new Integer(
- acceleratorRect.width));
- }
-
- //Add on the widest accelerator
- r.width += maxAccValue;
- }
- }
-
- if( useCheckAndArrow() ) {
- // Add in the checkIcon
- r.width += checkIconRect.width;
- r.width += defaultTextIconGap;
-
- // Add in the arrowIcon
- r.width += defaultTextIconGap;
- r.width += arrowIconRect.width;
- }
-
- r.width += 2*defaultTextIconGap;
-
- Insets insets = b.getInsets();
- if(insets != null) {
- r.width += insets.left + insets.right;
- r.height += insets.top + insets.bottom;
- }
-
- // if the width is even, bump it up one. This is critical
- // for the focus dash line to draw properly
- if(r.width%2 == 0) {
- r.width++;
- }
-
- // if the height is even, bump it up one. This is critical
- // for the text to center properly
- if(r.height%2 == 0) {
- r.height++;
- }
- /*
- if(!(b instanceof JMenu && ((JMenu) b).isTopLevelMenu()) ) {
-
- // Container parent = menuItem.getParent();
- JComponent p = (JComponent) parent;
-
- System.out.println("MaxText: "+p.getClientProperty(BasicMenuItemUI.MAX_TEXT_WIDTH));
- System.out.println("MaxACC"+p.getClientProperty(BasicMenuItemUI.MAX_ACC_WIDTH));
-
- System.out.println("returning pref.width: " + r.width);
- System.out.println("Current getSize: " + b.getSize() + "\n");
- }*/
- context.dispose();
- accContext.dispose();
- return r.getSize();
- }
-
- public void update(Graphics g, JComponent c) {
- SynthContext context = getContext(c);
-
- SynthLookAndFeel.update(context, g);
- paint(context, g);
- context.dispose();
- }
-
- public void paint(Graphics g, JComponent c) {
- SynthContext context = getContext(c);
-
- paint(context, g);
- context.dispose();
- }
-
- protected void paint(SynthContext context, Graphics g) {
- JComponent c = context.getComponent();
- JMenuItem b = (JMenuItem)c;
- ButtonModel model = b.getModel();
- Insets i = b.getInsets();
-
- resetRects();
-
- viewRect.setBounds(0, 0, b.getWidth(), b.getHeight());
-
- viewRect.x += i.left;
- viewRect.y += i.top;
- viewRect.width -= (i.right + viewRect.x);
- viewRect.height -= (i.bottom + viewRect.y);
-
- SynthContext accContext = getContext(menuItem,
- Region.MENU_ITEM_ACCELERATOR);
- SynthStyle style = context.getStyle();
- Font f = style.getFont(context);
- g.setFont(f);
- FontMetrics fm = g.getFontMetrics(f);
- FontMetrics accFM = g.getFontMetrics(accContext.getStyle().
- getFont(accContext));
-
- // get Accelerator text
- KeyStroke accelerator = b.getAccelerator();
- String acceleratorText = "";
- if (accelerator != null) {
- int modifiers = accelerator.getModifiers();
- if (modifiers > 0) {
- acceleratorText = KeyEvent.getKeyModifiersText(modifiers);
- //acceleratorText += "-";
- acceleratorText += acceleratorDelimiter;
- }
-
- int keyCode = accelerator.getKeyCode();
- if (keyCode != 0) {
- acceleratorText += KeyEvent.getKeyText(keyCode);
- } else {
- acceleratorText += accelerator.getKeyChar();
- }
- }
-
- // layout the text and icon
- String text = layoutMenuItem(context, fm, accContext,
- b.getText(), accFM, acceleratorText, b.getIcon(),
- checkIcon, arrowIcon,
- b.getVerticalAlignment(), b.getHorizontalAlignment(),
- b.getVerticalTextPosition(), b.getHorizontalTextPosition(),
- viewRect, iconRect, textRect, acceleratorRect,
- checkIconRect, arrowIconRect,
- b.getText() == null ? 0 : defaultTextIconGap,
- defaultTextIconGap
- );
-
- // Paint the Check
- if (checkIcon != null && useCheckAndArrow() ) {
- SynthIcon.paintIcon(checkIcon, context, g, checkIconRect.x,
- checkIconRect.y, checkIconRect.width, checkIconRect.height);
- }
-
- // Paint the Icon
- if(b.getIcon() != null) {
- Icon icon;
- if(!model.isEnabled()) {
- icon = (Icon) b.getDisabledIcon();
- } else if(model.isPressed() && model.isArmed()) {
- icon = (Icon) b.getPressedIcon();
- if(icon == null) {
- // Use default icon
- icon = (Icon) b.getIcon();
- }
- } else {
- icon = (Icon) b.getIcon();
- }
-
- if (icon!=null) {
- SynthIcon.paintIcon(icon, context, g, iconRect.x,
- iconRect.y, iconRect.width, iconRect.height);
- }
- }
-
- // Draw the Text
- if(text != null) {
- View v = (View) c.getClientProperty(BasicHTML.propertyKey);
- if (v != null) {
- v.paint(g, textRect);
- } else {
- g.setColor(style.getColor(context, ColorType.TEXT_FOREGROUND));
- g.setFont(style.getFont(context));
- style.getSynthGraphics(context).paintText(context, g, text,
- textRect.x, textRect.y, menuItem.
- getDisplayedMnemonicIndex());
- }
- }
-
- // Draw the Accelerator Text
- if(acceleratorText != null && !acceleratorText.equals("")) {
- // Get the maxAccWidth from the parent to calculate the offset.
- int accOffset = 0;
- Container parent = menuItem.getParent();
- if (parent != null && parent instanceof JPopupMenu) {
- ComponentUI ui = ((JPopupMenu)parent).getUI();
- if (ui instanceof SynthPopupMenuUI) {
- SynthPopupMenuUI popupUI = (SynthPopupMenuUI)ui;
- // Calculate the offset, with which the accelerator texts
- // will be drawn with.
- int max = popupUI.getMaxAcceleratorWidth();
- if (max > 0) {
- accOffset = max - acceleratorRect.width;
- }
- }
- else {
- // We don't have a SynthPopupMenuUI, fallback to using the
- // values in the client properties of the JPopupMenu.
- Integer maxValueInt = (Integer)((JComponent)parent).
- getClientProperty(MAX_ACC_WIDTH);
- int maxValue = maxValueInt != null ?
- maxValueInt.intValue() : acceleratorRect.width;
-
- // Calculate the offset, with which the accelerator texts
- // will be drawn with.
- accOffset = maxValue - acceleratorRect.width;
- }
- }
-
- SynthStyle accStyle = accContext.getStyle();
-
- g.setColor(accStyle.getColor(accContext,
- ColorType.TEXT_FOREGROUND));
- g.setFont(accStyle.getFont(accContext));
- accStyle.getSynthGraphics(accContext).paintText(
- accContext, g, acceleratorText, acceleratorRect.x -
- accOffset, acceleratorRect.y, -1);
- }
-
- // Paint the Arrow
- if (arrowIcon != null && useCheckAndArrow()) {
- SynthIcon.paintIcon(arrowIcon, context, g, arrowIconRect.x,
- arrowIconRect.y, arrowIconRect.width, arrowIconRect.height);
- }
- accContext.dispose();
- }
-
- /**
- * Compute and return the location of the icons origin, the
- * location of origin of the text baseline, and a possibly clipped
- * version of the compound labels string. Locations are computed
- * relative to the viewRect rectangle.
- */
-
- private String layoutMenuItem(
- SynthContext context,
- FontMetrics fm,
- SynthContext accContext,
- String text,
- FontMetrics fmAccel,
- String acceleratorText,
- Icon icon,
- Icon checkIcon,
- Icon arrowIcon,
- int verticalAlignment,
- int horizontalAlignment,
- int verticalTextPosition,
- int horizontalTextPosition,
- Rectangle viewRect,
- Rectangle iconRect,
- Rectangle textRect,
- Rectangle acceleratorRect,
- Rectangle checkIconRect,
- Rectangle arrowIconRect,
- int textIconGap,
- int menuItemGap
- )
- {
-
- context.getStyle().getSynthGraphics(context).layoutText(
- context, fm, text, icon,horizontalAlignment, verticalAlignment,
- horizontalTextPosition, verticalTextPosition, viewRect,
- iconRect, textRect, textIconGap);
-
- /* Initialize the acceelratorText bounds rectangle textRect. If a null
- * or and empty String was specified we substitute "" here
- * and use 0,0,0,0 for acceleratorTextRect.
- */
- if( (acceleratorText == null) || acceleratorText.equals("") ) {
- acceleratorRect.width = acceleratorRect.height = 0;
- acceleratorText = "";
- }
- else {
- SynthStyle style = accContext.getStyle();
- acceleratorRect.width = style.getSynthGraphics(accContext).
- computeStringWidth(accContext, fmAccel.getFont(), fmAccel,
- acceleratorText);
- acceleratorRect.height = fmAccel.getHeight();
- }
-
- /* Initialize the checkIcon bounds rectangle's width & height.
- */
-
- if( useCheckAndArrow()) {
- if (checkIcon != null) {
- checkIconRect.width = SynthIcon.getIconWidth(checkIcon,
- context);
- checkIconRect.height = SynthIcon.getIconHeight(checkIcon,
- context);
- }
- else {
- checkIconRect.width = checkIconRect.height = 0;
- }
-
- /* Initialize the arrowIcon bounds rectangle width & height.
- */
-
- if (arrowIcon != null) {
- arrowIconRect.width = SynthIcon.getIconWidth(arrowIcon,
- context);
- arrowIconRect.height = SynthIcon.getIconHeight(arrowIcon,
- context);
- } else {
- arrowIconRect.width = arrowIconRect.height = 0;
- }
- }
-
- Rectangle labelRect = iconRect.union(textRect);
- if( SynthLookAndFeel.isLeftToRight(menuItem) ) {
- textRect.x += menuItemGap;
- iconRect.x += menuItemGap;
-
- // Position the Accelerator text rect
- acceleratorRect.x = viewRect.x + viewRect.width -
- arrowIconRect.width - menuItemGap - acceleratorRect.width;
-
- // Position the Check and Arrow Icons
- if (useCheckAndArrow()) {
- checkIconRect.x = viewRect.x + menuItemGap;
- textRect.x += menuItemGap + checkIconRect.width;
- iconRect.x += menuItemGap + checkIconRect.width;
- arrowIconRect.x = viewRect.x + viewRect.width - menuItemGap
- - arrowIconRect.width;
- }
- } else {
- textRect.x -= menuItemGap;
- iconRect.x -= menuItemGap;
-
- // Position the Accelerator text rect
- acceleratorRect.x = viewRect.x + arrowIconRect.width + menuItemGap;
-
- // Position the Check and Arrow Icons
- if (useCheckAndArrow()) {
- checkIconRect.x = viewRect.x + viewRect.width - menuItemGap
- - checkIconRect.width;
- textRect.x -= menuItemGap + checkIconRect.width;
- iconRect.x -= menuItemGap + checkIconRect.width;
- arrowIconRect.x = viewRect.x + menuItemGap;
- }
- }
-
- // Align the accelertor text and the check and arrow icons vertically
- // with the center of the label rect.
- acceleratorRect.y = labelRect.y + (labelRect.height2) - (acceleratorRect.height2);
- if( useCheckAndArrow() ) {
- arrowIconRect.y = labelRect.y + (labelRect.height2) - (arrowIconRect.height2);
- checkIconRect.y = labelRect.y + (labelRect.height2) - (checkIconRect.height2);
- }
-
- /*
- System.out.println("Layout: text="+menuItem.getText()+"\n\tv="
- +viewRect+"\n\tc="+checkIconRect+"\n\ti="
- +iconRect+"\n\tt="+textRect+"\n\tacc="
- +acceleratorRect+"\n\ta="+arrowIconRect+"\n");
- */
-
- return text;
- }
-
- /*
- * Returns false if the component is a JMenu and it is a top
- * level menu (on the menubar).
- */
- private boolean useCheckAndArrow(){
- boolean b = true;
- if((menuItem instanceof JMenu) &&
- (((JMenu)menuItem).isTopLevelMenu())) {
- b = false;
- }
- return b;
- }
-
- public MenuElement[] getPath() {
- MenuSelectionManager m = MenuSelectionManager.defaultManager();
- MenuElement oldPath[] = m.getSelectedPath();
- MenuElement newPath[];
- int i = oldPath.length;
- if (i == 0)
- return new MenuElement[0];
- Component parent = menuItem.getParent();
- if (oldPath[i-1].getComponent() == parent) {
- // The parent popup menu is the last so far
- newPath = new MenuElement[i+1];
- System.arraycopy(oldPath, 0, newPath, 0, i);
- newPath[i] = menuItem;
- } else {
- // A sibling menuitem is the current selection
- //
- // This probably needs to handle 'exit submenu into
- // a menu item. Search backwards along the current
- // selection until you find the parent popup menu,
- // then copy up to that and add yourself...
- int j;
- for (j = oldPath.length-1; j >= 0; j--) {
- if (oldPath[j].getComponent() == parent)
- break;
- }
- newPath = new MenuElement[j+2];
- System.arraycopy(oldPath, 0, newPath, 0, j+1);
- newPath[j+1] = menuItem;
- /*
- System.out.println("Sibling condition -- ");
- System.out.println("Old array : ");
- printMenuElementArray(oldPath, false);
- System.out.println("New array : ");
- printMenuElementArray(newPath, false);
- */
- }
- return newPath;
- }
-
- void printMenuElementArray(MenuElement path[], boolean dumpStack) {
- System.out.println("Path is(");
- int i, j;
- for(i=0,j=path.length; i<j ;i++){
- for (int k=0; k<=i; k++)
- System.out.print(" ");
- MenuElement me = (MenuElement) path[i];
- if(me instanceof JMenuItem)
- System.out.println(((JMenuItem)me).getText() + ", ");
- else if (me == null)
- System.out.println("NULL , ");
- else
- System.out.println("" + me + ", ");
- }
- System.out.println(")");
-
- if (dumpStack == true)
- Thread.dumpStack();
- }
- protected class MouseInputHandler implements MouseInputListener {
- public void mouseClicked(MouseEvent e) {}
- public void mousePressed(MouseEvent e) {
- }
- public void mouseReleased(MouseEvent e) {
- MenuSelectionManager manager =
- MenuSelectionManager.defaultManager();
- Point p = e.getPoint();
- if(p.x >= 0 && p.x < menuItem.getWidth() &&
- p.y >= 0 && p.y < menuItem.getHeight()) {
- doClick(manager);
- } else {
- manager.processMouseEvent(e);
- }
- }
- public void mouseEntered(MouseEvent e) {
- MenuSelectionManager manager = MenuSelectionManager.defaultManager();
- int modifiers = e.getModifiers();
- // 4188027: drag enter/exit added in JDK 1.1.7A, JDK1.2
- if ((modifiers & (InputEvent.BUTTON1_MASK |
- InputEvent.BUTTON2_MASK | InputEvent.BUTTON3_MASK)) !=0 ) {
- MenuSelectionManager.defaultManager().processMouseEvent(e);
- } else {
- manager.setSelectedPath(getPath());
- }
- }
- public void mouseExited(MouseEvent e) {
- MenuSelectionManager manager = MenuSelectionManager.defaultManager();
-
- int modifiers = e.getModifiers();
- // 4188027: drag enter/exit added in JDK 1.1.7A, JDK1.2
- if ((modifiers & (InputEvent.BUTTON1_MASK |
- InputEvent.BUTTON2_MASK | InputEvent.BUTTON3_MASK)) !=0 ) {
- MenuSelectionManager.defaultManager().processMouseEvent(e);
- } else {
-
- MenuElement path[] = manager.getSelectedPath();
- if (path.length > 1) {
- MenuElement newPath[] = new MenuElement[path.length-1];
- int i,c;
- for(i=0,c=path.length-1;i<c;i++)
- newPath[i] = path[i];
- manager.setSelectedPath(newPath);
- }
- }
- }
-
- public void mouseDragged(MouseEvent e) {
- MenuSelectionManager.defaultManager().processMouseEvent(e);
- }
- public void mouseMoved(MouseEvent e) {
- }
- }
-
-
- private class MenuDragMouseHandler implements MenuDragMouseListener {
- public void menuDragMouseEntered(MenuDragMouseEvent e) {
- MenuSelectionManager manager = e.getMenuSelectionManager();
- MenuElement path[] = e.getPath();
- manager.setSelectedPath(path);
- }
- public void menuDragMouseDragged(MenuDragMouseEvent e) {
- MenuSelectionManager manager = e.getMenuSelectionManager();
- MenuElement path[] = e.getPath();
- manager.setSelectedPath(path);
- }
- public void menuDragMouseExited(MenuDragMouseEvent e) {}
- public void menuDragMouseReleased(MenuDragMouseEvent e) {
- MenuSelectionManager manager = e.getMenuSelectionManager();
- MenuElement path[] = e.getPath();
- Point p = e.getPoint();
- if(p.x >= 0 && p.x < menuItem.getWidth() &&
- p.y >= 0 && p.y < menuItem.getHeight()) {
- doClick(manager);
- } else {
- manager.clearSelectedPath();
- }
- }
- }
-
- private class MenuKeyHandler implements MenuKeyListener {
-
- /**
- * Handles the mnemonic key typed in the MenuItem if this menuItem is in
- * a standalone popup menu. This invocation normally
- * handled in BasicMenuUI.MenuKeyHandler.menuKeyPressed. Ideally, the
- * MenuKeyHandlers for both BasicMenuItemUI and BasicMenuUI can be consolidated
- * into BasicPopupMenuUI but that would require an semantic change. This
- * would result in a performance win since we can shortcut a lot of the needless
- * processing from MenuSelectionManager.processKeyEvent(). See 4670831.
- */
- public void menuKeyTyped(MenuKeyEvent e) {
- if (DEBUG) {
- System.out.println("in BasicMenuItemUI.menuKeyTyped for " + menuItem.getText());
- }
- int key = menuItem.getMnemonic();
- if(key == 0 || e.getPath().length != 2) // Hack! Only proceed if in a JPopupMenu
- return;
- if(lower((char)key) == lower(e.getKeyChar())) {
- MenuSelectionManager manager =
- e.getMenuSelectionManager();
- doClick(manager);
- e.consume();
- }
- }
- public void menuKeyPressed(MenuKeyEvent e) {
- if (DEBUG) {
- System.out.println("in BasicMenuItemUI.menuKeyPressed for " + menuItem.getText());
- }
- }
- public void menuKeyReleased(MenuKeyEvent e) {}
-
- private char lower(char keyChar) {
- return Character.toLowerCase(keyChar);
- }
- }
-
- private class PropertyChangeHandler implements PropertyChangeListener {
- public void propertyChange(PropertyChangeEvent e) {
- String name = e.getPropertyName();
-
- if (SynthLookAndFeel.shouldUpdateStyle(e)) {
- fetchStyle((JMenuItem)e.getSource());
- }
- if (name.equals("labelFor") || name.equals("displayedMnemonic") ||
- name.equals("accelerator")) {
- updateAcceleratorBinding();
- } else if (name.equals("text") || "font".equals(name) ||
- "foreground".equals(name)) {
- // remove the old html view client property if one
- // existed, and install a new one if the text installed
- // into the JLabel is html source.
- JMenuItem lbl = ((JMenuItem) e.getSource());
- String text = lbl.getText();
- BasicHTML.updateRenderer(lbl, text);
- }
- }
- }
-
- private static class ClickAction extends AbstractAction {
- public void actionPerformed(ActionEvent e) {
- JMenuItem mi = (JMenuItem)e.getSource();
- MenuSelectionManager.defaultManager().clearSelectedPath();
- mi.doClick();
- }
- }
-
- /**
- * Call this method when a menu item is to be activated.
- * This method handles some of the details of menu item activation
- * such as clearing the selected path and messaging the
- * JMenuItem's doClick() method.
- *
- * @param msm A MenuSelectionManager. The visual feedback and
- * internal bookkeeping tasks are delegated to
- * this MenuSelectionManager. If <code>null</code> is
- * passed as this argument, the
- * <code>MenuSelectionManager.defaultManager</code> is
- * used.
- * @see MenuSelectionManager
- * @see JMenuItem#doClick(int)
- * @since 1.4
- */
- protected void doClick(MenuSelectionManager msm) {
- // Auditory cue
- if (! isInternalFrameSystemMenu()) {
- SynthLookAndFeel.playSound(menuItem, getPropertyPrefix() +
- ".commandSound");
- }
- // Visual feedback
- if (msm == null) {
- msm = MenuSelectionManager.defaultManager();
- }
- msm.clearSelectedPath();
- menuItem.doClick(0);
- }
-
- /**
- * This is to see if the menu item in question is part of the
- * system menu on an internal frame.
- * The Strings that are being checked can be found in
- * MetalInternalFrameTitlePaneUI.java,
- * WindowsInternalFrameTitlePaneUI.java, and
- * MotifInternalFrameTitlePaneUI.java.
- *
- * @since 1.4
- */
- private boolean isInternalFrameSystemMenu() {
- String actionCommand = menuItem.getActionCommand();
- if ((actionCommand == "Close") ||
- (actionCommand == "Minimize") ||
- (actionCommand == "Restore") ||
- (actionCommand == "Maximize")) {
- return true;
- } else {
- return false;
- }
- }
-
- }