Home » openjdk-7 » java » awt » [javadoc | source]

    1   /*
    2    * Copyright (c) 1995, 2006, Oracle and/or its affiliates. All rights reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Oracle designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Oracle in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22    * or visit www.oracle.com if you need additional information or have any
   23    * questions.
   24    */
   25   package java.awt;
   26   
   27   import java.io.IOException;
   28   import java.io.ObjectInputStream;
   29   import java.util.Vector;
   30   import java.util.Enumeration;
   31   import java.awt.peer.MenuBarPeer;
   32   import java.awt.event.KeyEvent;
   33   import javax.accessibility;
   34   
   35   /**
   36    * The <code>MenuBar</code> class encapsulates the platform's
   37    * concept of a menu bar bound to a frame. In order to associate
   38    * the menu bar with a <code>Frame</code> object, call the
   39    * frame's <code>setMenuBar</code> method.
   40    * <p>
   41    * <A NAME="mbexample"></A><!-- target for cross references -->
   42    * This is what a menu bar might look like:
   43    * <p>
   44    * <img src="doc-files/MenuBar-1.gif"
   45    * <alt="Diagram of MenuBar containing 2 menus: Examples and Options.
   46    * Examples menu is expanded showing items: Basic, Simple, Check, and More Examples."
   47    * ALIGN=center HSPACE=10 VSPACE=7>
   48    * <p>
   49    * A menu bar handles keyboard shortcuts for menu items, passing them
   50    * along to its child menus.
   51    * (Keyboard shortcuts, which are optional, provide the user with
   52    * an alternative to the mouse for invoking a menu item and the
   53    * action that is associated with it.)
   54    * Each menu item can maintain an instance of <code>MenuShortcut</code>.
   55    * The <code>MenuBar</code> class defines several methods,
   56    * {@link MenuBar#shortcuts} and
   57    * {@link MenuBar#getShortcutMenuItem}
   58    * that retrieve information about the shortcuts a given
   59    * menu bar is managing.
   60    *
   61    * @author Sami Shaio
   62    * @see        java.awt.Frame
   63    * @see        java.awt.Frame#setMenuBar(java.awt.MenuBar)
   64    * @see        java.awt.Menu
   65    * @see        java.awt.MenuItem
   66    * @see        java.awt.MenuShortcut
   67    * @since      JDK1.0
   68    */
   69   public class MenuBar extends MenuComponent implements MenuContainer, Accessible {
   70   
   71       static {
   72           /* ensure that the necessary native libraries are loaded */
   73           Toolkit.loadLibraries();
   74           if (!GraphicsEnvironment.isHeadless()) {
   75               initIDs();
   76           }
   77       }
   78   
   79       /**
   80        * This field represents a vector of the
   81        * actual menus that will be part of the MenuBar.
   82        *
   83        * @serial
   84        * @see #countMenus()
   85        */
   86       Vector menus = new Vector();
   87   
   88       /**
   89        * This menu is a special menu dedicated to
   90        * help.  The one thing to note about this menu
   91        * is that on some platforms it appears at the
   92        * right edge of the menubar.
   93        *
   94        * @serial
   95        * @see #getHelpMenu()
   96        * @see #setHelpMenu(Menu)
   97        */
   98       Menu helpMenu;
   99   
  100       private static final String base = "menubar";
  101       private static int nameCounter = 0;
  102   
  103       /*
  104        * JDK 1.1 serialVersionUID
  105        */
  106        private static final long serialVersionUID = -4930327919388951260L;
  107   
  108       /**
  109        * Creates a new menu bar.
  110        * @exception HeadlessException if GraphicsEnvironment.isHeadless()
  111        * returns true.
  112        * @see java.awt.GraphicsEnvironment#isHeadless
  113        */
  114       public MenuBar() throws HeadlessException {
  115       }
  116   
  117       /**
  118        * Construct a name for this MenuComponent.  Called by getName() when
  119        * the name is null.
  120        */
  121       String constructComponentName() {
  122           synchronized (MenuBar.class) {
  123               return base + nameCounter++;
  124           }
  125       }
  126   
  127       /**
  128        * Creates the menu bar's peer.  The peer allows us to change the
  129        * appearance of the menu bar without changing any of the menu bar's
  130        * functionality.
  131        */
  132       public void addNotify() {
  133           synchronized (getTreeLock()) {
  134               if (peer == null)
  135                   peer = Toolkit.getDefaultToolkit().createMenuBar(this);
  136   
  137               int nmenus = getMenuCount();
  138               for (int i = 0 ; i < nmenus ; i++) {
  139                   getMenu(i).addNotify();
  140               }
  141           }
  142       }
  143   
  144       /**
  145        * Removes the menu bar's peer.  The peer allows us to change the
  146        * appearance of the menu bar without changing any of the menu bar's
  147        * functionality.
  148        */
  149       public void removeNotify() {
  150           synchronized (getTreeLock()) {
  151               int nmenus = getMenuCount();
  152               for (int i = 0 ; i < nmenus ; i++) {
  153                   getMenu(i).removeNotify();
  154               }
  155               super.removeNotify();
  156           }
  157       }
  158   
  159       /**
  160        * Gets the help menu on the menu bar.
  161        * @return    the help menu on this menu bar.
  162        */
  163       public Menu getHelpMenu() {
  164           return helpMenu;
  165       }
  166   
  167       /**
  168        * Sets the specified menu to be this menu bar's help menu.
  169        * If this menu bar has an existing help menu, the old help menu is
  170        * removed from the menu bar, and replaced with the specified menu.
  171        * @param m    the menu to be set as the help menu
  172        */
  173       public void setHelpMenu(Menu m) {
  174           synchronized (getTreeLock()) {
  175               if (helpMenu == m) {
  176                   return;
  177               }
  178               if (helpMenu != null) {
  179                   remove(helpMenu);
  180               }
  181               if (m.parent != this) {
  182                   add(m);
  183               }
  184               helpMenu = m;
  185               if (m != null) {
  186                   m.isHelpMenu = true;
  187                   m.parent = this;
  188                   MenuBarPeer peer = (MenuBarPeer)this.peer;
  189                   if (peer != null) {
  190                       if (m.peer == null) {
  191                           m.addNotify();
  192                       }
  193                       peer.addHelpMenu(m);
  194                   }
  195               }
  196           }
  197       }
  198   
  199       /**
  200        * Adds the specified menu to the menu bar.
  201        * If the menu has been part of another menu bar,
  202        * removes it from that menu bar.
  203        *
  204        * @param        m   the menu to be added
  205        * @return       the menu added
  206        * @see          java.awt.MenuBar#remove(int)
  207        * @see          java.awt.MenuBar#remove(java.awt.MenuComponent)
  208        */
  209       public Menu add(Menu m) {
  210           synchronized (getTreeLock()) {
  211               if (m.parent != null) {
  212                   m.parent.remove(m);
  213               }
  214               menus.addElement(m);
  215               m.parent = this;
  216   
  217               MenuBarPeer peer = (MenuBarPeer)this.peer;
  218               if (peer != null) {
  219                   if (m.peer == null) {
  220                       m.addNotify();
  221                   }
  222                   peer.addMenu(m);
  223               }
  224               return m;
  225           }
  226       }
  227   
  228       /**
  229        * Removes the menu located at the specified
  230        * index from this menu bar.
  231        * @param        index   the position of the menu to be removed.
  232        * @see          java.awt.MenuBar#add(java.awt.Menu)
  233        */
  234       public void remove(int index) {
  235           synchronized (getTreeLock()) {
  236               Menu m = getMenu(index);
  237               menus.removeElementAt(index);
  238               MenuBarPeer peer = (MenuBarPeer)this.peer;
  239               if (peer != null) {
  240                   m.removeNotify();
  241                   m.parent = null;
  242                   peer.delMenu(index);
  243               }
  244           }
  245       }
  246   
  247       /**
  248        * Removes the specified menu component from this menu bar.
  249        * @param        m the menu component to be removed.
  250        * @see          java.awt.MenuBar#add(java.awt.Menu)
  251        */
  252       public void remove(MenuComponent m) {
  253           synchronized (getTreeLock()) {
  254               int index = menus.indexOf(m);
  255               if (index >= 0) {
  256                   remove(index);
  257               }
  258           }
  259       }
  260   
  261       /**
  262        * Gets the number of menus on the menu bar.
  263        * @return     the number of menus on the menu bar.
  264        * @since      JDK1.1
  265        */
  266       public int getMenuCount() {
  267           return countMenus();
  268       }
  269   
  270       /**
  271        * @deprecated As of JDK version 1.1,
  272        * replaced by <code>getMenuCount()</code>.
  273        */
  274       @Deprecated
  275       public int countMenus() {
  276           return getMenuCountImpl();
  277       }
  278   
  279       /*
  280        * This is called by the native code, so client code can't
  281        * be called on the toolkit thread.
  282        */
  283       final int getMenuCountImpl() {
  284           return menus.size();
  285       }
  286   
  287       /**
  288        * Gets the specified menu.
  289        * @param      i the index position of the menu to be returned.
  290        * @return     the menu at the specified index of this menu bar.
  291        */
  292       public Menu getMenu(int i) {
  293           return getMenuImpl(i);
  294       }
  295   
  296       /*
  297        * This is called by the native code, so client code can't
  298        * be called on the toolkit thread.
  299        */
  300       final Menu getMenuImpl(int i) {
  301           return (Menu)menus.elementAt(i);
  302       }
  303   
  304       /**
  305        * Gets an enumeration of all menu shortcuts this menu bar
  306        * is managing.
  307        * @return      an enumeration of menu shortcuts that this
  308        *                      menu bar is managing.
  309        * @see         java.awt.MenuShortcut
  310        * @since       JDK1.1
  311        */
  312       public synchronized Enumeration<MenuShortcut> shortcuts() {
  313           Vector shortcuts = new Vector();
  314           int nmenus = getMenuCount();
  315           for (int i = 0 ; i < nmenus ; i++) {
  316               Enumeration e = getMenu(i).shortcuts();
  317               while (e.hasMoreElements()) {
  318                   shortcuts.addElement(e.nextElement());
  319               }
  320           }
  321           return shortcuts.elements();
  322       }
  323   
  324       /**
  325        * Gets the instance of <code>MenuItem</code> associated
  326        * with the specified <code>MenuShortcut</code> object,
  327        * or <code>null</code> if none of the menu items being managed
  328        * by this menu bar is associated with the specified menu
  329        * shortcut.
  330        * @param        s the specified menu shortcut.
  331        * @see          java.awt.MenuItem
  332        * @see          java.awt.MenuShortcut
  333        * @since        JDK1.1
  334        */
  335        public MenuItem getShortcutMenuItem(MenuShortcut s) {
  336           int nmenus = getMenuCount();
  337           for (int i = 0 ; i < nmenus ; i++) {
  338               MenuItem mi = getMenu(i).getShortcutMenuItem(s);
  339               if (mi != null) {
  340                   return mi;
  341               }
  342           }
  343           return null;  // MenuShortcut wasn't found
  344        }
  345   
  346       /*
  347        * Post an ACTION_EVENT to the target of the MenuPeer
  348        * associated with the specified keyboard event (on
  349        * keydown).  Returns true if there is an associated
  350        * keyboard event.
  351        */
  352       boolean handleShortcut(KeyEvent e) {
  353           // Is it a key event?
  354           int id = e.getID();
  355           if (id != KeyEvent.KEY_PRESSED && id != KeyEvent.KEY_RELEASED) {
  356               return false;
  357           }
  358   
  359           // Is the accelerator modifier key pressed?
  360           int accelKey = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
  361           if ((e.getModifiers() & accelKey) == 0) {
  362               return false;
  363           }
  364   
  365           // Pass MenuShortcut on to child menus.
  366           int nmenus = getMenuCount();
  367           for (int i = 0 ; i < nmenus ; i++) {
  368               Menu m = getMenu(i);
  369               if (m.handleShortcut(e)) {
  370                   return true;
  371               }
  372           }
  373           return false;
  374       }
  375   
  376       /**
  377        * Deletes the specified menu shortcut.
  378        * @param     s the menu shortcut to delete.
  379        * @since     JDK1.1
  380        */
  381       public void deleteShortcut(MenuShortcut s) {
  382           int nmenus = getMenuCount();
  383           for (int i = 0 ; i < nmenus ; i++) {
  384               getMenu(i).deleteShortcut(s);
  385           }
  386       }
  387   
  388       /* Serialization support.  Restore the (transient) parent
  389        * fields of Menubar menus here.
  390        */
  391   
  392       /**
  393        * The MenuBar's serialized data version.
  394        *
  395        * @serial
  396        */
  397       private int menuBarSerializedDataVersion = 1;
  398   
  399       /**
  400        * Writes default serializable fields to stream.
  401        *
  402        * @param s the <code>ObjectOutputStream</code> to write
  403        * @see AWTEventMulticaster#save(ObjectOutputStream, String, EventListener)
  404        * @see #readObject(java.io.ObjectInputStream)
  405        */
  406       private void writeObject(java.io.ObjectOutputStream s)
  407         throws java.lang.ClassNotFoundException,
  408                java.io.IOException
  409       {
  410         s.defaultWriteObject();
  411       }
  412   
  413       /**
  414        * Reads the <code>ObjectInputStream</code>.
  415        * Unrecognized keys or values will be ignored.
  416        *
  417        * @param s the <code>ObjectInputStream</code> to read
  418        * @exception HeadlessException if
  419        *   <code>GraphicsEnvironment.isHeadless</code> returns
  420        *   <code>true</code>
  421        * @see java.awt.GraphicsEnvironment#isHeadless
  422        * @see #writeObject(java.io.ObjectOutputStream)
  423        */
  424       private void readObject(ObjectInputStream s)
  425         throws ClassNotFoundException, IOException, HeadlessException
  426       {
  427         // HeadlessException will be thrown from MenuComponent's readObject
  428         s.defaultReadObject();
  429         for (int i = 0; i < menus.size(); i++) {
  430           Menu m = (Menu)menus.elementAt(i);
  431           m.parent = this;
  432         }
  433       }
  434   
  435       /**
  436        * Initialize JNI field and method IDs
  437        */
  438       private static native void initIDs();
  439   
  440   
  441   /////////////////
  442   // Accessibility support
  443   ////////////////
  444   
  445       /**
  446        * Gets the AccessibleContext associated with this MenuBar.
  447        * For menu bars, the AccessibleContext takes the form of an
  448        * AccessibleAWTMenuBar.
  449        * A new AccessibleAWTMenuBar instance is created if necessary.
  450        *
  451        * @return an AccessibleAWTMenuBar that serves as the
  452        *         AccessibleContext of this MenuBar
  453        * @since 1.3
  454        */
  455       public AccessibleContext getAccessibleContext() {
  456           if (accessibleContext == null) {
  457               accessibleContext = new AccessibleAWTMenuBar();
  458           }
  459           return accessibleContext;
  460       }
  461   
  462       /**
  463        * Defined in MenuComponent. Overridden here.
  464        */
  465       int getAccessibleChildIndex(MenuComponent child) {
  466           return menus.indexOf(child);
  467       }
  468   
  469       /**
  470        * Inner class of MenuBar used to provide default support for
  471        * accessibility.  This class is not meant to be used directly by
  472        * application developers, but is instead meant only to be
  473        * subclassed by menu component developers.
  474        * <p>
  475        * This class implements accessibility support for the
  476        * <code>MenuBar</code> class.  It provides an implementation of the
  477        * Java Accessibility API appropriate to menu bar user-interface elements.
  478        * @since 1.3
  479        */
  480       protected class AccessibleAWTMenuBar extends AccessibleAWTMenuComponent
  481       {
  482           /*
  483            * JDK 1.3 serialVersionUID
  484            */
  485           private static final long serialVersionUID = -8577604491830083815L;
  486   
  487           /**
  488            * Get the role of this object.
  489            *
  490            * @return an instance of AccessibleRole describing the role of the
  491            * object
  492            * @since 1.4
  493            */
  494           public AccessibleRole getAccessibleRole() {
  495               return AccessibleRole.MENU_BAR;
  496           }
  497   
  498       } // class AccessibleAWTMenuBar
  499   
  500   }

Home » openjdk-7 » java » awt » [javadoc | source]