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

  1. /*
  2.  * @(#)Menu.java    1.42 98/03/18
  3.  *
  4.  * Copyright 1995-1997 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  *
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14. package java.awt;
  15.  
  16. import java.util.Vector;
  17. import java.util.Enumeration;
  18. import java.awt.peer.MenuPeer;
  19. import java.awt.event.KeyEvent;
  20.  
  21. /**
  22.  * A <code>Menu</code> object is a pull-down menu component 
  23.  * that is deployed from a menu bar. 
  24.  * <p>
  25.  * A menu can optionally be a <i>tear-off</i> menu. A tear-off menu 
  26.  * can be opened and dragged away from its parent menu bar or menu. 
  27.  * It remains on the screen after the mouse button has been released. 
  28.  * The mechanism for tearing off a menu is platform dependent, since 
  29.  * the look and feel of the tear-off menu is determined by its peer.
  30.  * On platforms that do not support tear-off menus, the tear-off
  31.  * property is ignored.
  32.  * <p>
  33.  * Each item in a menu must belong to the <code>MenuItem</code> 
  34.  * class. It can be an instance of <code>MenuItem</code>, a submenu 
  35.  * (an instance of <code>Menu</code>), or a check box (an instance of 
  36.  * <code>CheckboxMenuItem</code>).
  37.  *
  38.  * @version 1.42, 03/18/98
  39.  * @author Sami Shaio
  40.  * @see     java.awt.MenuItem
  41.  * @see     java.awt.CheckboxMenuItem
  42.  * @since   JDK1.0
  43.  */
  44. public class Menu extends MenuItem implements MenuContainer {
  45.     
  46.     static {
  47.         Toolkit.loadLibraries();     
  48.         initIDs();
  49.     }
  50.  
  51.     Vector        items = new Vector();
  52.     boolean        tearOff;
  53.     boolean        isHelpMenu;
  54.  
  55.     private static final String base = "menu";
  56.     private static int nameCounter = 0;
  57.  
  58.     /*
  59.      * JDK 1.1 serialVersionUID 
  60.      */
  61.      private static final long serialVersionUID = -8809584163345499784L;
  62.  
  63.     /** 
  64.      * Constructs a new menu with an empty label. This menu is not
  65.      * a tear-off menu.
  66.      * @since      JDK1.1
  67.      */
  68.     public Menu() {
  69.     this("", false);
  70.     }
  71.  
  72.     /** 
  73.      * Constructs a new menu with the specified label. This menu is not
  74.      * a tear-off menu.
  75.      * @param       label the menu's label in the menu bar, or in 
  76.      *                   another menu of which this menu is a submenu.
  77.      */
  78.     public Menu(String label) {
  79.     this(label, false);
  80.     }
  81.  
  82.     /** 
  83.      * Constructs a new menu with the specified label. If the 
  84.      * value of <code>tearOff</code> is <code>true</code>,
  85.      * the menu can be torn off.
  86.      * <p>
  87.      * Tear-off functionality may not be supported by all 
  88.      * implementations of AWT.  If a particular implementation doesn't 
  89.      * support tear-off menus, this value is silently ignored.
  90.      * @param       label the menu's label in the menu bar, or in 
  91.      *                   another menu of which this menu is a submenu.
  92.      * @param       tearOff   if <code>true</code>, the menu 
  93.      *                   is a tear-off menu.
  94.      * @since       JDK1.0.
  95.      */
  96.     public Menu(String label, boolean tearOff) {
  97.     super(label);
  98.     this.name = base + nameCounter++;
  99.     this.tearOff = tearOff;
  100.     }
  101.  
  102.     /**
  103.      * Creates the menu's peer.  The peer allows us to modify the 
  104.      * appearance of the menu without changing its functionality.
  105.      */
  106.     public void addNotify() {
  107.     if (peer == null) {
  108.         peer = Toolkit.getDefaultToolkit().createMenu(this);
  109.     }
  110.     int nitems = getItemCount();
  111.     for (int i = 0 ; i < nitems ; i++) {
  112.         MenuItem mi = getItem(i);
  113.         mi.parent = this;
  114.         mi.addNotify();
  115.     }
  116.     }
  117.  
  118.     /**
  119.      * Removes the menu's peer.  The peer allows us to modify the appearance
  120.      * of the menu without changing its functionality.
  121.      */
  122.     public void removeNotify() {
  123.     int nitems = getItemCount();
  124.     for (int i = 0 ; i < nitems ; i++) {
  125.         getItem(i).removeNotify();
  126.     }
  127.     super.removeNotify();
  128.     }
  129.  
  130.     /**
  131.      * Indicates whether this menu is a tear-off menu.  
  132.      * <p>
  133.      * Tear-off functionality may not be supported by all 
  134.      * implementations of AWT.  If a particular implementation doesn't 
  135.      * support tear-off menus, this value is silently ignored.
  136.      * @return      <code>true</code> if this is a tear-off menu; 
  137.      *                         <code>false</code> otherwise.
  138.      */
  139.     public boolean isTearOff() {
  140.     return tearOff;
  141.     }
  142.  
  143.     /** 
  144.       * Get the number of items in this menu.
  145.       * @return     the number of items in this menu.
  146.       * @since      JDK1.1
  147.       */
  148.     public int getItemCount() {
  149.     return countItems();
  150.     }
  151.  
  152.     /** 
  153.      * @deprecated As of JDK version 1.1,
  154.      * replaced by <code>getItemCount()</code>.
  155.      */
  156.     public int countItems() {
  157.     return items.size();
  158.     }
  159.  
  160.     /**
  161.      * Gets the item located at the specified index of this menu.
  162.      * @param     index the position of the item to be returned.
  163.      * @return    the item located at the specified index.
  164.      */
  165.     public MenuItem getItem(int index) {
  166.     return (MenuItem)items.elementAt(index);
  167.     }
  168.  
  169.     /**
  170.      * Adds the specified menu item to this menu. If the 
  171.      * menu item has been part of another menu, remove it  
  172.      * from that menu. 
  173.      * @param       mi   the menu item to be added.
  174.      * @return      the menu item added.
  175.      * @see         java.awt.Menu#insert(java.lang.String, int)
  176.      * @see         java.awt.Menu#insert(java.awt.MenuItem, int)
  177.      */
  178.     public synchronized MenuItem add(MenuItem mi) {
  179.     if (mi.parent != null) {
  180.         mi.parent.remove(mi);
  181.     }
  182.     items.addElement(mi);
  183.     mi.parent = this;
  184.         MenuPeer peer = (MenuPeer)this.peer;
  185.     if (peer != null) {
  186.         mi.addNotify();
  187.         peer.addItem(mi);
  188.     }
  189.     return mi;
  190.     }
  191.  
  192.     /**
  193.      * Adds an item with the specified label to this menu. 
  194.      * @param       label   the text on the item.
  195.      * @see         java.awt.Menu#insert(java.lang.String, int)
  196.      * @see         java.awt.Menu#insert(java.awt.MenuItem, int)
  197.      */
  198.     public void add(String label) {
  199.     add(new MenuItem(label));
  200.     }
  201.  
  202.     /**
  203.      * Inserts a menu item into this menu 
  204.      * at the specified position.
  205.      * @param         menuitem  the menu item to be inserted.
  206.      * @param         index     the position at which the menu  
  207.      *                          item should be inserted.
  208.      * @see           java.awt.Menu#add(java.lang.String)
  209.      * @see           java.awt.Menu#add(java.awt.MenuItem)
  210.      * @exception     IllegalArgumentException if the value of
  211.      *                    <code>index</code> is less than zero.
  212.      * @since         JDK1.1
  213.      */
  214.  
  215.     public synchronized void insert(MenuItem menuitem, int index) {
  216.     if (index < 0) {
  217.         throw new IllegalArgumentException("index less than zero.");
  218.     }
  219.  
  220.         int nitems = getItemCount();
  221.     Vector tempItems = new Vector();
  222.  
  223.     /* Remove the item at index, nitems-index times 
  224.        storing them in a temporary vector in the
  225.        order they appear on the menu.
  226.        */
  227.     for (int i = index ; i < nitems; i++) {
  228.         tempItems.addElement(getItem(index));
  229.         remove(index);
  230.     }
  231.  
  232.     add(menuitem);
  233.  
  234.     /* Add the removed items back to the menu, they are
  235.        already in the correct order in the temp vector.
  236.        */
  237.     for (int i = 0; i < tempItems.size()  ; i++) {
  238.         add((MenuItem)tempItems.elementAt(i));
  239.     }
  240.     }
  241.  
  242.     /**
  243.      * Inserts a menu item with the specified label into this menu 
  244.      * at the specified position.
  245.      * @param       label the text on the item.
  246.      * @param       index the position at which the menu item 
  247.      *                      should be inserted.
  248.      * @see         java.awt.Menu#add(java.lang.String)
  249.      * @see         java.awt.Menu#add(java.awt.MenuItem)
  250.      * @since       JDK1.1
  251.      */
  252.  
  253.     public void insert(String label, int index) {
  254.         insert(new MenuItem(label), index);
  255.     }
  256.       
  257.     /**
  258.      * Adds a separator line, or a hypen, to the menu at the current position.
  259.      * @see         java.awt.Menu#insertSeparator(int)
  260.      */
  261.     public void addSeparator() {
  262.     add("-");
  263.     }
  264.  
  265.     /**
  266.      * Inserts a separator at the specified position.
  267.      * @param       index the position at which the 
  268.      *                       menu separator should be inserted.
  269.      * @exception   IllegalArgumentException if the value of 
  270.      *                       <code>index</code> is less than 0.
  271.      * @see         java.awt.Menu#addSeparator
  272.      * @since       JDK1.1
  273.      */
  274.  
  275.     public void insertSeparator(int index) {
  276.     if (index < 0) {
  277.         throw new IllegalArgumentException("index less than zero.");
  278.     }
  279.  
  280.         int nitems = getItemCount();
  281.     Vector tempItems = new Vector();
  282.  
  283.     /* Remove the item at index, nitems-index times 
  284.        storing them in a temporary vector in the
  285.        order they appear on the menu.
  286.        */
  287.     for (int i = index ; i < nitems; i++) {
  288.         tempItems.addElement(getItem(index));
  289.         remove(index);
  290.     }
  291.  
  292.     addSeparator();
  293.  
  294.     /* Add the removed items back to the menu, they are
  295.        already in the correct order in the temp vector.
  296.        */
  297.     for (int i = 0; i < tempItems.size()  ; i++) {
  298.         add((MenuItem)tempItems.elementAt(i));
  299.     }
  300.     }
  301.  
  302.     /**
  303.      * Removes the menu item at the specified index from this menu.
  304.      * @param       index the position of the item to be removed. 
  305.      */
  306.     public synchronized void remove(int index) {
  307.     MenuItem mi = getItem(index);
  308.     items.removeElementAt(index);
  309.         MenuPeer peer = (MenuPeer)this.peer;
  310.     if (peer != null) {
  311.         mi.removeNotify();
  312.         mi.parent = null;
  313.         peer.delItem(index);
  314.     }
  315.     }
  316.  
  317.     /**
  318.      * Removes the specified menu item from this menu.
  319.      * @param       item the item to be removed from the menu
  320.      */
  321.     public synchronized void remove(MenuComponent item) {
  322.     int index = items.indexOf(item);
  323.     if (index >= 0) {
  324.         remove(index);
  325.     }
  326.     }
  327.  
  328.     /**
  329.      * Removes all items from this menu.
  330.      * @since       JDK1.0.
  331.      */
  332.     public synchronized void removeAll() {
  333.         int nitems = getItemCount();
  334.     for (int i = 0 ; i < nitems ; i++) {
  335.         remove(0);
  336.     }
  337.     }
  338.  
  339.     /*
  340.      * Post an ActionEvent to the target of the MenuPeer 
  341.      * associated with the specified keyboard event (on 
  342.      * keydown).  Returns true if there is an associated 
  343.      * keyboard event.
  344.      */
  345.     boolean handleShortcut(KeyEvent e) {
  346.         int nitems = getItemCount();
  347.         for (int i = 0 ; i < nitems ; i++) {
  348.             MenuItem mi = getItem(i);
  349.             if (mi.handleShortcut(e)) {
  350.                 return true;
  351.             }
  352.         }
  353.         return false;
  354.     }
  355.  
  356.     MenuItem getShortcutMenuItem(MenuShortcut s) {
  357.     int nitems = getItemCount();
  358.     for (int i = 0 ; i < nitems ; i++) {
  359.             MenuItem mi = getItem(i).getShortcutMenuItem(s);
  360.             if (mi != null) {
  361.                 return mi;
  362.             }
  363.     }
  364.         return null;
  365.     }
  366.  
  367.     synchronized Enumeration shortcuts() {
  368.         Vector shortcuts = new Vector();
  369.         int nitems = getItemCount();
  370.     for (int i = 0 ; i < nitems ; i++) {
  371.             MenuItem mi = getItem(i);
  372.             if (mi instanceof Menu) {
  373.                 Enumeration e = ((Menu)mi).shortcuts();
  374.                 while (e.hasMoreElements()) {
  375.                     shortcuts.addElement(e.nextElement());
  376.                 }
  377.             } else {
  378.                 MenuShortcut ms = mi.getShortcut();
  379.                 if (ms != null) {
  380.                     shortcuts.addElement(ms);
  381.                 }
  382.             }
  383.     }
  384.         return shortcuts.elements();
  385.     }
  386.  
  387.     void deleteShortcut(MenuShortcut s) {
  388.     int nitems = getItemCount();
  389.     for (int i = 0 ; i < nitems ; i++) {
  390.         getItem(i).deleteShortcut();
  391.     }
  392.     }
  393.  
  394.  
  395.     /* Serialization support.  A MenuContainer is responsible for
  396.      * restoring the parent fields of its children. 
  397.      */
  398.  
  399.     private int menuSerializedDataVersion = 1;
  400.  
  401.     private void writeObject(java.io.ObjectOutputStream s)
  402.       throws java.lang.ClassNotFoundException,
  403.          java.io.IOException 
  404.     {
  405.       s.defaultWriteObject();
  406.     }
  407.  
  408.     private void readObject(java.io.ObjectInputStream s)
  409.       throws java.lang.ClassNotFoundException,
  410.          java.io.IOException 
  411.     {
  412.       s.defaultReadObject();
  413.       for(int i = 0; i < items.size(); i++) {
  414.     MenuItem item = (MenuItem)items.elementAt(i);
  415.     item.parent = this;
  416.       }
  417.     }
  418.  
  419.     /**
  420.      * Gets the parameter string representing the state of this menu. 
  421.      * This string is useful for debugging.
  422.      * @since      JDK1.0nu.
  423.      */
  424.     public String paramString() {
  425.         String str = ",tearOff=" + tearOff+",isHelpMenu=" + isHelpMenu;
  426.         return super.paramString() + str;
  427.     }
  428.  
  429.     /**
  430.      * Initialize JNI field and method IDs
  431.      */
  432.     private static native void initIDs();
  433. }
  434.  
  435.