home *** CD-ROM | disk | FTP | other *** search
/ Java 1.2 How-To / JavaHowTo.iso / 3rdParty / jbuilder / unsupported / JDK1.2beta3 / SOURCE / SRC.ZIP / java / awt / swing / JMenuItem.java < prev    next >
Encoding:
Java Source  |  1998-03-20  |  12.4 KB  |  392 lines

  1. /*
  2.  * @(#)JMenuItem.java    1.51 98/02/10
  3.  * 
  4.  * Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
  5.  * 
  6.  * This software is the confidential and proprietary information of Sun
  7.  * Microsystems, Inc. ("Confidential Information").  You shall not
  8.  * disclose such Confidential Information and shall use it only in
  9.  * accordance with the terms of the license agreement you entered into
  10.  * with Sun.
  11.  * 
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
  13.  * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  14.  * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  15.  * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
  16.  * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
  17.  * THIS SOFTWARE OR ITS DERIVATIVES.
  18.  * 
  19.  */
  20. package java.awt.swing;
  21.  
  22. import java.util.EventListener;
  23. import java.awt.*;
  24. import java.awt.event.*;
  25. import java.awt.image.*;
  26. import java.io.Serializable;
  27. import java.awt.swing.plaf.*;
  28. import java.awt.swing.event.*;
  29. import java.awt.accessibility.*;
  30.  
  31. /**
  32.  * An implementation of a MenuItem. A menu item is essentially a button
  33.  * sitting in a list. When the user selects the "button", the action
  34.  * associated with the menu item is performed. A JMenuItem contained
  35.  * in a JPopupMenu performs exactly that function.
  36.  * <p>
  37.  * Warning: serialized objects of this class will not be compatible with
  38.  * future swing releases.  The current serialization support is appropriate 
  39.  * for short term storage or RMI between Swing1.0 applications.  It will
  40.  * not be possible to load serialized Swing1.0 objects with future releases
  41.  * of Swing.  The JDK1.2 release of Swing will be the compatibility
  42.  * baseline for the serialized form of Swing objects.
  43.  *
  44.  * @version 1.51 02/10/98
  45.  * @author Georges Saab
  46.  * @author David Karlton
  47.  * @see JPopupMenu
  48.  * @see JMenu
  49.  * @see JCheckBoxMenuItem
  50.  * @see JRadioButtonMenuItem
  51.  */
  52. public class JMenuItem extends AbstractButton implements Accessible,MenuElement  {
  53.  
  54.     /**
  55.      * Creates a menuItem with no set text or icon.
  56.      */
  57.     public JMenuItem() {
  58.         this(null, (Icon)null);
  59.         setRequestFocusEnabled(false);
  60.     }
  61.  
  62.     /**
  63.      * Creates a menuItem with an icon.
  64.      *
  65.      * @param icon the icon of the MenuItem.
  66.      */
  67.     public JMenuItem(Icon icon) {
  68.         this(null, icon);
  69.         setRequestFocusEnabled(false);
  70.     }
  71.  
  72.     /**
  73.      * Creates a menuItem with text.
  74.      *
  75.      * @param text the text of the MenuItem.
  76.      */
  77.     public JMenuItem(String text) {
  78.         this(text, (Icon)null);
  79.     }
  80.     
  81.     /**
  82.      * Creates a menuItem with the supplied text and icon.
  83.      *
  84.      * @param text the text of the MenuItem.
  85.      * @param icon the icon of the MenuItem.
  86.      */
  87.     public JMenuItem(String text, Icon icon) {
  88.         setModel(new DefaultButtonModel());
  89.         init(text, icon);
  90.         setBorderPainted(false);
  91.         setFocusPainted(false);
  92.         setHorizontalTextPosition(JButton.LEFT);
  93.         setHorizontalAlignment(JButton.LEFT);
  94.         updateUI();
  95.     }
  96.  
  97.     /**
  98.      * Creates a menuItem with the specified text and
  99.      * keyboard mnemonic.
  100.      *
  101.      * @param text the text of the MenuItem.
  102.      * @param mnemonic the keyboard mnemonic for the MenuItem
  103.      */
  104.     public JMenuItem(String text, int mnemonic) {
  105.         setModel(new DefaultButtonModel());
  106.         init(text, null);
  107.         setBorderPainted(false);
  108.         setFocusPainted(false);
  109.         setHorizontalTextPosition(JButton.LEFT);
  110.         setHorizontalAlignment(JButton.LEFT);
  111.         setMnemonic(mnemonic);
  112.         updateUI();
  113.     }
  114.  
  115.     /**
  116.      * Initialize the menu item with the specified text and icon.
  117.      *
  118.      * @param text the text of the MenuItem.
  119.      * @param icon the icon of the MenuItem.
  120.      */
  121.     protected void init(String text, Icon icon) {
  122.         setLayout(new OverlayLayout(this));
  123.  
  124.         if(text != null) {
  125.             setText(text);
  126.         }
  127.         
  128.         if(icon != null) {
  129.             setIcon(icon);
  130.         }
  131.         
  132.         // Listen for Focus events
  133.         addFocusListener(new MenuItemFocusListener());
  134.     }
  135.  
  136.     private static class MenuItemFocusListener implements FocusListener,
  137.     Serializable {
  138.     public void focusGained(FocusEvent event) {}
  139.     public void focusLost(FocusEvent event) {
  140.         // When focus is lost, repaint if 
  141.         // the focus information is painted
  142.         JMenuItem mi = (JMenuItem)event.getSource();
  143.         if(mi.isFocusPainted()) {
  144.         mi.repaint();
  145.         }
  146.     }
  147.     }
  148.     
  149.     
  150.     /**
  151.      * Sets the L&F object that renders this component.
  152.      *
  153.      * @param ui  the MenuItemUI L&F object
  154.      * @see UIDefaults#getUI
  155.      * @beaninfo
  156.      * description: The menu item's UI delegate
  157.      *       bound: true
  158.      *      expert: true
  159.      *      hidden: true
  160.      */
  161.     public void setUI(MenuItemUI ui) {
  162.         super.setUI(ui);
  163.     }
  164.     
  165.     /**
  166.      * Notification from the UIFactory that the L&F has changed. 
  167.      * Called to replace the UI with the latest version from the 
  168.      * UIFactory.
  169.      *
  170.      * @see JComponent#updateUI
  171.      */
  172.     public void updateUI() {
  173.         setUI((MenuItemUI)UIManager.getUI(this));
  174.     }
  175.  
  176.  
  177.     /**
  178.      * Returns the name of the L&F class that renders this component.
  179.      *
  180.      * @return "MenuItemUI"
  181.      * @see JComponent#getUIClassID
  182.      * @see UIDefaults#getUI
  183.      */
  184.     public String getUIClassID() {
  185.         return "MenuItemUI";
  186.     }
  187.  
  188.  
  189.     /**
  190.      * Identifies the menu item as "armed". If the mouse button is
  191.      * released while it is over this item, the menu's action event
  192.      * will fire. If the mouse button is released elsewhere, the
  193.      * event will not fire and the menu item will be disarmed.
  194.      * 
  195.      * @param b true to arm the menu item so it can be selected
  196.      * @beaninfo
  197.      *    description: Mouse release will fire an action event
  198.      *         hidden: true
  199.      */
  200.     public void setArmed(boolean b) {
  201.         ButtonModel model = (ButtonModel) getModel();
  202.  
  203.         boolean oldValue = model.isArmed();
  204.         if ((accessibleContext != null) && (oldValue != b)) {
  205.             if (b) {
  206.                 accessibleContext.firePropertyChange(
  207.                 AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
  208.             null, 
  209.             AccessibleState.ARMED);
  210.             } else {
  211.                 accessibleContext.firePropertyChange(
  212.                         AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
  213.             AccessibleState.ARMED, 
  214.             null);
  215.             }
  216.         }
  217.         if(model.isArmed() != b) {
  218.             model.setArmed(b);
  219.         }
  220.     }
  221.  
  222.     /**
  223.      * Returns whether the menu item is "armed".
  224.      * 
  225.      * @return true if the menu item is armed, and it can be selected
  226.      * @see #setArmed
  227.      */
  228.     public boolean isArmed() {
  229.         ButtonModel model = (ButtonModel) getModel();
  230.         return model.isArmed();
  231.     }
  232.  
  233.     /**
  234.      * Enable or disable the menu item.
  235.      *
  236.      * @param b  true to enable the item
  237.      * @beaninfo
  238.      *    description: Does the component react to user interaction
  239.      *          bound: true
  240.      *      preferred: true
  241.      */
  242.     public void setEnabled(boolean b) {
  243.         // Make sure we aren't armed!
  244.         if (b == false)
  245.             setArmed(false);
  246.         super.setEnabled(b);
  247.     }
  248.  
  249.     /* The keystroke which acts as the menu item's accelerator
  250.      */
  251.     private KeyStroke accelerator;
  252.  
  253.     /* Set the key combination which invokes the Menu Item's
  254.      * action listeners without navigating the menu hierarchy.
  255.      *
  256.      * @param keyStroke the KeyStroke which will serve as an accelerator
  257.      * @beaninfo
  258.      *     description: The keystroke combination which will invoke the JMenuItem's
  259.      *                  actionlisteners without navigating the menu hierarchy
  260.      *           bound: true
  261.      *       preferred: true
  262.      */
  263.     public void setAccelerator(KeyStroke keyStroke) {
  264.     if (accelerator != null)
  265.         unregisterKeyboardAction(accelerator);
  266.  
  267.     // PENDING(ges) change this to a (lighter) ActionListener which implements
  268.     // Serializable
  269.     registerKeyboardAction(new AbstractAction(){
  270.         public void actionPerformed(ActionEvent e) {
  271.         MenuSelectionManager.defaultManager().clearSelectedPath();
  272.         doClick();
  273.         }
  274.     } , keyStroke, WHEN_IN_FOCUSED_WINDOW);
  275.     this.accelerator = keyStroke;
  276.     }
  277.  
  278.     /* Returns the KeyStroke which serves as an accelerator 
  279.      * for the menu item.
  280.      */
  281.     public KeyStroke getAccelerator() {
  282.     return this.accelerator;
  283.     }
  284.  
  285.     /**
  286.      * Process a mouse event. event is a MouseEvent with source being the receiving component.
  287.      * componentPath is the path of the receiving MenuElement in the menu
  288.      * hierarchy. manager is the MenuSelectionManager for the menu hierarchy.
  289.      * This method should process the MouseEvent and change the menu selection if necessary
  290.      * by using MenuSelectionManager's API.
  291.      * <p>
  292.      * Note: you do not have to forward the event to sub-components. This is done automatically
  293.      * by the MenuSelectionManager
  294.      */
  295.     public void processMouseEvent(MouseEvent event,MenuElement path[],MenuSelectionManager manager) {
  296.         ((MenuItemUI)getUI()).processMouseEvent(this,event,path,manager);
  297.     }
  298.  
  299.     /** Implemented to be a MenuElement. This message is forwarded to the UI **/
  300.     public void processKeyEvent(KeyEvent e,MenuElement path[],MenuSelectionManager manager) {
  301.         ((MenuItemUI)getUI()).processKeyEvent(this,e,path,manager);
  302.     }
  303.  
  304.     /**
  305.      * Called by the MenuSelectionManager when the MenuElement is selected
  306.      * or unselected.
  307.      * 
  308.      * @param isIncluded  true if this menu item is on the part of the menu
  309.      *                    path that changed, false if this menu is part of the
  310.      *                    a menu path that changed, but this particular part of
  311.      *                    that path is still the same
  312.      * @see MenuSelectionManager#setSelectedPath(MenuElement[])
  313.      */
  314.     public void menuSelectionChanged(boolean isIncluded) {
  315.         setArmed(isIncluded);
  316.     }
  317.  
  318.     /**
  319.      * This method returns an array containing the sub-menu components for this menu component.
  320.      *
  321.      * @return an array of MenuElements
  322.      */
  323.     public MenuElement[] getSubElements() {
  324.         return new MenuElement[0];
  325.     }
  326.     
  327.     /**
  328.      * This method returns the java.awt.Component used to paint this object.
  329.      * The returned component will be used to convert events and detect if an event is inside
  330.      * a menu component.
  331.      *
  332.      * @return the Component that paints this menu item
  333.      */
  334.     public Component getComponent() {
  335.         return this;
  336.     }
  337.  
  338. /////////////////
  339. // Accessibility support
  340. ////////////////
  341.  
  342.     /**
  343.      * Get the AccessibleContext associated with this JComponent
  344.      *
  345.      * @return the AccessibleContext of this JComponent
  346.      */
  347.     public AccessibleContext getAccessibleContext() {
  348.         if (accessibleContext == null) {
  349.             accessibleContext = new AccessibleJMenuItem();
  350.         }
  351.         return accessibleContext;
  352.     }
  353.  
  354.  
  355.     /**
  356.      * The class used to obtain the accessible role for this object.
  357.      * <p>
  358.      * Warning: serialized objects of this class will not be compatible with
  359.      * future swing releases.  The current serialization support is appropriate
  360.      * for short term storage or RMI between Swing1.0 applications.  It will
  361.      * not be possible to load serialized Swing1.0 objects with future releases
  362.      * of Swing.  The JDK1.2 release of Swing will be the compatibility
  363.      * baseline for the serialized form of Swing objects.
  364.      */
  365.     protected class AccessibleJMenuItem extends AccessibleAbstractButton implements ChangeListener {
  366.  
  367.         AccessibleJMenuItem() {
  368.             super();
  369.             JMenuItem.this.addChangeListener(this);
  370.         }
  371.  
  372.         /**
  373.          * Get the role of this object.
  374.          *
  375.          * @return an instance of AccessibleRole describing the role of the 
  376.          * object
  377.          */
  378.         public AccessibleRole getAccessibleRole() {
  379.             return AccessibleRole.MENU_ITEM;
  380.         }
  381.  
  382.         /**
  383.          * Supports the change listener interface and fires property change
  384.          */
  385.         public void stateChanged(ChangeEvent e) {
  386.             firePropertyChange(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY, 
  387.                    new Boolean(false), new Boolean(true));
  388.         }
  389.     } // inner class AccessibleJMenuItem
  390. }
  391.  
  392.