home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 November / Chip_1998-11_cd.bin / tema / Cafe / main.bin / MenuItem.java < prev    next >
Text File  |  1997-10-01  |  16KB  |  487 lines

  1. /*
  2.  * @(#)MenuItem.java    1.45 97/08/15
  3.  * 
  4.  * Copyright (c) 1995, 1996 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.  * CopyrightVersion 1.1_beta
  20.  * 
  21.  */
  22. package java.awt;
  23.  
  24. import java.awt.peer.MenuItemPeer;
  25. import java.awt.event.*;
  26. import java.io.ObjectOutputStream;
  27. import java.io.ObjectInputStream;
  28. import java.io.IOException;
  29.  
  30.  
  31. /**
  32.  * All items in a menu must belong to the class 
  33.  * <code>MenuItem</code>, or one of its subclasses.
  34.  * <p>
  35.  * The default <code>MenuItem</code> object embodies
  36.  * a simple labeled menu item. 
  37.  * <p>
  38.  * This picture of a menu bar shows five menu items:
  39.  * <IMG SRC="images-awt/MenuBar-1.gif" 
  40.  * ALIGN=CENTER HSPACE=10 VSPACE=7> 
  41.  * <br CLEAR=LEFT>
  42.  * The first two items are simple menu items, labeled 
  43.  * <code>"Basic"</code> and <code>"Simple"</code>. 
  44.  * Following these two items is a separator, which is itself
  45.  * a menu item, created with the label <code>"-"</code>. 
  46.  * Next is an instance of <code>CheckboxMenuItem</code> 
  47.  * labeled <code>"Check"</code>. The final menu item is a 
  48.  * submenu labeled <code>"More Examples"</code>, 
  49.  * and this submenu is an instance of <code>Menu</code>. 
  50.  * <p>
  51.  * When a menu item is selected, AWT sends an action event to 
  52.  * the menu item. Since the event is an
  53.  * instance of <code>ActionEvent</code>, the <code>processEvent</code> 
  54.  * method examines the event and passes it along to 
  55.  * <code>processActionEvent</code>. The latter method redirects the
  56.  * event to any <code>ActionListener</code> objects that have
  57.  * registered an interest in action events generated by this
  58.  * menu item. 
  59.  * <P> 
  60.  * Note that the subclass <code>Menu</code> overrides this behavior and 
  61.  * does not send any event to the frame until one of its subitems is 
  62.  * selected. 
  63.  *
  64.  * @version 1.45, 08/15/97
  65.  * @author Sami Shaio
  66.  */
  67. public class MenuItem extends MenuComponent {
  68.     boolean enabled = true;
  69.     String label;
  70.     String actionCommand;
  71.  
  72.     // The eventMask is ONLY set by subclasses via enableEvents.
  73.     // The mask should NOT be set when listeners are registered
  74.     // so that we can distinguish the difference between when
  75.     // listeners request events and subclasses request them.
  76.     long eventMask;
  77.  
  78.     transient ActionListener actionListener;
  79.  
  80.     private MenuShortcut shortcut = null;
  81.  
  82.     private static final String base = "menuitem";
  83.     private static int nameCounter = 0;
  84.  
  85.     /*
  86.      * JDK 1.1 serialVersionUID 
  87.      */
  88.     private static final long serialVersionUID = -21757335363267194L;
  89.  
  90.     /** 
  91.      * Constructs a new MenuItem with an empty label and no keyboard
  92.      * shortcut.
  93.      * @since    JDK1.1
  94.      */
  95.     public MenuItem() {
  96.     this("", null);
  97.     }
  98.  
  99.     /** 
  100.      * Constructs a new MenuItem with the specified label 
  101.      * and no keyboard shortcut. Note that use of "-" in
  102.      * a label is reserved to indicate a separator between 
  103.      * menu items. By default, all menu items except for 
  104.      * separators are enabled. 
  105.      * @param       label the label for this menu item. 
  106.      * @since       JDK1.0
  107.      */
  108.     public MenuItem(String label) {
  109.     this(label, null);
  110.     }
  111.  
  112.     /**
  113.      * Create a menu item with an associated keyboard shortcut. 
  114.      * Note that use of "-" in a label is reserved to indicate 
  115.      * a separator between menu items. By default, all menu 
  116.      * items except for separators are enabled. 
  117.      * @param       label the label for this menu item. 
  118.      * @param       s the instance of <code>MenuShortcut</code> 
  119.      *                       associated with this menu item. 
  120.      * @since       JDK1.1
  121.      */
  122.     public MenuItem(String label, MenuShortcut s) {
  123.         this.name = base + nameCounter++;
  124.     this.label = label;
  125.         this.shortcut = s;
  126.     }
  127.  
  128.     /**
  129.      * Creates the menu item's peer.  The peer allows us to modify the 
  130.      * appearance of the menu item without changing its functionality.
  131.      */
  132.     public void addNotify() {
  133.     if (peer == null) {
  134.         peer = Toolkit.getDefaultToolkit().createMenuItem(this);
  135.     }
  136.     }
  137.  
  138.     /**
  139.      * Gets the label for this menu item.
  140.      * @return  the label of this menu item, or <code>null</code> 
  141.                        if this menu item has no label.
  142.      * @see     java.awt.MenuItem#setLabel
  143.      * @since   JDK1.0
  144.      */
  145.     public String getLabel() {
  146.     return label;
  147.     }
  148.  
  149.     /**
  150.      * Sets the label for this menu item to the specified label.
  151.      * @param     label   the new label, or <code>null</code> for no label.
  152.      * @see       java.awt.MenuItem#getLabel
  153.      * @since     JDK1.0
  154.      */
  155.     public synchronized void setLabel(String label) {
  156.     this.label = label;
  157.     MenuItemPeer peer = (MenuItemPeer)this.peer;
  158.     if (peer != null) {
  159.         peer.setLabel(label);
  160.     }
  161.     }
  162.  
  163.     /**
  164.      * Checks whether this menu item is enabled.
  165.      * @see        java.awt.MenuItem#setEnabled
  166.      * @since      JDK1.0
  167.      */
  168.     public boolean isEnabled() {
  169.     return enabled;
  170.     }
  171.  
  172.     /**
  173.      * Sets whether or not this menu item can be chosen.
  174.      * @param      b  if <code>true</code>, enables this menu item; 
  175.      *                       if <code>false</code>, disables it.
  176.      * @see        java.awt.MenuItem#isEnabled
  177.      * @since      JDK1.1
  178.      */
  179.     public synchronized void setEnabled(boolean b) {
  180.         enable(b);
  181.     }
  182.  
  183.     /**
  184.      * @deprecated As of JDK version 1.1,
  185.      * replaced by <code>setEnabled(boolean)</code>.
  186.      */
  187.     public synchronized void enable() {
  188.     enabled = true;
  189.     MenuItemPeer peer = (MenuItemPeer)this.peer;
  190.     if (peer != null) {
  191.         peer.enable();
  192.     }
  193.     }
  194.  
  195.     /**
  196.      * @deprecated As of JDK version 1.1,
  197.      * replaced by <code>setEnabled(boolean)</code>.
  198.      */
  199.     public void enable(boolean b) {
  200.         if (b) {
  201.         enable();
  202.     } else {
  203.         disable();
  204.     }
  205.     }
  206.  
  207.     /**
  208.      * @deprecated As of JDK version 1.1,
  209.      * replaced by <code>setEnabled(boolean)</code>.
  210.      */
  211.     public synchronized void disable() {
  212.     enabled = false;
  213.     MenuItemPeer peer = (MenuItemPeer)this.peer;
  214.     if (peer != null) {
  215.         peer.disable();
  216.     }
  217.     }
  218.  
  219.     /**
  220.      * Get the <code>MenuShortcut</code> object associated with this
  221.      * menu item, 
  222.      * @return      the menu shortcut associated with this menu item,
  223.      *                   or <code>null</code> if none has been specified.
  224.      * @see         java.awt.MenuItem#setShortcut
  225.      * @since       JDK1.1
  226.      */
  227.     public MenuShortcut getShortcut() {
  228.         return shortcut;
  229.     }
  230.  
  231.     /** 
  232.      * Set the <code>MenuShortcut</code> object associated with this
  233.      * menu item. If a menu shortcut is already associated with 
  234.      * this menu item, it is replaced.
  235.      * @param       s  the menu shortcut to associate 
  236.      *                           with this menu item.
  237.      * @see         java.awt.MenuItem#getShortcut
  238.      * @since       JDK1.1
  239.      */
  240.     public void setShortcut(MenuShortcut s) {
  241.         shortcut = s;
  242.     MenuItemPeer peer = (MenuItemPeer)this.peer;
  243.     if (peer != null) {
  244.         peer.setLabel(label);
  245.     }
  246.     }
  247.  
  248.     /**
  249.      * Delete any <code>MenuShortcut</code> object associated 
  250.      * with this menu item.
  251.      * @since      JDK1.1
  252.      */
  253.     public void deleteShortcut() {
  254.         shortcut = null;
  255.     MenuItemPeer peer = (MenuItemPeer)this.peer;
  256.     if (peer != null) {
  257.         peer.setLabel(label);
  258.     }
  259.     }
  260.  
  261.     /*
  262.      * Delete a matching MenuShortcut associated with this MenuItem.
  263.      * Used when iterating Menus.
  264.      */
  265.     void deleteShortcut(MenuShortcut s) {
  266.         if (s.equals(shortcut)) {
  267.             shortcut = null;
  268.             MenuItemPeer peer = (MenuItemPeer)this.peer;
  269.             if (peer != null) {
  270.                 peer.setLabel(label);
  271.             }
  272.         }
  273.     }
  274.  
  275.     /*
  276.      * Post an ActionEvent to the target (on 
  277.      * keydown).  Returns true if there is an associated 
  278.      * shortcut.
  279.      */
  280.     boolean handleShortcut(KeyEvent e) {
  281.         MenuShortcut s = new MenuShortcut(e.getKeyCode(), 
  282.                              (e.getModifiers() & InputEvent.SHIFT_MASK) > 0);
  283.         if (s.equals(shortcut) && enabled) {
  284.             // MenuShortcut match -- issue an event on keydown.
  285.             if (e.getID() == KeyEvent.KEY_PRESSED) {
  286.                 Toolkit.getEventQueue().postEvent(
  287.                           new ActionEvent(this, ActionEvent.ACTION_PERFORMED, 
  288.                                           actionCommand));
  289.             } else {
  290.                 // silently eat key release.
  291.             }
  292.             return true;
  293.     }
  294.         return false;
  295.     }
  296.  
  297.     MenuItem getShortcutMenuItem(MenuShortcut s) {
  298.         return (s.equals(shortcut)) ? this : null;
  299.     }
  300.  
  301.     /**
  302.      * Enables event delivery to this menu item for events 
  303.      * to be defined by the specified event mask parameter
  304.      * <p>
  305.      * Since event types are automatically enabled when a listener for 
  306.      * that type is added to the menu item, this method only needs 
  307.      * to be invoked by subclasses of <code>MenuItem</code> which desire to 
  308.      * have the specified event types delivered to <code>processEvent</code> 
  309.      * regardless of whether a listener is registered. 
  310.      * @param       eventsToEnable the event mask defining the event types.
  311.      * @see         java.awt.MenuItem#processEvent
  312.      * @see         java.awt.MenuItem#disableEvents
  313.      * @see         java.awt.Component#enableEvents
  314.      * @since       JDK1.1
  315.      */
  316.     protected final void enableEvents(long eventsToEnable) {
  317.         eventMask |= eventsToEnable;
  318.     }
  319.  
  320.     /**
  321.      * Disables event delivery to this menu item for events 
  322.      * defined by the specified event mask parameter.
  323.      * @param       eventsToDisable the event mask defining the event types.
  324.      * @see         java.awt.MenuItem#processEvent
  325.      * @see         java.awt.MenuItem#enableEvents
  326.      * @see         java.awt.Component#disableEvents
  327.      * @since       JDK1.1
  328.      */
  329.     protected final void disableEvents(long eventsToDisable) {
  330.         eventMask &= ~eventsToDisable;  
  331.     }  
  332.  
  333.     /**
  334.      * Sets the command name of the action event that is fired 
  335.      * by this menu item.
  336.      * <p>
  337.      * By default, the action command is set to the label of 
  338.      * the menu item.
  339.      * @param       command   the action command to be set 
  340.      *                                for this menu item.
  341.      * @see         java.awt.MenuItem#getActionCommand
  342.      * @since       JDK1.1
  343.      */
  344.     public void setActionCommand(String command) {
  345.         actionCommand = command;
  346.     }
  347.  
  348.     /**
  349.      * Gets the command name of the action event that is fired 
  350.      * by this menu item.
  351.      * @see         java.awt.MenuItem#setActionCommand
  352.      * @since       JDK1.1
  353.      */
  354.     public String getActionCommand() {
  355.         return (actionCommand == null? label : actionCommand);
  356.     }
  357.  
  358.     /**
  359.      * Adds the specified action listener to receive action events
  360.      * from this menu item.
  361.      * @param      l the action listener.
  362.      * @see        java.awt.event.ActionEvent
  363.      * @see        java.awt.event.ActionListener
  364.      * @see        java.awt.MenuItem#removeActionListener
  365.      * @since      JDK1.1
  366.      */ 
  367.     public synchronized void addActionListener(ActionListener l) {
  368.     actionListener = AWTEventMulticaster.add(actionListener, l);
  369.         newEventsOnly = true;    
  370.     }
  371.  
  372.     /**
  373.      * Removes the specified action listener so it no longer receives
  374.      * action events from this menu item.
  375.      * @param      l the action listener.
  376.      * @see        java.awt.event.ActionEvent
  377.      * @see        java.awt.event.ActionListener
  378.      * @see        java.awt.MenuItem#addActionListener
  379.      * @since      JDK1.1
  380.      */ 
  381.     public synchronized void removeActionListener(ActionListener l) {
  382.     actionListener = AWTEventMulticaster.remove(actionListener, l);
  383.     }
  384.  
  385.     /**
  386.      * Processes events on this menu item. If the event is an 
  387.      * instance of <code>ActionEvent</code>, it invokes 
  388.      * <code>processActionEvent</code>, another method 
  389.      * defined by <code>MenuItem</code>.
  390.      * <p>
  391.      * Currently, menu items only support action events.
  392.      * @param       e the event.
  393.      * @see         java.awt.MenuItem#processActionEvent
  394.      * @since       JDK1.1
  395.      */
  396.     protected void processEvent(AWTEvent e) {
  397.         if (e instanceof ActionEvent) {
  398.             processActionEvent((ActionEvent)e);     
  399.         }
  400.     }
  401.  
  402.     // REMIND: remove when filtering is done at lower level
  403.     boolean eventEnabled(AWTEvent e) {
  404.         if (e.id == ActionEvent.ACTION_PERFORMED) {
  405.             if ((eventMask & AWTEvent.ACTION_EVENT_MASK) != 0 ||
  406.                 actionListener != null) {
  407.                 return true;
  408.             } 
  409.             return false;
  410.         }
  411.         return super.eventEnabled(e);
  412.     }        
  413.  
  414.     /** 
  415.      * Processes action events occurring on this menu item, 
  416.      * by dispatching them to any registered 
  417.      * <code>ActionListener</code> objects.
  418.      * This method is not called unless action events are 
  419.      * enabled for this component. Action events are enabled 
  420.      * when one of the following occurs:
  421.      * <p><ul>
  422.      * <li>An <code>ActionListener</code> object is registered 
  423.      * via <code>addActionListener</code>.
  424.      * <li>Action events are enabled via <code>enableEvents</code>.
  425.      * </ul>
  426.      * @param       e the action event.
  427.      * @see         java.awt.event.ActionEvent
  428.      * @see         java.awt.event.ActionListener
  429.      * @see         java.awt.MenuItem#enableEvents
  430.      * @since       JDK1.1
  431.      */  
  432.     protected void processActionEvent(ActionEvent e) {
  433.         if (actionListener != null) {
  434.             actionListener.actionPerformed(e);
  435.         }
  436.     }
  437.  
  438.     /**
  439.      * Returns the parameter string representing the state of this menu 
  440.      * item. This string is useful for debugging. 
  441.      * @return  the parameter string of this menu item.
  442.      * @since   JDK1.0
  443.      */
  444.     public String paramString() {
  445.         String str = ",label=" + label;
  446.         if (shortcut != null) {
  447.             str += ",shortcut=" + shortcut;
  448.         }
  449.         return super.paramString() + str;
  450.     }
  451.  
  452.  
  453.     /* Serialization support. 
  454.      */
  455.  
  456.     private int menuItemSerializedDataVersion = 1;
  457.  
  458.  
  459.     private void writeObject(ObjectOutputStream s)
  460.       throws IOException 
  461.     {
  462.       s.defaultWriteObject();
  463.  
  464.       AWTEventMulticaster.save(s, actionListenerK, actionListener);
  465.       s.writeObject(null);
  466.     }
  467.  
  468.  
  469.     private void readObject(ObjectInputStream s)
  470.       throws ClassNotFoundException, IOException 
  471.     {
  472.       s.defaultReadObject();
  473.  
  474.       Object keyOrNull;
  475.       while(null != (keyOrNull = s.readObject())) {
  476.     String key = ((String)keyOrNull).intern();
  477.  
  478.     if (actionListenerK == key) 
  479.       addActionListener((ActionListener)(s.readObject()));
  480.  
  481.     else // skip value for unrecognized key
  482.       s.readObject();
  483.       }
  484.     }
  485.  
  486. }
  487.