/* * @(#)VsnetMenuUI.java * * Copyright 2002 JIDE Software Inc. All rights reserved. */ package com.jidesoft.plaf.vsnet; import com.jidesoft.plaf.UIDefaultsLookup; import com.jidesoft.plaf.basic.ThemePainter; import com.jidesoft.swing.ButtonStyle; import com.jidesoft.swing.JideSwingUtilities; import com.jidesoft.swing.TopLevelMenuContainer; import com.sun.java.swing.plaf.windows.WindowsGraphicsUtils; import com.sun.java.swing.plaf.windows.WindowsLookAndFeel; import javax.swing.*; import javax.swing.event.*; import javax.swing.plaf.ComponentUI; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.Arrays; /** * Menu UI implementation */ public class VsnetMenuUI extends VsnetMenuItemUI { protected ChangeListener changeListener; protected PropertyChangeListener propertyChangeListener; protected MenuListener menuListener; private int lastMnemonic = 0; private static final boolean DEBUG = false; // show bad params, misc. private static boolean crossMenuMnemonic = true; private boolean isMouseOver = false; private PopupMenuListener popupMenuListener; public static ComponentUI createUI(JComponent x) { return new VsnetMenuUI(); } @Override protected void installDefaults() { super.installDefaults(); if (menuItem instanceof JMenu) { ((JMenu) menuItem).setDelay(200); } crossMenuMnemonic = UIDefaultsLookup.getBoolean("Menu.crossMenuMnemonic"); } @Override protected String getPropertyPrefix() { return "Menu"; } @Override protected void paintBackground(Graphics g, JMenuItem menuItem, Color bgColor) { if (!(menuItem instanceof JMenu) || !((JMenu) menuItem).isTopLevelMenu()) { super.paintBackground(g, menuItem, bgColor); return; } ButtonModel model = menuItem.getModel(); Color oldColor = g.getColor(); int menuWidth; int menuHeight; if (JideSwingUtilities.getOrientationOf(menuItem) == SwingConstants.HORIZONTAL) { menuWidth = menuItem.getWidth(); menuHeight = menuItem.getHeight(); } else { menuWidth = menuItem.getHeight(); menuHeight = menuItem.getWidth(); } Color borderColor = getPainter().getMenuItemBorderColor(); // Color mouseHoverBackground = UIDefaultsLookup.getColor("Menu.mouseHoverBackground"); // Border mouseHoverBorder = UIDefaultsLookup.getBorder("Menu.mouseHoverBorder"); if (menuItem.isOpaque()) { if (menuItem.getParent() != null) { g.setColor(menuItem.getParent().getBackground()); } else { g.setColor(menuItem.getBackground()); } g.fillRect(0, 0, menuWidth, menuHeight); } Rectangle rect = new Rectangle(0, 0, menuWidth, menuHeight); if (menuItem instanceof JMenu && model.isSelected()) { // Draw a dark shadow border without bottom // TODO: we should consider the location of popup menu and decide which side not paint. // TODO: for example if the menu is going upward, we shouldn't paint the top. if (((JMenu) menuItem).getPopupMenu().isVisible()) { // paint differently if popup menu is visible if (JideSwingUtilities.getOrientationOf(menuItem) == SwingConstants.HORIZONTAL) { getPainter().paintMenuItemBackground(menuItem, g, rect, JideSwingUtilities.getOrientationOf(menuItem), ThemePainter.STATE_DEFAULT, false); g.setColor(borderColor); g.drawLine(0, 0, menuWidth - 1, 0); g.drawLine(menuWidth - 1, 0, menuWidth - 1, menuHeight - 1); g.drawLine(0, menuHeight - 1, 0, 1); g.drawLine(0, menuHeight - 1, menuWidth - 1, menuHeight - 1); } else { getPainter().paintMenuItemBackground(menuItem, g, rect, JideSwingUtilities.getOrientationOf(menuItem), ThemePainter.STATE_DEFAULT, false); g.setColor(borderColor); g.drawLine(0, menuHeight - 1, menuWidth - 1, menuHeight - 1); g.drawLine(menuWidth - 1, 0, menuWidth - 1, menuHeight); g.drawLine(0, menuHeight - 1, 0, 1); g.drawLine(0, 0, menuWidth - 1, 0); } } else { getPainter().paintMenuItemBackground(menuItem, g, rect, JideSwingUtilities.getOrientationOf(menuItem), ThemePainter.STATE_ROLLOVER); } } else if (isMouseOver() && model.isEnabled()) { getPainter().paintMenuItemBackground(menuItem, g, rect, JideSwingUtilities.getOrientationOf(menuItem), ThemePainter.STATE_ROLLOVER); } if (isDownArrowVisible(menuItem.getParent())) { g.setColor(menuItem.isEnabled() ? Color.BLACK : Color.GRAY); int middle = menuWidth - 9; g.drawLine(middle - 2, menuHeight / 2 - 1, middle + 2, menuHeight / 2 - 1); g.drawLine(middle - 1, menuHeight / 2, middle + 1, menuHeight / 2); g.drawLine(middle, menuHeight / 2 + 1, middle, menuHeight / 2 + 1); } g.setColor(oldColor); } @Override protected void installListeners() { super.installListeners(); if (changeListener == null) changeListener = createChangeListener(menuItem); if (changeListener != null) menuItem.addChangeListener(changeListener); if (propertyChangeListener == null) propertyChangeListener = createPropertyChangeListener(menuItem); if (propertyChangeListener != null) menuItem.addPropertyChangeListener(propertyChangeListener); if (menuListener == null) menuListener = createMenuListener(menuItem); if (menuListener != null && menuItem instanceof JMenu) { ((JMenu) menuItem).addMenuListener(menuListener); } if (popupMenuListener == null) { popupMenuListener = createPopupMenuListener(); } if (popupMenuListener != null && menuItem instanceof JMenu) { ((JMenu) menuItem).getPopupMenu().addPopupMenuListener(popupMenuListener); } } protected PopupMenuListener createPopupMenuListener() { return new PopupMenuListener() { public void popupMenuWillBecomeVisible(PopupMenuEvent e) { repaint(); } public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { repaint(); } public void popupMenuCanceled(PopupMenuEvent e) { repaint(); } private void repaint() { if (menuItem != null) { menuItem.repaint(); } } }; } @Override protected void installKeyboardActions() { super.installKeyboardActions(); updateMnemonicBinding(); } protected void updateMnemonicBinding() { int mnemonic = menuItem.getModel().getMnemonic(); int[] shortcutKeys = (int[]) UIDefaultsLookup.get("Menu.shortcutKeys"); if (shortcutKeys == null) { shortcutKeys = new int[]{KeyEvent.ALT_MASK}; } if (mnemonic == lastMnemonic) { return; } if (lastMnemonic != 0 && windowInputMap != null) { for (int shortcutKey : shortcutKeys) { windowInputMap.remove(KeyStroke.getKeyStroke (lastMnemonic, shortcutKey, false)); windowInputMap.remove(KeyStroke.getKeyStroke (lastMnemonic, shortcutKey, true)); } } if (mnemonic != 0) { if (windowInputMap == null) { windowInputMap = createInputMap(JComponent. WHEN_IN_FOCUSED_WINDOW); SwingUtilities.replaceUIInputMap(menuItem, JComponent. WHEN_IN_FOCUSED_WINDOW, windowInputMap); } for (int shortcutKey : shortcutKeys) { windowInputMap.put(KeyStroke.getKeyStroke(mnemonic, shortcutKey, false), "selectMenu"); } } lastMnemonic = mnemonic; } @Override protected void uninstallKeyboardActions() { super.uninstallKeyboardActions(); } /** * The ActionMap for BasicMenUI can not be shared, this is subclassed to create a new one for each invocation. */ @Override protected ActionMap getActionMap() { return createActionMap(); } /** * Invoked to create the ActionMap. */ @Override protected ActionMap createActionMap() { ActionMap am = super.createActionMap(); if (am != null && menuItem instanceof JMenu) { am.put("selectMenu", new PostAction((JMenu) menuItem, true)); } return am; } @Override protected MouseInputListener createMouseInputListener(JComponent c) { return new MouseInputHandler(); } protected MenuListener createMenuListener(JComponent c) { return new MenuHandler(); } protected ChangeListener createChangeListener(JComponent c) { return null; } protected PropertyChangeListener createPropertyChangeListener(JComponent c) { return new PropertyChangeHandler(); } @Override protected void uninstallDefaults() { menuItem.setArmed(false); menuItem.setSelected(false); menuItem.resetKeyboardActions(); super.uninstallDefaults(); } @Override protected void uninstallListeners() { super.uninstallListeners(); if (changeListener != null) menuItem.removeChangeListener(changeListener); changeListener = null; if (propertyChangeListener != null) menuItem.removePropertyChangeListener(propertyChangeListener); propertyChangeListener = null; if (menuListener != null && menuItem instanceof JMenu) { ((JMenu) menuItem).removeMenuListener(menuListener); } menuListener = null; if (popupMenuListener != null && menuItem instanceof JMenu) { ((JMenu) menuItem).getPopupMenu().removePopupMenuListener(popupMenuListener); } popupMenuListener = null; } @Override protected MenuDragMouseListener createMenuDragMouseListener(JComponent c) { return new MenuDragMouseHandler(); } @Override protected MenuKeyListener createMenuKeyListener(JComponent c) { return new MenuKeyHandler(); } @Override public Dimension getMaximumSize(JComponent c) { if (menuItem instanceof JMenu && ((JMenu) menuItem).isTopLevelMenu()) { Dimension d = c.getPreferredSize(); if (JideSwingUtilities.getOrientationOf(menuItem) == SwingConstants.HORIZONTAL) { return new Dimension(d.width, Short.MAX_VALUE); } else { return new Dimension(Short.MAX_VALUE, d.height); } } return null; } protected static void setupPostTimer(JMenu menu) { Timer timer = new Timer(menu.getDelay(), new PostAction(menu, false)); timer.setRepeats(false); timer.start(); } protected static void appendPath(MenuElement[] path, MenuElement elem) { MenuElement newPath[] = new MenuElement[path.length + 1]; System.arraycopy(path, 0, newPath, 0, path.length); newPath[path.length] = elem; MenuSelectionManager.defaultManager().setSelectedPath(newPath); } protected static class PostAction extends AbstractAction { JMenu menu; boolean force = false; private static final long serialVersionUID = 8723756757971612903L; PostAction(JMenu menu, boolean shouldForce) { this.menu = menu; this.force = shouldForce; } public void actionPerformed(ActionEvent e) { if (!crossMenuMnemonic) { JPopupMenu pm = getActivePopupMenu(); if (pm != null && pm != menu.getParent()) { return; } } final MenuSelectionManager defaultManager = MenuSelectionManager.defaultManager(); if (force) { Container cnt = menu.getParent(); if (cnt != null && cnt instanceof JMenuBar) { MenuElement me[]; MenuElement subElements[]; subElements = menu.getPopupMenu().getSubElements(); if (subElements.length > 0) { me = new MenuElement[4]; me[0] = (MenuElement) cnt; me[1] = menu; me[2] = menu.getPopupMenu(); me[3] = subElements[0]; } else { me = new MenuElement[3]; me[0] = (MenuElement) cnt; me[1] = menu; me[2] = menu.getPopupMenu(); } defaultManager.setSelectedPath(me); } } else { MenuElement path[] = defaultManager.getSelectedPath(); if (path.length > 0 && path[path.length - 1] == menu) { appendPath(path, menu.getPopupMenu()); } } } @Override public boolean isEnabled() { return menu.getModel().isEnabled(); } } private class PropertyChangeHandler implements PropertyChangeListener { public void propertyChange(PropertyChangeEvent e) { String prop = e.getPropertyName(); if (prop.equals(AbstractButton.MNEMONIC_CHANGED_PROPERTY)) { updateMnemonicBinding(); } else if (prop.equals(ButtonStyle.BUTTON_STYLE_PROPERTY)) { AbstractButton b = (AbstractButton) e.getSource(); b.repaint(); } else if ("verticalTextPosition".equals(prop) || "horizontalTextPosition".equals(prop)) { AbstractButton b = (AbstractButton) e.getSource(); b.updateUI(); } } } /** * Instantiated and used by a menu item to handle the current menu selection from mouse events. A MouseInputHandler * processes and forwards all mouse events to a shared instance of the MenuSelectionManager. * <p/> * This class is protected so that it can be subclassed by other look and feels to implement their own mouse * handling behavior. All overridden methods should call the parent methods so that the menu selection is correct. * * @see MenuSelectionManager * @since 1.4 */ protected class MouseInputHandler implements MouseInputListener { public void mouseClicked(MouseEvent e) { } /** * Invoked when the mouse has been clicked on the menu. This method clears or sets the selection path of the * MenuSelectionManager. * * @param e the mouse event */ public void mousePressed(MouseEvent e) { if (!(menuItem instanceof JMenu)) { return; } JMenu menu = (JMenu) menuItem; if (!menu.isEnabled()) return; MenuSelectionManager manager = MenuSelectionManager.defaultManager(); if (menu.getParent() instanceof JMenuBar || menu.getParent() instanceof TopLevelMenuContainer) { if (menu.isSelected()) { manager.clearSelectedPath(); } else { //Container cnt = menu.getParent(); Container cnt = getFirstParentMenuElement(menu); if (cnt != null && cnt instanceof MenuElement) { ArrayList<Component> parents = new ArrayList<Component>(); while (cnt instanceof MenuElement) { parents.add(0, cnt); if (cnt instanceof JPopupMenu) { cnt = (Container) ((JPopupMenu) cnt).getInvoker(); } else { //cnt = cnt.getParent(); cnt = getFirstParentMenuElement(cnt); } } MenuElement me[] = new MenuElement[parents.size() + 1]; for (int i = 0; i < parents.size(); i++) { Container container = (Container) parents.get(i); me[i] = (MenuElement) container; } me[parents.size()] = menu; manager.setSelectedPath(me); } else { MenuElement me[] = new MenuElement[1]; me[0] = menu; manager.setSelectedPath(me); } } } MenuElement selectedPath[] = manager.getSelectedPath(); if (selectedPath.length > 0 && selectedPath[selectedPath.length - 1] != menu.getPopupMenu()) { if (menu.isTopLevelMenu() || menu.getDelay() == 0) { appendPath(selectedPath, menu.getPopupMenu()); } else { setupPostTimer(menu); } } } protected Container getFirstParentMenuElement(Component comp) { Container parent = comp.getParent(); while (parent != null) { if (parent instanceof MenuElement) return parent; parent = parent.getParent(); } return null; } /** * Invoked when the mouse has been released on the menu. Delegates the mouse event to the MenuSelectionManager. * * @param e the mouse event */ public void mouseReleased(MouseEvent e) { if (!SwingUtilities.isLeftMouseButton(e)) { return; } if (!(menuItem instanceof JMenu)) { return; } JMenu menu = (JMenu) menuItem; if (!menu.isEnabled()) return; MenuSelectionManager manager = MenuSelectionManager.defaultManager(); manager.processMouseEvent(e); if (!e.isConsumed()) manager.clearSelectedPath(); } /** * Invoked when the cursor enters the menu. This method sets the selected path for the MenuSelectionManager and * handles the case in which a menu item is used to pop up an additional menu, as in a hierarchical menu * system. * * @param e the mouse event; not used */ public void mouseEntered(MouseEvent e) { if (!(menuItem instanceof JMenu)) { return; } JMenu menu = (JMenu) menuItem; if (!menu.isEnabled()) return; MenuSelectionManager manager = MenuSelectionManager.defaultManager(); MenuElement selectedPath[] = manager.getSelectedPath(); if (!menu.isTopLevelMenu()) { if (!(selectedPath.length > 0 && selectedPath[selectedPath.length - 1] == menu.getPopupMenu())) { if (menu.getDelay() == 0) { appendPath(getPath(), menu.getPopupMenu()); } else { manager.setSelectedPath(getPath()); setupPostTimer(menu); } } } else { if (selectedPath.length > 0 && selectedPath[0] == menu.getParent()) { MenuElement newPath[] = new MenuElement[3]; // A top level menu's parent is by definition // a JMenuBar newPath[0] = (MenuElement) menu.getParent(); newPath[1] = menu; newPath[2] = menu.getPopupMenu(); manager.setSelectedPath(newPath); } } if (!SwingUtilities.isLeftMouseButton(e)) { setMouseOver(true); } menuItem.repaint(); } public void mouseExited(MouseEvent e) { setMouseOver(false); menuItem.repaint(); } /** * Invoked when a mouse button is pressed on the menu and then dragged. Delegates the mouse event to the * MenuSelectionManager. * * @param e the mouse event * @see MouseMotionListener#mouseDragged */ public void mouseDragged(MouseEvent e) { if (!(menuItem instanceof JMenu)) { return; } JMenu menu = (JMenu) menuItem; if (!menu.isEnabled()) return; MenuSelectionManager.defaultManager().processMouseEvent(e); } public void mouseMoved(MouseEvent e) { } } private class MenuHandler implements MenuListener { public void menuSelected(MenuEvent e) { } public void menuDeselected(MenuEvent e) { } public void menuCanceled(MenuEvent e) { if (!(menuItem instanceof JMenu)) { return; } JMenu m = (JMenu) e.getSource(); MenuSelectionManager manager = MenuSelectionManager.defaultManager(); if (manager.isComponentPartOfCurrentMenu(m)) MenuSelectionManager.defaultManager().clearSelectedPath(); } } private class MenuDragMouseHandler implements MenuDragMouseListener { public void menuDragMouseEntered(MenuDragMouseEvent e) { } public void menuDragMouseDragged(MenuDragMouseEvent e) { if (!(menuItem instanceof JMenu)) { return; } if (!menuItem.isEnabled()) return; 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()) { JMenu menu = (JMenu) menuItem; MenuElement selectedPath[] = manager.getSelectedPath(); if (!(selectedPath.length > 0 && selectedPath[selectedPath.length - 1] == menu.getPopupMenu())) { if (menu.isTopLevelMenu() || menu.getDelay() == 0 || e.getID() == MouseEvent.MOUSE_DRAGGED) { appendPath(path, menu.getPopupMenu()); } else { manager.setSelectedPath(path); setupPostTimer(menu); } } } else if (e.getID() == MouseEvent.MOUSE_RELEASED) { Component comp = manager.componentForPoint(e.getComponent(), e.getPoint()); if (comp == null) manager.clearSelectedPath(); } } public void menuDragMouseExited(MenuDragMouseEvent e) { } public void menuDragMouseReleased(MenuDragMouseEvent e) { } } static JPopupMenu getActivePopupMenu() { MenuElement[] path = MenuSelectionManager.defaultManager(). getSelectedPath(); for (int i = path.length - 1; i >= 0; i--) { MenuElement elem = path[i]; if (elem instanceof JPopupMenu) { return (JPopupMenu) elem; } } return null; } /** * Handles the mnemonic handling for the JMenu and JMenuItems. */ private class MenuKeyHandler implements MenuKeyListener { /** * Opens the SubMenu */ public void menuKeyTyped(MenuKeyEvent e) { if (DEBUG) { System.out.println("in BasicMenuUI.menuKeyTyped for " + menuItem.getText()); } if (!crossMenuMnemonic) { JPopupMenu pm = getActivePopupMenu(); if (pm != null && pm != menuItem.getParent()) { return; } } int key = menuItem.getMnemonic(); if (key == 0) return; MenuElement path[] = e.getPath(); if (lower((char) key) == lower(e.getKeyChar())) { JPopupMenu popupMenu = ((JMenu) menuItem).getPopupMenu(); ArrayList newList = new ArrayList(Arrays.asList(path)); newList.add(popupMenu); MenuElement sub[] = popupMenu.getSubElements(); if (sub.length > 0) { newList.add(sub[0]); } MenuSelectionManager manager = e.getMenuSelectionManager(); MenuElement newPath[] = new MenuElement[0]; newPath = (MenuElement[]) newList.toArray(newPath); manager.setSelectedPath(newPath); e.consume(); } } /** * Handles the mnemonics for the menu items. Will also handle duplicate mnemonics. Perhaps this should be moved * into BasicPopupMenuUI. See 4670831 */ public void menuKeyPressed(MenuKeyEvent e) { if (DEBUG) { System.out.println("in BasicMenuUI.menuKeyPressed for " + menuItem.getText()); } // Handle the case for Escape or Enter... char keyChar = e.getKeyChar(); if (!Character.isLetterOrDigit(keyChar)) return; MenuSelectionManager manager = e.getMenuSelectionManager(); MenuElement path[] = e.getPath(); MenuElement selectedPath[] = manager.getSelectedPath(); for (int i = selectedPath.length - 1; i >= 0; i--) { if (selectedPath[i] == menuItem) { JPopupMenu popupMenu = ((JMenu) menuItem).getPopupMenu(); if (!popupMenu.isVisible()) { return; // Do not invoke items from invisible popup } MenuElement items[] = popupMenu.getSubElements(); MenuElement currentItem = selectedPath[selectedPath.length - 1]; int currentIndex = -1; int matches = 0; int firstMatch = -1; int indexes[] = null; for (int j = 0; j < items.length; j++) { if (!(items[j] instanceof JMenuItem)) { continue; } int key = ((JMenuItem) items[j]).getMnemonic(); if (lower((char) key) == lower(keyChar)) { if (matches == 0) { firstMatch = j; matches++; } else { if (indexes == null) { indexes = new int[items.length]; indexes[0] = firstMatch; } indexes[matches++] = j; } } if (currentItem == items[j]) { currentIndex = matches - 1; } } if (matches == 0) { // no op (consume) } else if (matches == 1) { // Invoke the menu action JMenuItem item = (JMenuItem) items[firstMatch]; if (!(item instanceof JMenu)) { // Let Submenus be handled by menuKeyTyped manager.clearSelectedPath(); item.doClick(); } } else { // Select the menu item with the matching mnemonic. If // the same mnemonic has been invoked then select the next // menu item in the cycle. MenuElement newItem = null; if (indexes != null) { newItem = items[indexes[(currentIndex + 1) % matches]]; } MenuElement newPath[] = new MenuElement[path.length + 2]; System.arraycopy(path, 0, newPath, 0, path.length); newPath[path.length] = popupMenu; newPath[path.length + 1] = newItem; manager.setSelectedPath(newPath); } e.consume(); return; } } } public void menuKeyReleased(MenuKeyEvent e) { } private char lower(char keyChar) { return Character.toLowerCase(keyChar); } } /** * Method which renders the text of the current menu item. * <p/> * * @param g Graphics context * @param menuItem Current menu item to render * @param textRect Bounding rectangle to render the text. * @param text String to render * @since 1.4 */ @Override protected void paintText(Graphics g, JMenuItem menuItem, Rectangle textRect, String text) { // Note: This method is almost identical to the same method in WindowsMenuItemUI ButtonModel model = menuItem.getModel(); if (!(menuItem instanceof JMenu) || !((JMenu) menuItem).isTopLevelMenu()) { if (menuItem.getComponentOrientation().isLeftToRight()) { int defaultTextIconGap = UIDefaultsLookup.getInt("MenuItem.textIconGap"); int defaultShadowWidth = UIDefaultsLookup.getInt("MenuItem.shadowWidth"); textRect.x = defaultShadowWidth + defaultTextIconGap; } else { int defaultTextIconGap = UIDefaultsLookup.getInt("MenuItem.textIconGap"); int defaultShadowWidth = UIDefaultsLookup.getInt("MenuItem.shadowWidth"); textRect.x = viewRect.width - (defaultShadowWidth + defaultTextIconGap + textRect.width); } } if (!model.isEnabled()) { // *** paint the text disabled WindowsGraphicsUtils.paintText(g, menuItem, textRect, text, 0); } else { FontMetrics fm = g.getFontMetrics(); int mnemonicIndex = menuItem.getDisplayedMnemonicIndex(); // W2K Feature: Check to see if the Underscore should be rendered. if (WindowsLookAndFeel.isMnemonicHidden()) { mnemonicIndex = -1; } Color oldColor = g.getColor(); // For Win95, the selected text color is the selection foreground color if (model.isSelected()) { if (/*SystemInfo.isClassicWindows() || */menuItem instanceof JMenu && !((JMenu) menuItem).isTopLevelMenu()) { g.setColor(selectionForeground); // Uses protected field. } } JideSwingUtilities.drawStringUnderlineCharAt(menuItem, g, text, mnemonicIndex, textRect.x, textRect.y + fm.getAscent()); g.setColor(oldColor); } // } } /** * Set the temporary flag to indicate if the mouse has entered the menu. * * @param over the flag */ protected void setMouseOver(boolean over) { isMouseOver = over; menuItem.getModel().setRollover(isMouseOver); } /** * Get the temporary flag to indicate if the mouse has entered the menu. * * @return the flag. */ protected boolean isMouseOver() { return isMouseOver; } @Override public Dimension getPreferredSize(JComponent c) { Dimension size = super.getPreferredSize(c); if (menuItem instanceof JMenu && ((JMenu) menuItem).isTopLevelMenu() && isDownArrowVisible(menuItem.getParent())) { if (JideSwingUtilities.getOrientationOf(menuItem) == SwingConstants.HORIZONTAL) size.width += 11; else size.height += 11; } return size; } }