1 /* BasicMenuItemUI.java --
2 Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package javax.swing.plaf.basic;
41 import java.awt.Color;
42 import java.awt.Component;
43 import java.awt.Dimension;
45 import java.awt.FontMetrics;
46 import java.awt.Graphics;
47 import java.awt.Insets;
48 import java.awt.Rectangle;
49 import java.awt.event.ActionEvent;
50 import java.awt.event.ItemEvent;
51 import java.awt.event.ItemListener;
52 import java.awt.event.KeyEvent;
53 import java.awt.event.MouseEvent;
54 import java.beans.PropertyChangeEvent;
55 import java.beans.PropertyChangeListener;
56 import java.util.ArrayList;
58 import javax.swing.AbstractAction;
59 import javax.swing.ActionMap;
60 import javax.swing.ButtonModel;
61 import javax.swing.Icon;
62 import javax.swing.InputMap;
63 import javax.swing.JCheckBoxMenuItem;
64 import javax.swing.JComponent;
65 import javax.swing.JMenu;
66 import javax.swing.JMenuItem;
67 import javax.swing.JPopupMenu;
68 import javax.swing.KeyStroke;
69 import javax.swing.LookAndFeel;
70 import javax.swing.MenuElement;
71 import javax.swing.MenuSelectionManager;
72 import javax.swing.SwingConstants;
73 import javax.swing.SwingUtilities;
74 import javax.swing.UIDefaults;
75 import javax.swing.UIManager;
76 import javax.swing.event.MenuDragMouseEvent;
77 import javax.swing.event.MenuDragMouseListener;
78 import javax.swing.event.MenuKeyEvent;
79 import javax.swing.event.MenuKeyListener;
80 import javax.swing.event.MouseInputListener;
81 import javax.swing.plaf.ActionMapUIResource;
82 import javax.swing.plaf.ComponentInputMapUIResource;
83 import javax.swing.plaf.ComponentUI;
84 import javax.swing.plaf.MenuItemUI;
87 * UI Delegate for JMenuItem.
89 public class BasicMenuItemUI extends MenuItemUI
92 * Font to be used when displaying menu item's accelerator.
94 protected Font acceleratorFont;
97 * Color to be used when displaying menu item's accelerator.
99 protected Color acceleratorForeground;
102 * Color to be used when displaying menu item's accelerator when menu item is
105 protected Color acceleratorSelectionForeground;
108 * Icon that is displayed after the text to indicated that this menu contains
111 protected Icon arrowIcon;
114 * Icon that is displayed before the text. This icon is only used in
115 * JCheckBoxMenuItem or JRadioBoxMenuItem.
117 protected Icon checkIcon;
120 * Number of spaces between icon and text.
122 protected int defaultTextIconGap = 4;
125 * Color of the text when menu item is disabled
127 protected Color disabledForeground;
130 * The menu Drag mouse listener listening to the menu item.
132 protected MenuDragMouseListener menuDragMouseListener;
135 * The menu item itself
137 protected JMenuItem menuItem;
140 * Menu Key listener listening to the menu item.
142 protected MenuKeyListener menuKeyListener;
145 * mouse input listener listening to menu item.
147 protected MouseInputListener mouseInputListener;
150 * Indicates if border should be painted
152 protected boolean oldBorderPainted;
155 * Color of text that is used when menu item is selected
157 protected Color selectionBackground;
160 * Color of the text that is used when menu item is selected.
162 protected Color selectionForeground;
165 * String that separates description of the modifiers and the key
167 private String acceleratorDelimiter;
170 * ItemListener to listen for item changes in the menu item
172 private ItemListener itemListener;
175 * Number of spaces between accelerator and menu item's label.
177 private int defaultAcceleratorLabelGap = 10;
180 * The gap between different menus on the MenuBar.
182 private int MenuGap = 10;
184 /** A PropertyChangeListener to make UI updates after property changes **/
185 PropertyChangeHandler propertyChangeListener;
188 * A class to handle PropertChangeEvents for the JMenuItem
189 * @author Anthony Balkissoon abalkiss at redhat dot com.
191 class PropertyChangeHandler implements PropertyChangeListener
194 * This method is called when a property of the menuItem is changed.
195 * Currently it is only used to update the accelerator key bindings.
198 * the PropertyChangeEvent
200 public void propertyChange(PropertyChangeEvent e)
202 if (e.getPropertyName() == "accelerator")
204 InputMap map = SwingUtilities.getUIInputMap(menuItem, JComponent.WHEN_IN_FOCUSED_WINDOW);
206 map.remove((KeyStroke)e.getOldValue());
208 map = new ComponentInputMapUIResource(menuItem);
210 KeyStroke accelerator = (KeyStroke) e.getNewValue();
211 if (accelerator != null)
212 map.put(accelerator, "doClick");
218 * A class to handle accelerator keys. This is the Action we will
219 * perform when the accelerator key for this JMenuItem is pressed.
220 * @author Anthony Balkissoon abalkiss at redhat dot com
223 class ClickAction extends AbstractAction
226 * This is what is done when the accelerator key for the JMenuItem is
229 public void actionPerformed(ActionEvent event)
231 doClick(MenuSelectionManager.defaultManager());
236 * Creates a new BasicMenuItemUI object.
238 public BasicMenuItemUI()
240 mouseInputListener = createMouseInputListener(menuItem);
241 menuDragMouseListener = createMenuDragMouseListener(menuItem);
242 menuKeyListener = createMenuKeyListener(menuItem);
243 itemListener = new ItemHandler();
244 propertyChangeListener = new PropertyChangeHandler();
248 * Create MenuDragMouseListener to listen for mouse dragged events.
251 * menu item to listen to
252 * @return The MenuDragMouseListener
254 protected MenuDragMouseListener createMenuDragMouseListener(JComponent c)
256 return new MenuDragMouseHandler();
260 * Creates MenuKeyListener to listen to key events occuring when menu item is
261 * visible on the screen.
264 * menu item to listen to
265 * @return The MenuKeyListener
267 protected MenuKeyListener createMenuKeyListener(JComponent c)
269 return new MenuKeyHandler();
273 * Handles mouse input events occuring for this menu item
276 * menu item to listen to
277 * @return The MouseInputListener
279 protected MouseInputListener createMouseInputListener(JComponent c)
281 return new MouseInputHandler();
285 * Factory method to create a BasicMenuItemUI for the given {@link
286 * JComponent}, which should be a {@link JMenuItem}.
289 * The {@link JComponent} a UI is being created for.
290 * @return A BasicMenuItemUI for the {@link JComponent}.
292 public static ComponentUI createUI(JComponent c)
294 return new BasicMenuItemUI();
298 * Programatically clicks menu item.
301 * MenuSelectionManager for the menu hierarchy
303 protected void doClick(MenuSelectionManager msm)
306 msm.clearSelectedPath();
310 * Returns maximum size for the specified menu item
313 * component for which to get maximum size
314 * @return Maximum size for the specified menu item.
316 public Dimension getMaximumSize(JComponent c)
322 * Returns minimum size for the specified menu item
325 * component for which to get minimum size
326 * @return Minimum size for the specified menu item.
328 public Dimension getMinimumSize(JComponent c)
334 * Returns path to this menu item.
336 * @return $MenuElement[]$ Returns array of menu elements that constitute a
337 * path to this menu item.
339 public MenuElement[] getPath()
341 ArrayList path = new ArrayList();
343 // Path to menu should also include its popup menu.
344 if (menuItem instanceof JMenu)
345 path.add(((JMenu) menuItem).getPopupMenu());
347 Component c = menuItem;
348 while (c instanceof MenuElement)
350 path.add(0, (MenuElement) c);
352 if (c instanceof JPopupMenu)
353 c = ((JPopupMenu) c).getInvoker();
358 MenuElement[] pathArray = new MenuElement[path.size()];
359 path.toArray(pathArray);
364 * Returns preferred size for the given menu item.
367 * menu item for which to get preferred size
369 * check icon displayed in the given menu item
371 * arrow icon displayed in the given menu item
372 * @param defaultTextIconGap
373 * space between icon and text in the given menuItem
374 * @return $Dimension$ preferred size for the given menu item
376 protected Dimension getPreferredMenuItemSize(JComponent c, Icon checkIcon,
378 int defaultTextIconGap)
380 JMenuItem m = (JMenuItem) c;
381 Dimension d = BasicGraphicsUtils.getPreferredButtonSize(m,
384 // if menu item has accelerator then take accelerator's size into account
385 // when calculating preferred size.
386 KeyStroke accelerator = m.getAccelerator();
389 if (accelerator != null)
391 rect = getAcceleratorRect(
393 m.getToolkit().getFontMetrics(acceleratorFont));
395 // add width of accelerator's text
396 d.width += rect.width + defaultAcceleratorLabelGap;
398 // adjust the heigth of the preferred size if necessary
399 if (d.height < rect.height)
400 d.height = rect.height;
403 if (checkIcon != null)
405 d.width += checkIcon.getIconWidth() + defaultTextIconGap;
407 if (checkIcon.getIconHeight() > d.height)
408 d.height = checkIcon.getIconHeight();
411 if (arrowIcon != null && (c instanceof JMenu))
413 int pWidth = m.getParent().getWidth();
414 if (!((JMenu)c).isTopLevelMenu() && d.width < pWidth)
416 - m.getInsets().left - m.getInsets().right;
418 d.width += arrowIcon.getIconWidth() + MenuGap;
420 if (arrowIcon.getIconHeight() > d.height)
421 d.height = arrowIcon.getIconHeight();
428 * Returns preferred size of the given component
431 * component for which to return preferred size
432 * @return $Dimension$ preferred size for the given component
434 public Dimension getPreferredSize(JComponent c)
436 return getPreferredMenuItemSize(c, checkIcon, arrowIcon, defaultTextIconGap);
440 * Returns the prefix for entries in the {@link UIDefaults} table.
444 protected String getPropertyPrefix()
450 * This method installs the components for this {@link JMenuItem}.
453 * The {@link JMenuItem} to install components for.
455 protected void installComponents(JMenuItem menuItem)
457 // FIXME: Need to implement
461 * This method installs the defaults that are defined in the Basic look and
462 * feel for this {@link JMenuItem}.
464 protected void installDefaults()
466 String prefix = getPropertyPrefix();
467 LookAndFeel.installBorder(menuItem, prefix + ".border");
468 LookAndFeel.installColorsAndFont(menuItem, prefix + ".background",
469 prefix + ".foreground", prefix + ".font");
470 menuItem.setMargin(UIManager.getInsets(prefix + ".margin"));
471 acceleratorFont = UIManager.getFont(prefix + ".acceleratorFont");
472 acceleratorForeground = UIManager.getColor(prefix + ".acceleratorForeground");
473 acceleratorSelectionForeground = UIManager.getColor(prefix + ".acceleratorSelectionForeground");
474 selectionBackground = UIManager.getColor(prefix + ".selectionBackground");
475 selectionForeground = UIManager.getColor(prefix + ".selectionForeground");
476 acceleratorDelimiter = UIManager.getString(prefix + ".acceleratorDelimiter");
477 checkIcon = UIManager.getIcon(prefix + ".checkIcon");
479 menuItem.setHorizontalTextPosition(SwingConstants.TRAILING);
480 menuItem.setHorizontalAlignment(SwingConstants.LEADING);
484 * This method installs the keyboard actions for this {@link JMenuItem}.
486 protected void installKeyboardActions()
488 InputMap focusedWindowMap = SwingUtilities.getUIInputMap(menuItem, JComponent.WHEN_IN_FOCUSED_WINDOW);
489 if (focusedWindowMap == null)
490 focusedWindowMap = new ComponentInputMapUIResource(menuItem);
491 KeyStroke accelerator = menuItem.getAccelerator();
492 if (accelerator != null)
493 focusedWindowMap.put(accelerator, "doClick");
494 SwingUtilities.replaceUIInputMap(menuItem, JComponent.WHEN_IN_FOCUSED_WINDOW, focusedWindowMap);
496 ActionMap UIActionMap = SwingUtilities.getUIActionMap(menuItem);
497 if (UIActionMap == null)
498 UIActionMap = new ActionMapUIResource();
499 UIActionMap.put("doClick", new ClickAction());
500 SwingUtilities.replaceUIActionMap(menuItem, UIActionMap);
504 * This method installs the listeners for the {@link JMenuItem}.
506 protected void installListeners()
508 menuItem.addMouseListener(mouseInputListener);
509 menuItem.addMouseMotionListener(mouseInputListener);
510 menuItem.addMenuDragMouseListener(menuDragMouseListener);
511 menuItem.addMenuKeyListener(menuKeyListener);
512 menuItem.addItemListener(itemListener);
513 menuItem.addPropertyChangeListener(propertyChangeListener);
517 * Installs and initializes all fields for this UI delegate. Any properties of
518 * the UI that need to be initialized and/or set to defaults will be done now.
519 * It will also install any listeners necessary.
522 * The {@link JComponent} that is having this UI installed.
524 public void installUI(JComponent c)
527 menuItem = (JMenuItem) c;
529 installComponents(menuItem);
531 installKeyboardActions();
535 * Paints given menu item using specified graphics context
538 * The graphics context used to paint this menu item
542 public void paint(Graphics g, JComponent c)
544 paintMenuItem(g, c, checkIcon, arrowIcon, c.getBackground(),
545 c.getForeground(), defaultTextIconGap);
549 * Paints background of the menu item
552 * The graphics context used to paint this menu item
556 * Background color to use when painting menu item
558 protected void paintBackground(Graphics g, JMenuItem menuItem, Color bgColor)
560 // Menu item is considered to be highlighted when it is selected.
561 // But we don't want to paint the background of JCheckBoxMenuItems
562 ButtonModel mod = menuItem.getModel();
563 if (menuItem.isContentAreaFilled())
565 if ((menuItem.isSelected() && checkIcon == null) || (mod != null &&
567 && (menuItem.getParent() instanceof MenuElement))
568 g.setColor(selectionBackground);
571 g.fillRect(0, 0, menuItem.getWidth(), menuItem.getHeight());
576 * Paints specified menu item
579 * The graphics context used to paint this menu item
583 * check icon to use when painting menu item
585 * arrow icon to use when painting menu item
587 * Background color of the menu item
589 * Foreground color of the menu item
590 * @param defaultTextIconGap
591 * space to use between icon and text when painting menu item
593 protected void paintMenuItem(Graphics g, JComponent c, Icon checkIcon,
594 Icon arrowIcon, Color background,
595 Color foreground, int defaultTextIconGap)
597 JMenuItem m = (JMenuItem) c;
598 Rectangle tr = new Rectangle(); // text rectangle
599 Rectangle ir = new Rectangle(); // icon rectangle
600 Rectangle vr = new Rectangle(); // view rectangle
601 Rectangle br = new Rectangle(); // border rectangle
602 Rectangle ar = new Rectangle(); // accelerator rectangle
603 Rectangle cr = new Rectangle(); // checkIcon rectangle
605 int vertAlign = m.getVerticalAlignment();
606 int horAlign = m.getHorizontalAlignment();
607 int vertTextPos = m.getVerticalTextPosition();
608 int horTextPos = m.getHorizontalTextPosition();
610 Font f = m.getFont();
612 FontMetrics fm = g.getFontMetrics(f);
613 SwingUtilities.calculateInnerArea(m, br);
614 SwingUtilities.calculateInsetArea(br, m.getInsets(), vr);
615 paintBackground(g, m, background);
618 * MenuItems insets are equal to menuItems margin, space between text and
619 * menuItems border. We need to paint insets region as well.
621 Insets insets = m.getInsets();
624 br.width += insets.right + insets.left;
625 br.height += insets.top + insets.bottom;
627 // If this menu item is a JCheckBoxMenuItem then paint check icon
628 if (checkIcon != null)
630 SwingUtilities.layoutCompoundLabel(m, fm, null, checkIcon, vertAlign,
631 horAlign, vertTextPos, horTextPos,
632 vr, cr, tr, defaultTextIconGap);
633 checkIcon.paintIcon(m, g, cr.x, cr.y);
634 // We need to calculate position of the menu text and position of
635 // user menu icon if there exists one relative to the check icon.
636 // So we need to adjust view rectangle s.t. its starting point is at
637 // checkIcon.width + defaultTextIconGap.
638 vr.x = cr.x + cr.width + defaultTextIconGap;
641 // if this is a submenu, then paint arrow icon to indicate it.
642 if (arrowIcon != null && (c instanceof JMenu))
644 if (!((JMenu) c).isTopLevelMenu())
646 int width = arrowIcon.getIconWidth();
647 int height = arrowIcon.getIconHeight();
648 int offset = (vr.height - height) / 2;
649 arrowIcon.paintIcon(m, g, vr.width - width, vr.y + offset);
653 // paint text and user menu icon if it exists
654 Icon i = m.getIcon();
655 SwingUtilities.layoutCompoundLabel(c, fm, m.getText(), i, vertAlign,
656 horAlign, vertTextPos, horTextPos, vr,
657 ir, tr, defaultTextIconGap);
659 i.paintIcon(c, g, ir.x, ir.y);
660 paintText(g, m, tr, m.getText());
663 String acceleratorText = "";
665 if (m.getAccelerator() != null)
667 acceleratorText = getAcceleratorText(m.getAccelerator());
668 fm = g.getFontMetrics(acceleratorFont);
669 ar.width = fm.stringWidth(acceleratorText);
670 ar.x = br.width - ar.width;
671 vr.x = br.width - ar.width - defaultTextIconGap;
673 SwingUtilities.layoutCompoundLabel(m, fm, acceleratorText, null,
674 vertAlign, horAlign, vertTextPos,
675 horTextPos, vr, ir, ar,
678 paintAccelerator(g, m, ar, acceleratorText);
683 * Paints label for the given menu item
686 * The graphics context used to paint this menu item
688 * menu item for which to draw its label
690 * rectangle specifiying position of the text relative to the given
693 * label of the menu item
695 protected void paintText(Graphics g, JMenuItem menuItem, Rectangle textRect,
698 Font f = menuItem.getFont();
700 FontMetrics fm = g.getFontMetrics(f);
702 if (text != null && !text.equals(""))
704 if (menuItem.isEnabled())
706 // Menu item is considered to be highlighted when it is selected.
707 // But not if it's a JCheckBoxMenuItem
708 ButtonModel mod = menuItem.getModel();
709 if ((menuItem.isSelected() && checkIcon == null)
710 || (mod != null && mod.isArmed())
711 && (menuItem.getParent() instanceof MenuElement))
712 g.setColor(selectionForeground);
714 g.setColor(menuItem.getForeground());
717 // FIXME: should fix this to use 'disabledForeground', but its
718 // default value in BasicLookAndFeel is null.
720 // FIXME: should there be different foreground colours for selected
721 // or deselected, when disabled?
722 g.setColor(Color.gray);
724 int mnemonicIndex = menuItem.getDisplayedMnemonicIndex();
726 if (mnemonicIndex != -1)
727 BasicGraphicsUtils.drawStringUnderlineCharAt(g, text, mnemonicIndex,
732 BasicGraphicsUtils.drawString(g, text, 0, textRect.x,
733 textRect.y + fm.getAscent());
738 * This method uninstalls the components for this {@link JMenuItem}.
741 * The {@link JMenuItem} to uninstall components for.
743 protected void uninstallComponents(JMenuItem menuItem)
745 // FIXME: need to implement
749 * This method uninstalls the defaults and sets any objects created during
752 protected void uninstallDefaults()
754 menuItem.setForeground(null);
755 menuItem.setBackground(null);
756 menuItem.setBorder(null);
757 menuItem.setMargin(null);
758 menuItem.setBackground(null);
759 menuItem.setBorder(null);
760 menuItem.setFont(null);
761 menuItem.setForeground(null);
762 menuItem.setMargin(null);
763 acceleratorFont = null;
764 acceleratorForeground = null;
765 acceleratorSelectionForeground = null;
767 selectionBackground = null;
768 selectionForeground = null;
769 acceleratorDelimiter = null;
773 * Uninstalls any keyboard actions.
775 protected void uninstallKeyboardActions()
777 SwingUtilities.replaceUIInputMap(menuItem,
778 JComponent.WHEN_IN_FOCUSED_WINDOW, null);
782 * Unregisters all the listeners that this UI delegate was using.
784 protected void uninstallListeners()
786 menuItem.removeMouseListener(mouseInputListener);
787 menuItem.removeMenuDragMouseListener(menuDragMouseListener);
788 menuItem.removeMenuKeyListener(menuKeyListener);
789 menuItem.removeItemListener(itemListener);
790 menuItem.removePropertyChangeListener(propertyChangeListener);
794 * Performs the opposite of installUI. Any properties or resources that need
795 * to be cleaned up will be done now. It will also uninstall any listeners it
796 * has. In addition, any properties of this UI will be nulled.
799 * The {@link JComponent} that is having this UI uninstalled.
801 public void uninstallUI(JComponent c)
803 uninstallListeners();
805 uninstallComponents(menuItem);
810 * This method calls paint.
813 * The graphics context used to paint this menu item
815 * The menu item to paint
817 public void update(Graphics g, JComponent c)
823 * Return text representation of the specified accelerator
826 * Accelerator for which to return string representation
827 * @return $String$ Text representation of the given accelerator
829 private String getAcceleratorText(KeyStroke accelerator)
831 // convert keystroke into string format
832 String modifiersText = "";
833 int modifiers = accelerator.getModifiers();
834 char keyChar = accelerator.getKeyChar();
835 int keyCode = accelerator.getKeyCode();
838 modifiersText = KeyEvent.getKeyModifiersText(modifiers)
839 + acceleratorDelimiter;
841 if (keyCode == KeyEvent.VK_UNDEFINED)
842 return modifiersText + keyChar;
844 return modifiersText + KeyEvent.getKeyText(keyCode);
848 * Calculates and return rectange in which accelerator should be displayed
851 * accelerator for which to return the display rectangle
853 * The font metrics used to measure the text
854 * @return $Rectangle$ reactangle which will be used to display accelerator
856 private Rectangle getAcceleratorRect(KeyStroke accelerator, FontMetrics fm)
858 int width = fm.stringWidth(getAcceleratorText(accelerator));
859 int height = fm.getHeight();
860 return new Rectangle(0, 0, width, height);
864 * Paints accelerator inside menu item
867 * The graphics context used to paint the border
869 * Menu item for which to draw accelerator
870 * @param acceleratorRect
871 * rectangle representing position of the accelerator relative to the
873 * @param acceleratorText
876 private void paintAccelerator(Graphics g, JMenuItem menuItem,
877 Rectangle acceleratorRect,
878 String acceleratorText)
880 g.setFont(acceleratorFont);
881 FontMetrics fm = g.getFontMetrics(acceleratorFont);
883 if (menuItem.isEnabled())
884 g.setColor(acceleratorForeground);
886 // FIXME: should fix this to use 'disabledForeground', but its
887 // default value in BasicLookAndFeel is null.
888 g.setColor(Color.gray);
890 BasicGraphicsUtils.drawString(g, acceleratorText, 0, acceleratorRect.x,
891 acceleratorRect.y + fm.getAscent());
895 * This class handles mouse events occuring inside the menu item. Most of the
896 * events are forwarded for processing to MenuSelectionManager of the current
899 protected class MouseInputHandler implements MouseInputListener
902 * Creates a new MouseInputHandler object.
904 protected MouseInputHandler()
906 // Nothing to do here.
910 * This method is called when mouse is clicked on the menu item. It forwards
911 * this event to MenuSelectionManager.
914 * A {@link MouseEvent}.
916 public void mouseClicked(MouseEvent e)
918 MenuSelectionManager manager = MenuSelectionManager.defaultManager();
919 manager.processMouseEvent(e);
923 * This method is called when mouse is dragged inside the menu item. It
924 * forwards this event to MenuSelectionManager.
927 * A {@link MouseEvent}.
929 public void mouseDragged(MouseEvent e)
931 MenuSelectionManager manager = MenuSelectionManager.defaultManager();
932 manager.processMouseEvent(e);
936 * This method is called when mouse enters menu item. When this happens menu
937 * item is considered to be selected and selection path in
938 * MenuSelectionManager is set. This event is also forwarded to
939 * MenuSelection Manager for further processing.
942 * A {@link MouseEvent}.
944 public void mouseEntered(MouseEvent e)
946 Component source = (Component) e.getSource();
947 if (source.getParent() instanceof MenuElement)
949 MenuSelectionManager manager = MenuSelectionManager.defaultManager();
950 manager.setSelectedPath(getPath());
951 manager.processMouseEvent(e);
956 * This method is called when mouse exits menu item. The event is forwarded
957 * to MenuSelectionManager for processing.
960 * A {@link MouseEvent}.
962 public void mouseExited(MouseEvent e)
964 MenuSelectionManager manager = MenuSelectionManager.defaultManager();
965 manager.processMouseEvent(e);
969 * This method is called when mouse is inside the menu item. This event is
970 * forwarder to MenuSelectionManager for further processing.
973 * A {@link MouseEvent}.
975 public void mouseMoved(MouseEvent e)
977 MenuSelectionManager manager = MenuSelectionManager.defaultManager();
978 manager.processMouseEvent(e);
982 * This method is called when mouse is pressed. This event is forwarded to
983 * MenuSelectionManager for further processing.
986 * A {@link MouseEvent}.
988 public void mousePressed(MouseEvent e)
990 MenuSelectionManager manager = MenuSelectionManager.defaultManager();
991 manager.processMouseEvent(e);
995 * This method is called when mouse is released. If the mouse is released
996 * inside this menuItem, then this menu item is considered to be chosen and
997 * the menu hierarchy should be closed.
1000 * A {@link MouseEvent}.
1002 public void mouseReleased(MouseEvent e)
1004 Rectangle size = menuItem.getBounds();
1005 MenuSelectionManager manager = MenuSelectionManager.defaultManager();
1006 if (e.getX() > 0 && e.getX() < size.width && e.getY() > 0
1007 && e.getY() < size.height)
1009 manager.clearSelectedPath();
1014 manager.processMouseEvent(e);
1019 * This class handles mouse dragged events.
1021 private class MenuDragMouseHandler implements MenuDragMouseListener
1024 * Tbis method is invoked when mouse is dragged over the menu item.
1027 * The MenuDragMouseEvent
1029 public void menuDragMouseDragged(MenuDragMouseEvent e)
1031 MenuSelectionManager manager = MenuSelectionManager.defaultManager();
1032 manager.setSelectedPath(e.getPath());
1036 * Tbis method is invoked when mouse enters the menu item while it is being
1040 * The MenuDragMouseEvent
1042 public void menuDragMouseEntered(MenuDragMouseEvent e)
1044 MenuSelectionManager manager = MenuSelectionManager.defaultManager();
1045 manager.setSelectedPath(e.getPath());
1049 * Tbis method is invoked when mouse exits the menu item while it is being
1052 * @param e the MenuDragMouseEvent
1054 public void menuDragMouseExited(MenuDragMouseEvent e)
1056 // TODO: What should be done here, if anything?
1060 * Tbis method is invoked when mouse was dragged and released inside the
1064 * The MenuDragMouseEvent
1066 public void menuDragMouseReleased(MenuDragMouseEvent e)
1068 MenuElement[] path = e.getPath();
1070 if (path[path.length - 1] instanceof JMenuItem)
1071 ((JMenuItem) path[path.length - 1]).doClick();
1073 MenuSelectionManager manager = MenuSelectionManager.defaultManager();
1074 manager.clearSelectedPath();
1079 * This class handles key events occuring when menu item is visible on the
1082 private class MenuKeyHandler implements MenuKeyListener
1085 * This method is invoked when key has been pressed
1088 * A {@link MenuKeyEvent}.
1090 public void menuKeyPressed(MenuKeyEvent e)
1092 // TODO: What should be done here, if anything?
1096 * This method is invoked when key has been pressed
1099 * A {@link MenuKeyEvent}.
1101 public void menuKeyReleased(MenuKeyEvent e)
1103 // TODO: What should be done here, if anything?
1107 * This method is invoked when key has been typed It handles the mnemonic
1108 * key for the menu item.
1111 * A {@link MenuKeyEvent}.
1113 public void menuKeyTyped(MenuKeyEvent e)
1115 // TODO: What should be done here, if anything?
1120 * Helper class that listens for item changes to the properties of the {@link
1123 private class ItemHandler implements ItemListener
1126 * This method is called when one of the menu item changes.
1128 * @param evt A {@link ItemEvent}.
1130 public void itemStateChanged(ItemEvent evt)
1132 boolean state = false;
1133 if (menuItem instanceof JCheckBoxMenuItem)
1135 if (evt.getStateChange() == ItemEvent.SELECTED)
1137 ((JCheckBoxMenuItem) menuItem).setState(state);
1139 menuItem.revalidate();