| /* BasicMenuItemUI.java -- |
| Copyright (C) 2002, 2004 Free Software Foundation, Inc. |
| |
| This file is part of GNU Classpath. |
| |
| GNU Classpath is free software; you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by |
| the Free Software Foundation; either version 2, or (at your option) |
| any later version. |
| |
| GNU Classpath is distributed in the hope that it will be useful, but |
| WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with GNU Classpath; see the file COPYING. If not, write to the |
| Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA |
| 02111-1307 USA. |
| |
| Linking this library statically or dynamically with other modules is |
| making a combined work based on this library. Thus, the terms and |
| conditions of the GNU General Public License cover the whole |
| combination. |
| |
| As a special exception, the copyright holders of this library give you |
| permission to link this library with independent modules to produce an |
| executable, regardless of the license terms of these independent |
| modules, and to copy and distribute the resulting executable under |
| terms of your choice, provided that you also meet, for each linked |
| independent module, the terms and conditions of the license of that |
| module. An independent module is a module which is not derived from |
| or based on this library. If you modify this library, you may extend |
| this exception to your version of the library, but you are not |
| obligated to do so. If you do not wish to do so, delete this |
| exception statement from your version. */ |
| |
| |
| package javax.swing.plaf.basic; |
| |
| import java.awt.Color; |
| import java.awt.Component; |
| import java.awt.Dimension; |
| import java.awt.Font; |
| import java.awt.FontMetrics; |
| import java.awt.Graphics; |
| import java.awt.Insets; |
| import java.awt.Rectangle; |
| import java.awt.event.KeyEvent; |
| import java.awt.event.MouseEvent; |
| import java.beans.PropertyChangeEvent; |
| import java.beans.PropertyChangeListener; |
| import java.util.ArrayList; |
| |
| import javax.swing.Icon; |
| import javax.swing.JComponent; |
| import javax.swing.JMenu; |
| import javax.swing.JMenuItem; |
| import javax.swing.JPopupMenu; |
| import javax.swing.KeyStroke; |
| import javax.swing.MenuElement; |
| import javax.swing.MenuSelectionManager; |
| import javax.swing.SwingConstants; |
| import javax.swing.SwingUtilities; |
| import javax.swing.UIDefaults; |
| import javax.swing.UIManager; |
| import javax.swing.event.MenuDragMouseEvent; |
| import javax.swing.event.MenuDragMouseListener; |
| import javax.swing.event.MenuKeyEvent; |
| import javax.swing.event.MenuKeyListener; |
| import javax.swing.event.MouseInputListener; |
| import javax.swing.plaf.ComponentUI; |
| import javax.swing.plaf.MenuItemUI; |
| |
| /** |
| * UI Delegate for JMenuItem. |
| */ |
| public class BasicMenuItemUI extends MenuItemUI |
| { |
| /** |
| * Font to be used when displaying menu item's accelerator. |
| */ |
| protected Font acceleratorFont; |
| |
| /** |
| * Color to be used when displaying menu item's accelerator. |
| */ |
| protected Color acceleratorForeground; |
| |
| /** |
| * Color to be used when displaying menu item's accelerator when menu item is |
| * selected. |
| */ |
| protected Color acceleratorSelectionForeground; |
| |
| /** |
| * Icon that is displayed after the text to indicated that this menu contains |
| * submenu. |
| */ |
| protected Icon arrowIcon; |
| |
| /** |
| * Icon that is displayed before the text. This icon is only used in |
| * JCheckBoxMenuItem or JRadioBoxMenuItem. |
| */ |
| protected Icon checkIcon; |
| |
| /** |
| * Number of spaces between icon and text. |
| */ |
| protected int defaultTextIconGap = 4; |
| |
| /** |
| * Color of the text when menu item is disabled |
| */ |
| protected Color disabledForeground; |
| |
| /** |
| * The menu Drag mouse listener listening to the menu item. |
| */ |
| protected MenuDragMouseListener menuDragMouseListener; |
| |
| /** |
| * The menu item itself |
| */ |
| protected JMenuItem menuItem; |
| |
| /** |
| * Menu Key listener listening to the menu item. |
| */ |
| protected MenuKeyListener menuKeyListener; |
| |
| /** |
| * mouse input listener listening to menu item. |
| */ |
| protected MouseInputListener mouseInputListener; |
| |
| /** |
| * Indicates if border should be painted |
| */ |
| protected boolean oldBorderPainted; |
| |
| /** |
| * Color of text that is used when menu item is selected |
| */ |
| protected Color selectionBackground; |
| |
| /** |
| * Color of the text that is used when menu item is selected. |
| */ |
| protected Color selectionForeground; |
| |
| /** |
| * String that separates description of the modifiers and the key |
| */ |
| private String acceleratorDelimiter; |
| |
| /** |
| * PropertyChangeListener to listen for property changes in the menu item |
| */ |
| private PropertyChangeListener propertyChangeListener; |
| |
| /** |
| * Number of spaces between accelerator and menu item's label. |
| */ |
| private int defaultAcceleratorLabelGap = 4; |
| |
| /** |
| * Creates a new BasicMenuItemUI object. |
| */ |
| public BasicMenuItemUI() |
| { |
| mouseInputListener = createMouseInputListener(menuItem); |
| menuDragMouseListener = createMenuDragMouseListener(menuItem); |
| menuKeyListener = createMenuKeyListener(menuItem); |
| propertyChangeListener = new PropertyChangeHandler(); |
| } |
| |
| /** |
| * Create MenuDragMouseListener to listen for mouse dragged events. |
| * |
| * @param c menu item to listen to |
| * |
| * @return The MenuDragMouseListener |
| */ |
| protected MenuDragMouseListener createMenuDragMouseListener(JComponent c) |
| { |
| return new MenuDragMouseHandler(); |
| } |
| |
| /** |
| * Creates MenuKeyListener to listen to key events occuring when menu item |
| * is visible on the screen. |
| * |
| * @param c menu item to listen to |
| * |
| * @return The MenuKeyListener |
| */ |
| protected MenuKeyListener createMenuKeyListener(JComponent c) |
| { |
| return new MenuKeyHandler(); |
| } |
| |
| /** |
| * Handles mouse input events occuring for this menu item |
| * |
| * @param c menu item to listen to |
| * |
| * @return The MouseInputListener |
| */ |
| protected MouseInputListener createMouseInputListener(JComponent c) |
| { |
| return new MouseInputHandler(); |
| } |
| |
| /** |
| * Factory method to create a BasicMenuItemUI for the given {@link |
| * JComponent}, which should be a {@link JMenuItem}. |
| * |
| * @param c The {@link JComponent} a UI is being created for. |
| * |
| * @return A BasicMenuItemUI for the {@link JComponent}. |
| */ |
| public static ComponentUI createUI(JComponent c) |
| { |
| return new BasicMenuItemUI(); |
| } |
| |
| /** |
| * Programatically clicks menu item. |
| * |
| * @param msm MenuSelectionManager for the menu hierarchy |
| */ |
| protected void doClick(MenuSelectionManager msm) |
| { |
| menuItem.doClick(); |
| msm.clearSelectedPath(); |
| } |
| |
| /** |
| * Returns maximum size for the specified menu item |
| * |
| * @param c component for which to get maximum size |
| * |
| * @return Maximum size for the specified menu item. |
| */ |
| public Dimension getMaximumSize(JComponent c) |
| { |
| return null; |
| } |
| |
| /** |
| * Returns minimum size for the specified menu item |
| * |
| * @param c component for which to get minimum size |
| * |
| * @return Minimum size for the specified menu item. |
| */ |
| public Dimension getMinimumSize(JComponent c) |
| { |
| return null; |
| } |
| |
| /** |
| * Returns path to this menu item. |
| * |
| * @return $MenuElement[]$ Returns array of menu elements |
| * that constitute a path to this menu item. |
| */ |
| public MenuElement[] getPath() |
| { |
| ArrayList path = new ArrayList(); |
| |
| // Path to menu should also include its popup menu. |
| if (menuItem instanceof JMenu) |
| path.add(((JMenu) menuItem).getPopupMenu()); |
| |
| Component c = menuItem; |
| while (c instanceof MenuElement) |
| { |
| path.add(0, (MenuElement) c); |
| |
| if (c instanceof JPopupMenu) |
| c = ((JPopupMenu) c).getInvoker(); |
| else |
| c = c.getParent(); |
| } |
| |
| MenuElement[] pathArray = new MenuElement[path.size()]; |
| path.toArray(pathArray); |
| return pathArray; |
| } |
| |
| /** |
| * Returns preferred size for the given menu item. |
| * |
| * @param c menu item for which to get preferred size |
| * @param checkIcon chech icon displayed in the given menu item |
| * @param arrowIcon arrow icon displayed in the given menu item |
| * @param defaultTextIconGap space between icon and text in the given menuItem |
| * |
| * @return $Dimension$ preferred size for the given menu item |
| */ |
| protected Dimension getPreferredMenuItemSize(JComponent c, Icon checkIcon, |
| Icon arrowIcon, |
| int defaultTextIconGap) |
| { |
| JMenuItem m = (JMenuItem) c; |
| Dimension d = BasicGraphicsUtils.getPreferredButtonSize(m, |
| defaultTextIconGap); |
| |
| // if menu item has accelerator then take accelerator's size into account |
| // when calculating preferred size. |
| KeyStroke accelerator = m.getAccelerator(); |
| Rectangle rect; |
| |
| if (accelerator != null) |
| { |
| rect = getAcceleratorRect(accelerator, |
| m.getToolkit().getFontMetrics(acceleratorFont)); |
| |
| // add width of accelerator's text |
| d.width = d.width + rect.width + defaultAcceleratorLabelGap; |
| |
| // adjust the heigth of the preferred size if necessary |
| if (d.height < rect.height) |
| d.height = rect.height; |
| } |
| |
| if (checkIcon != null) |
| { |
| d.width = d.width + checkIcon.getIconWidth() + defaultTextIconGap; |
| |
| if (checkIcon.getIconHeight() > d.height) |
| d.height = checkIcon.getIconHeight(); |
| } |
| |
| if (arrowIcon != null && (c instanceof JMenu)) |
| { |
| d.width = d.width + arrowIcon.getIconWidth() + defaultTextIconGap; |
| |
| if (arrowIcon.getIconHeight() > d.height) |
| d.height = arrowIcon.getIconHeight(); |
| } |
| |
| return d; |
| } |
| |
| /** |
| * Returns preferred size of the given component |
| * |
| * @param c component for which to return preferred size |
| * |
| * @return $Dimension$ preferred size for the given component |
| */ |
| public Dimension getPreferredSize(JComponent c) |
| { |
| return getPreferredMenuItemSize(c, checkIcon, arrowIcon, defaultTextIconGap); |
| } |
| |
| protected String getPropertyPrefix() |
| { |
| return null; |
| } |
| |
| /** |
| * This method installs the components for this {@link JMenuItem}. |
| * |
| * @param menuItem The {@link JMenuItem} to install components for. |
| */ |
| protected void installComponents(JMenuItem menuItem) |
| { |
| // FIXME: Need to implement |
| } |
| |
| /** |
| * This method installs the defaults that are defined in the Basic look and |
| * feel for this {@link JMenuItem}. |
| */ |
| protected void installDefaults() |
| { |
| UIDefaults defaults = UIManager.getLookAndFeelDefaults(); |
| |
| menuItem.setBackground(defaults.getColor("MenuItem.background")); |
| menuItem.setBorder(defaults.getBorder("MenuItem.border")); |
| menuItem.setFont(defaults.getFont("MenuItem.font")); |
| menuItem.setForeground(defaults.getColor("MenuItem.foreground")); |
| menuItem.setMargin(defaults.getInsets("MenuItem.margin")); |
| menuItem.setOpaque(true); |
| acceleratorFont = defaults.getFont("MenuItem.acceleratorFont"); |
| acceleratorForeground = defaults.getColor("MenuItem.acceleratorForeground"); |
| acceleratorSelectionForeground = defaults.getColor("MenuItem.acceleratorSelectionForeground"); |
| selectionBackground = defaults.getColor("MenuItem.selectionBackground"); |
| selectionForeground = defaults.getColor("MenuItem.selectionForeground"); |
| acceleratorDelimiter = defaults.getString("MenuItem.acceleratorDelimiter"); |
| |
| menuItem.setHorizontalTextPosition(SwingConstants.TRAILING); |
| menuItem.setHorizontalAlignment(SwingConstants.LEADING); |
| } |
| |
| /** |
| * This method installs the keyboard actions for this {@link JMenuItem}. |
| */ |
| protected void installKeyboardActions() |
| { |
| // FIXME: Need to implement |
| } |
| |
| /** |
| * This method installs the listeners for the {@link JMenuItem}. |
| */ |
| protected void installListeners() |
| { |
| menuItem.addMouseListener(mouseInputListener); |
| menuItem.addMouseMotionListener(mouseInputListener); |
| menuItem.addMenuDragMouseListener(menuDragMouseListener); |
| menuItem.addMenuKeyListener(menuKeyListener); |
| menuItem.addPropertyChangeListener(propertyChangeListener); |
| } |
| |
| /** |
| * Installs and initializes all fields for this UI delegate. Any properties |
| * of the UI that need to be initialized and/or set to defaults will be |
| * done now. It will also install any listeners necessary. |
| * |
| * @param c The {@link JComponent} that is having this UI installed. |
| */ |
| public void installUI(JComponent c) |
| { |
| super.installUI(c); |
| menuItem = (JMenuItem) c; |
| installDefaults(); |
| installComponents(menuItem); |
| installListeners(); |
| } |
| |
| /** |
| * Paints given menu item using specified graphics context |
| * |
| * @param g The graphics context used to paint this menu item |
| * @param c Menu Item to paint |
| */ |
| public void paint(Graphics g, JComponent c) |
| { |
| paintMenuItem(g, c, checkIcon, arrowIcon, c.getBackground(), |
| c.getForeground(), defaultTextIconGap); |
| } |
| |
| /** |
| * Paints background of the menu item |
| * |
| * @param g The graphics context used to paint this menu item |
| * @param menuItem menu item to paint |
| * @param bgColor Background color to use when painting menu item |
| */ |
| protected void paintBackground(Graphics g, JMenuItem menuItem, Color bgColor) |
| { |
| Dimension size = getPreferredSize(menuItem); |
| Color foreground = g.getColor(); |
| g.setColor(bgColor); |
| g.drawRect(0, 0, size.width, size.height); |
| g.setColor(foreground); |
| } |
| |
| /** |
| * Paints specified menu item |
| * |
| * @param g The graphics context used to paint this menu item |
| * @param c menu item to paint |
| * @param checkIcon check icon to use when painting menu item |
| * @param arrowIcon arrow icon to use when painting menu item |
| * @param background Background color of the menu item |
| * @param foreground Foreground color of the menu item |
| * @param defaultTextIconGap space to use between icon and |
| * text when painting menu item |
| */ |
| protected void paintMenuItem(Graphics g, JComponent c, Icon checkIcon, |
| Icon arrowIcon, Color background, |
| Color foreground, int defaultTextIconGap) |
| { |
| JMenuItem m = (JMenuItem) c; |
| Rectangle tr = new Rectangle(); // text rectangle |
| Rectangle ir = new Rectangle(); // icon rectangle |
| Rectangle vr = new Rectangle(); // view rectangle |
| Rectangle br = new Rectangle(); // border rectangle |
| Rectangle ar = new Rectangle(); // accelerator rectangle |
| Rectangle cr = new Rectangle(); // checkIcon rectangle |
| |
| int vertAlign = m.getVerticalAlignment(); |
| int horAlign = m.getHorizontalAlignment(); |
| int vertTextPos = m.getVerticalTextPosition(); |
| int horTextPos = m.getHorizontalTextPosition(); |
| |
| Font f = m.getFont(); |
| g.setFont(f); |
| FontMetrics fm = g.getFontMetrics(f); |
| SwingUtilities.calculateInnerArea(m, br); |
| SwingUtilities.calculateInsetArea(br, m.getInsets(), vr); |
| paintBackground(g, m, m.getBackground()); |
| |
| /* MenuItems insets are equal to menuItems margin, space between text and |
| menuItems border. We need to paint insets region as well. */ |
| Insets insets = m.getInsets(); |
| br.x -= insets.left; |
| br.y -= insets.top; |
| br.width += insets.right + insets.left; |
| br.height += insets.top + insets.bottom; |
| |
| /* Menu item is considered to be highlighted when it is selected. |
| It is considered to be selected if menu item is inside some menu |
| and is armed or if it is both armed and pressed */ |
| if (m.getModel().isArmed() |
| && (m.getParent() instanceof MenuElement || m.getModel().isPressed())) |
| { |
| if (m.isContentAreaFilled()) |
| { |
| g.setColor(selectionBackground); |
| g.fillRect(br.x, br.y, br.width, br.height); |
| } |
| } |
| else |
| { |
| if (m.isContentAreaFilled()) |
| { |
| g.setColor(m.getBackground()); |
| g.fillRect(br.x, br.y, br.width, br.height); |
| } |
| } |
| |
| // If this menu item is a JCheckBoxMenuItem then paint check icon |
| if (checkIcon != null) |
| { |
| SwingUtilities.layoutCompoundLabel(m, fm, null, checkIcon, vertAlign, |
| horAlign, vertTextPos, horTextPos, |
| vr, cr, tr, defaultTextIconGap); |
| checkIcon.paintIcon(m, g, cr.x, cr.y); |
| |
| // We need to calculate position of the menu text and position of |
| // user menu icon if there exists one relative to the check icon. |
| // So we need to adjust view rectangle s.t. its starting point is at |
| // checkIcon.width + defaultTextIconGap. |
| vr.x = cr.x + cr.width + defaultTextIconGap; |
| } |
| |
| // if this is a submenu, then paint arrow icon to indicate it. |
| if (arrowIcon != null && (c instanceof JMenu)) |
| { |
| if (! ((JMenu) c).isTopLevelMenu()) |
| { |
| int width = arrowIcon.getIconWidth(); |
| int height = arrowIcon.getIconHeight(); |
| |
| arrowIcon.paintIcon(m, g, vr.width - width + defaultTextIconGap, |
| vr.y + 2); |
| } |
| } |
| |
| // paint text and user menu icon if it exists |
| Icon i = m.getIcon(); |
| SwingUtilities.layoutCompoundLabel(c, fm, m.getText(), i, |
| vertAlign, horAlign, vertTextPos, |
| horTextPos, vr, ir, tr, |
| defaultTextIconGap); |
| if (i != null) |
| i.paintIcon(c, g, ir.x, ir.y); |
| |
| paintText(g, m, tr, m.getText()); |
| |
| // paint accelerator |
| String acceleratorText = ""; |
| |
| if (m.getAccelerator() != null) |
| { |
| acceleratorText = getAcceleratorText(m.getAccelerator()); |
| fm = g.getFontMetrics(acceleratorFont); |
| ar.width = fm.stringWidth(acceleratorText); |
| ar.x = br.width - ar.width; |
| vr.x = br.width - ar.width; |
| |
| SwingUtilities.layoutCompoundLabel(m, fm, acceleratorText, null, |
| vertAlign, horAlign, vertTextPos, |
| horTextPos, vr, ir, ar, |
| defaultTextIconGap); |
| |
| paintAccelerator(g, m, ar, acceleratorText); |
| } |
| } |
| |
| /** |
| * Paints label for the given menu item |
| * |
| * @param g The graphics context used to paint this menu item |
| * @param menuItem menu item for which to draw its label |
| * @param textRect rectangle specifiying position of the text relative to |
| * the given menu item |
| * @param text label of the menu item |
| */ |
| protected void paintText(Graphics g, JMenuItem menuItem, Rectangle textRect, |
| String text) |
| { |
| Font f = menuItem.getFont(); |
| g.setFont(f); |
| FontMetrics fm = g.getFontMetrics(f); |
| |
| if (text != null && ! text.equals("")) |
| { |
| if (menuItem.isEnabled()) |
| g.setColor(menuItem.getForeground()); |
| else |
| // FIXME: should fix this to use 'disabledForeground', but its |
| // default value in BasicLookAndFeel is null. |
| g.setColor(Color.gray); |
| |
| int mnemonicIndex = menuItem.getDisplayedMnemonicIndex(); |
| |
| if (mnemonicIndex != -1) |
| BasicGraphicsUtils.drawStringUnderlineCharAt(g, text, mnemonicIndex, |
| textRect.x, |
| textRect.y |
| + fm.getAscent()); |
| else |
| BasicGraphicsUtils.drawString(g, text, 0, textRect.x, |
| textRect.y + fm.getAscent()); |
| } |
| } |
| |
| /** |
| * This method uninstalls the components for this {@link JMenuItem}. |
| * |
| * @param menuItem The {@link JMenuItem} to uninstall components for. |
| */ |
| protected void uninstallComponents(JMenuItem menuItem) |
| { |
| // FIXME: need to implement |
| } |
| |
| /** |
| * This method uninstalls the defaults and sets any objects created during |
| * install to null |
| */ |
| protected void uninstallDefaults() |
| { |
| menuItem.setForeground(null); |
| menuItem.setBackground(null); |
| menuItem.setBorder(null); |
| menuItem.setMargin(null); |
| menuItem.setBackground(null); |
| menuItem.setBorder(null); |
| menuItem.setFont(null); |
| menuItem.setForeground(null); |
| menuItem.setMargin(null); |
| acceleratorFont = null; |
| acceleratorForeground = null; |
| acceleratorSelectionForeground = null; |
| arrowIcon = null; |
| selectionBackground = null; |
| selectionForeground = null; |
| acceleratorDelimiter = null; |
| } |
| |
| /** |
| * Uninstalls any keyboard actions. |
| */ |
| protected void uninstallKeyboardActions() |
| { |
| // FIXME: need to implement |
| } |
| |
| /** |
| * Unregisters all the listeners that this UI delegate was using. |
| */ |
| protected void uninstallListeners() |
| { |
| menuItem.removeMouseListener(mouseInputListener); |
| menuItem.removeMenuDragMouseListener(menuDragMouseListener); |
| menuItem.removeMenuKeyListener(menuKeyListener); |
| menuItem.removePropertyChangeListener(propertyChangeListener); |
| } |
| |
| /** |
| * Performs the opposite of installUI. Any properties or resources that need |
| * to be cleaned up will be done now. It will also uninstall any listeners |
| * it has. In addition, any properties of this UI will be nulled. |
| * |
| * @param c The {@link JComponent} that is having this UI uninstalled. |
| */ |
| public void uninstallUI(JComponent c) |
| { |
| uninstallListeners(); |
| uninstallDefaults(); |
| uninstallComponents(menuItem); |
| menuItem = null; |
| } |
| |
| /** |
| * This method calls paint. |
| * |
| * @param g The graphics context used to paint this menu item |
| * @param c The menu item to paint |
| */ |
| public void update(Graphics g, JComponent c) |
| { |
| paint(g, c); |
| } |
| |
| /** |
| * Return text representation of the specified accelerator |
| * |
| * @param accelerator Accelerator for which to return string representation |
| * |
| * @return $String$ Text representation of the given accelerator |
| */ |
| private String getAcceleratorText(KeyStroke accelerator) |
| { |
| // convert keystroke into string format |
| String modifiersText = ""; |
| int modifiers = accelerator.getModifiers(); |
| char keyChar = accelerator.getKeyChar(); |
| int keyCode = accelerator.getKeyCode(); |
| |
| if (modifiers != 0) |
| modifiersText = KeyEvent.getKeyModifiersText(modifiers) |
| + acceleratorDelimiter; |
| |
| if (keyCode == KeyEvent.VK_UNDEFINED) |
| return modifiersText + keyChar; |
| else |
| return modifiersText + KeyEvent.getKeyText(keyCode); |
| } |
| |
| /** |
| * Calculates and return rectange in which accelerator should be displayed |
| * |
| * @param accelerator accelerator for which to return the display rectangle |
| * @param fm The font metrics used to measure the text |
| * |
| * @return $Rectangle$ reactangle which will be used to display accelerator |
| */ |
| private Rectangle getAcceleratorRect(KeyStroke accelerator, FontMetrics fm) |
| { |
| int width = fm.stringWidth(getAcceleratorText(accelerator)); |
| int height = fm.getHeight(); |
| return new Rectangle(0, 0, width, height); |
| } |
| |
| /** |
| * Paints accelerator inside menu item |
| * |
| * @param g The graphics context used to paint the border |
| * @param menuItem Menu item for which to draw accelerator |
| * @param acceleratorRect rectangle representing position |
| * of the accelerator relative to the menu item |
| * @param acceleratorText accelerator's text |
| */ |
| private void paintAccelerator(Graphics g, JMenuItem menuItem, |
| Rectangle acceleratorRect, |
| String acceleratorText) |
| { |
| g.setFont(acceleratorFont); |
| FontMetrics fm = g.getFontMetrics(acceleratorFont); |
| |
| if (menuItem.isEnabled()) |
| g.setColor(acceleratorForeground); |
| else |
| // FIXME: should fix this to use 'disabledForeground', but its |
| // default value in BasicLookAndFeel is null. |
| g.setColor(Color.gray); |
| |
| BasicGraphicsUtils.drawString(g, acceleratorText, 0, acceleratorRect.x, |
| acceleratorRect.y + fm.getAscent()); |
| } |
| |
| /** |
| * This class handles mouse events occuring inside the menu item. |
| * Most of the events are forwarded for processing to MenuSelectionManager |
| * of the current menu hierarchy. |
| * |
| */ |
| protected class MouseInputHandler implements MouseInputListener |
| { |
| /** |
| * Creates a new MouseInputHandler object. |
| */ |
| protected MouseInputHandler() |
| { |
| } |
| |
| /** |
| * This method is called when mouse is clicked on the menu item. |
| * It forwards this event to MenuSelectionManager. |
| * |
| * @param e A {@link MouseEvent}. |
| */ |
| public void mouseClicked(MouseEvent e) |
| { |
| MenuSelectionManager manager = MenuSelectionManager.defaultManager(); |
| manager.processMouseEvent(e); |
| } |
| |
| /** |
| * This method is called when mouse is dragged inside the menu item. |
| * It forwards this event to MenuSelectionManager. |
| * |
| * @param e A {@link MouseEvent}. |
| */ |
| public void mouseDragged(MouseEvent e) |
| { |
| MenuSelectionManager manager = MenuSelectionManager.defaultManager(); |
| manager.processMouseEvent(e); |
| } |
| |
| /** |
| * This method is called when mouse enters menu item. |
| * When this happens menu item is considered to be selected and selection path |
| * in MenuSelectionManager is set. This event is also forwarded to MenuSelection |
| * Manager for further processing. |
| * |
| * @param e A {@link MouseEvent}. |
| */ |
| public void mouseEntered(MouseEvent e) |
| { |
| Component source = (Component) e.getSource(); |
| if (source.getParent() instanceof MenuElement) |
| { |
| MenuSelectionManager manager = MenuSelectionManager.defaultManager(); |
| manager.setSelectedPath(getPath()); |
| manager.processMouseEvent(e); |
| } |
| } |
| |
| /** |
| * This method is called when mouse exits menu item. The event is |
| * forwarded to MenuSelectionManager for processing. |
| * |
| * @param e A {@link MouseEvent}. |
| */ |
| public void mouseExited(MouseEvent e) |
| { |
| MenuSelectionManager manager = MenuSelectionManager.defaultManager(); |
| manager.processMouseEvent(e); |
| } |
| |
| /** |
| * This method is called when mouse is inside the menu item. |
| * This event is forwarder to MenuSelectionManager for further processing. |
| * |
| * @param e A {@link MouseEvent}. |
| */ |
| public void mouseMoved(MouseEvent e) |
| { |
| MenuSelectionManager manager = MenuSelectionManager.defaultManager(); |
| manager.processMouseEvent(e); |
| } |
| |
| /** |
| * This method is called when mouse is pressed. This event is forwarded to |
| * MenuSelectionManager for further processing. |
| * |
| * @param e A {@link MouseEvent}. |
| */ |
| public void mousePressed(MouseEvent e) |
| { |
| MenuSelectionManager manager = MenuSelectionManager.defaultManager(); |
| manager.processMouseEvent(e); |
| } |
| |
| /** |
| * This method is called when mouse is released. If the mouse is released |
| * inside this menuItem, then this menu item is considered to be chosen and |
| * the menu hierarchy should be closed. |
| * |
| * @param e A {@link MouseEvent}. |
| */ |
| public void mouseReleased(MouseEvent e) |
| { |
| Rectangle size = menuItem.getBounds(); |
| MenuSelectionManager manager = MenuSelectionManager.defaultManager(); |
| if (e.getX() > 0 && e.getX() < size.width && e.getY() > 0 |
| && e.getY() < size.height) |
| { |
| manager.clearSelectedPath(); |
| menuItem.doClick(); |
| } |
| |
| else |
| manager.processMouseEvent(e); |
| } |
| } |
| |
| /** |
| * This class handles mouse dragged events. |
| */ |
| protected class MenuDragMouseHandler implements MenuDragMouseListener |
| { |
| /** |
| * Tbis method is invoked when mouse is dragged over the menu item. |
| * |
| * @param e The MenuDragMouseEvent |
| */ |
| public void menuDragMouseDragged(MenuDragMouseEvent e) |
| { |
| MenuSelectionManager manager = MenuSelectionManager.defaultManager(); |
| manager.setSelectedPath(e.getPath()); |
| } |
| |
| /** |
| * Tbis method is invoked when mouse enters the menu item while it is |
| * being dragged. |
| * |
| * @param e The MenuDragMouseEvent |
| */ |
| public void menuDragMouseEntered(MenuDragMouseEvent e) |
| { |
| MenuSelectionManager manager = MenuSelectionManager.defaultManager(); |
| manager.setSelectedPath(e.getPath()); |
| } |
| |
| /** |
| * Tbis method is invoked when mouse exits the menu item while |
| * it is being dragged |
| * |
| * @param e The MenuDragMouseEvent |
| */ |
| public void menuDragMouseExited(MenuDragMouseEvent e) |
| { |
| } |
| |
| /** |
| * Tbis method is invoked when mouse was dragged and released |
| * inside the menu item. |
| * |
| * @param e The MenuDragMouseEvent |
| */ |
| public void menuDragMouseReleased(MenuDragMouseEvent e) |
| { |
| MenuElement[] path = e.getPath(); |
| |
| if (path[path.length - 1] instanceof JMenuItem) |
| ((JMenuItem) path[path.length - 1]).doClick(); |
| |
| MenuSelectionManager manager = MenuSelectionManager.defaultManager(); |
| manager.clearSelectedPath(); |
| } |
| } |
| |
| /** |
| * This class handles key events occuring when menu item is visible on the |
| * screen. |
| */ |
| protected class MenuKeyHandler implements MenuKeyListener |
| { |
| /** |
| * This method is invoked when key has been pressed |
| * |
| * @param e A {@link MenuKeyEvent}. |
| */ |
| public void menuKeyPressed(MenuKeyEvent e) |
| { |
| } |
| |
| /** |
| * This method is invoked when key has been pressed |
| * |
| * @param e A {@link MenuKeyEvent}. |
| */ |
| public void menuKeyReleased(MenuKeyEvent e) |
| { |
| } |
| |
| /** |
| * This method is invoked when key has been typed |
| * It handles the mnemonic key for the menu item. |
| * |
| * @param e A {@link MenuKeyEvent}. |
| */ |
| public void menuKeyTyped(MenuKeyEvent e) |
| { |
| } |
| } |
| |
| /** |
| * Helper class that listens for changes to the properties of the {@link |
| * JMenuItem}. |
| */ |
| protected class PropertyChangeHandler implements PropertyChangeListener |
| { |
| /** |
| * This method is called when one of the menu item's properties change. |
| * |
| * @param evt A {@link PropertyChangeEvent}. |
| */ |
| public void propertyChange(PropertyChangeEvent evt) |
| { |
| menuItem.revalidate(); |
| menuItem.repaint(); |
| } |
| } |
| } |