0N/A/*
2362N/A * Copyright (c) 1995, 2006, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/Apackage java.awt;
0N/A
0N/Aimport java.io.IOException;
0N/Aimport java.io.ObjectInputStream;
0N/Aimport java.util.Vector;
0N/Aimport java.util.Enumeration;
0N/Aimport java.awt.peer.MenuPeer;
0N/Aimport java.awt.event.KeyEvent;
0N/Aimport javax.accessibility.*;
5255N/Aimport sun.awt.AWTAccessor;
0N/A
0N/A/**
0N/A * A <code>Menu</code> object is a pull-down menu component
0N/A * that is deployed from a menu bar.
0N/A * <p>
0N/A * A menu can optionally be a <i>tear-off</i> menu. A tear-off menu
0N/A * can be opened and dragged away from its parent menu bar or menu.
0N/A * It remains on the screen after the mouse button has been released.
0N/A * The mechanism for tearing off a menu is platform dependent, since
0N/A * the look and feel of the tear-off menu is determined by its peer.
0N/A * On platforms that do not support tear-off menus, the tear-off
0N/A * property is ignored.
0N/A * <p>
0N/A * Each item in a menu must belong to the <code>MenuItem</code>
0N/A * class. It can be an instance of <code>MenuItem</code>, a submenu
0N/A * (an instance of <code>Menu</code>), or a check box (an instance of
0N/A * <code>CheckboxMenuItem</code>).
0N/A *
0N/A * @author Sami Shaio
0N/A * @see java.awt.MenuItem
0N/A * @see java.awt.CheckboxMenuItem
0N/A * @since JDK1.0
0N/A */
0N/Apublic class Menu extends MenuItem implements MenuContainer, Accessible {
0N/A
0N/A static {
0N/A /* ensure that the necessary native libraries are loaded */
0N/A Toolkit.loadLibraries();
0N/A if (!GraphicsEnvironment.isHeadless()) {
0N/A initIDs();
0N/A }
5255N/A
5255N/A AWTAccessor.setMenuAccessor(
5255N/A new AWTAccessor.MenuAccessor() {
5255N/A public Vector getItems(Menu menu) {
5255N/A return menu.items;
5255N/A }
5255N/A });
0N/A }
0N/A
0N/A /**
0N/A * A vector of the items that will be part of the Menu.
0N/A *
0N/A * @serial
0N/A * @see #countItems()
0N/A */
0N/A Vector items = new Vector();
0N/A
0N/A /**
0N/A * This field indicates whether the menu has the
0N/A * tear of property or not. It will be set to
0N/A * <code>true</code> if the menu has the tear off
0N/A * property and it will be set to <code>false</code>
0N/A * if it does not.
0N/A * A torn off menu can be deleted by a user when
0N/A * it is no longer needed.
0N/A *
0N/A * @serial
0N/A * @see #isTearOff()
0N/A */
0N/A boolean tearOff;
0N/A
0N/A /**
0N/A * This field will be set to <code>true</code>
0N/A * if the Menu in question is actually a help
0N/A * menu. Otherwise it will be set to <code>
0N/A * false</code>.
0N/A *
0N/A * @serial
0N/A */
0N/A boolean isHelpMenu;
0N/A
0N/A private static final String base = "menu";
0N/A private static int nameCounter = 0;
0N/A
0N/A /*
0N/A * JDK 1.1 serialVersionUID
0N/A */
0N/A private static final long serialVersionUID = -8809584163345499784L;
0N/A
0N/A /**
0N/A * Constructs a new menu with an empty label. This menu is not
0N/A * a tear-off menu.
0N/A * @exception HeadlessException if GraphicsEnvironment.isHeadless()
0N/A * returns true.
0N/A * @see java.awt.GraphicsEnvironment#isHeadless
0N/A * @since JDK1.1
0N/A */
0N/A public Menu() throws HeadlessException {
0N/A this("", false);
0N/A }
0N/A
0N/A /**
0N/A * Constructs a new menu with the specified label. This menu is not
0N/A * a tear-off menu.
0N/A * @param label the menu's label in the menu bar, or in
0N/A * another menu of which this menu is a submenu.
0N/A * @exception HeadlessException if GraphicsEnvironment.isHeadless()
0N/A * returns true.
0N/A * @see java.awt.GraphicsEnvironment#isHeadless
0N/A */
0N/A public Menu(String label) throws HeadlessException {
0N/A this(label, false);
0N/A }
0N/A
0N/A /**
0N/A * Constructs a new menu with the specified label,
0N/A * indicating whether the menu can be torn off.
0N/A * <p>
0N/A * Tear-off functionality may not be supported by all
0N/A * implementations of AWT. If a particular implementation doesn't
0N/A * support tear-off menus, this value is silently ignored.
0N/A * @param label the menu's label in the menu bar, or in
0N/A * another menu of which this menu is a submenu.
0N/A * @param tearOff if <code>true</code>, the menu
0N/A * is a tear-off menu.
0N/A * @exception HeadlessException if GraphicsEnvironment.isHeadless()
0N/A * returns true.
0N/A * @see java.awt.GraphicsEnvironment#isHeadless
0N/A * @since JDK1.0.
0N/A */
0N/A public Menu(String label, boolean tearOff) throws HeadlessException {
0N/A super(label);
0N/A this.tearOff = tearOff;
0N/A }
0N/A
0N/A /**
0N/A * Construct a name for this MenuComponent. Called by getName() when
0N/A * the name is null.
0N/A */
0N/A String constructComponentName() {
0N/A synchronized (Menu.class) {
0N/A return base + nameCounter++;
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Creates the menu's peer. The peer allows us to modify the
0N/A * appearance of the menu without changing its functionality.
0N/A */
0N/A public void addNotify() {
0N/A synchronized (getTreeLock()) {
0N/A if (peer == null)
0N/A peer = Toolkit.getDefaultToolkit().createMenu(this);
0N/A int nitems = getItemCount();
0N/A for (int i = 0 ; i < nitems ; i++) {
0N/A MenuItem mi = getItem(i);
0N/A mi.parent = this;
0N/A mi.addNotify();
0N/A }
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Removes the menu's peer. The peer allows us to modify the appearance
0N/A * of the menu without changing its functionality.
0N/A */
0N/A public void removeNotify() {
0N/A synchronized (getTreeLock()) {
0N/A int nitems = getItemCount();
0N/A for (int i = 0 ; i < nitems ; i++) {
0N/A getItem(i).removeNotify();
0N/A }
0N/A super.removeNotify();
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Indicates whether this menu is a tear-off menu.
0N/A * <p>
0N/A * Tear-off functionality may not be supported by all
0N/A * implementations of AWT. If a particular implementation doesn't
0N/A * support tear-off menus, this value is silently ignored.
0N/A * @return <code>true</code> if this is a tear-off menu;
0N/A * <code>false</code> otherwise.
0N/A */
0N/A public boolean isTearOff() {
0N/A return tearOff;
0N/A }
0N/A
0N/A /**
0N/A * Get the number of items in this menu.
0N/A * @return the number of items in this menu.
0N/A * @since JDK1.1
0N/A */
0N/A public int getItemCount() {
0N/A return countItems();
0N/A }
0N/A
0N/A /**
0N/A * @deprecated As of JDK version 1.1,
0N/A * replaced by <code>getItemCount()</code>.
0N/A */
0N/A @Deprecated
0N/A public int countItems() {
0N/A return countItemsImpl();
0N/A }
0N/A
0N/A /*
0N/A * This is called by the native code, so client code can't
0N/A * be called on the toolkit thread.
0N/A */
0N/A final int countItemsImpl() {
0N/A return items.size();
0N/A }
0N/A
0N/A /**
0N/A * Gets the item located at the specified index of this menu.
0N/A * @param index the position of the item to be returned.
0N/A * @return the item located at the specified index.
0N/A */
0N/A public MenuItem getItem(int index) {
0N/A return getItemImpl(index);
0N/A }
0N/A
0N/A /*
0N/A * This is called by the native code, so client code can't
0N/A * be called on the toolkit thread.
0N/A */
0N/A final MenuItem getItemImpl(int index) {
0N/A return (MenuItem)items.elementAt(index);
0N/A }
0N/A
0N/A /**
0N/A * Adds the specified menu item to this menu. If the
0N/A * menu item has been part of another menu, removes it
0N/A * from that menu.
0N/A *
0N/A * @param mi the menu item to be added
0N/A * @return the menu item added
0N/A * @see java.awt.Menu#insert(java.lang.String, int)
0N/A * @see java.awt.Menu#insert(java.awt.MenuItem, int)
0N/A */
0N/A public MenuItem add(MenuItem mi) {
0N/A synchronized (getTreeLock()) {
0N/A if (mi.parent != null) {
0N/A mi.parent.remove(mi);
0N/A }
0N/A items.addElement(mi);
0N/A mi.parent = this;
0N/A MenuPeer peer = (MenuPeer)this.peer;
0N/A if (peer != null) {
0N/A mi.addNotify();
0N/A peer.addItem(mi);
0N/A }
0N/A return mi;
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Adds an item with the specified label to this menu.
0N/A *
0N/A * @param label the text on the item
0N/A * @see java.awt.Menu#insert(java.lang.String, int)
0N/A * @see java.awt.Menu#insert(java.awt.MenuItem, int)
0N/A */
0N/A public void add(String label) {
0N/A add(new MenuItem(label));
0N/A }
0N/A
0N/A /**
0N/A * Inserts a menu item into this menu
0N/A * at the specified position.
0N/A *
0N/A * @param menuitem the menu item to be inserted.
0N/A * @param index the position at which the menu
0N/A * item should be inserted.
0N/A * @see java.awt.Menu#add(java.lang.String)
0N/A * @see java.awt.Menu#add(java.awt.MenuItem)
0N/A * @exception IllegalArgumentException if the value of
0N/A * <code>index</code> is less than zero
0N/A * @since JDK1.1
0N/A */
0N/A
0N/A public void insert(MenuItem menuitem, int index) {
0N/A synchronized (getTreeLock()) {
0N/A if (index < 0) {
0N/A throw new IllegalArgumentException("index less than zero.");
0N/A }
0N/A
0N/A int nitems = getItemCount();
0N/A Vector tempItems = new Vector();
0N/A
0N/A /* Remove the item at index, nitems-index times
0N/A storing them in a temporary vector in the
0N/A order they appear on the menu.
0N/A */
0N/A for (int i = index ; i < nitems; i++) {
0N/A tempItems.addElement(getItem(index));
0N/A remove(index);
0N/A }
0N/A
0N/A add(menuitem);
0N/A
0N/A /* Add the removed items back to the menu, they are
0N/A already in the correct order in the temp vector.
0N/A */
0N/A for (int i = 0; i < tempItems.size() ; i++) {
0N/A add((MenuItem)tempItems.elementAt(i));
0N/A }
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Inserts a menu item with the specified label into this menu
0N/A * at the specified position. This is a convenience method for
0N/A * <code>insert(menuItem, index)</code>.
0N/A *
0N/A * @param label the text on the item
0N/A * @param index the position at which the menu item
0N/A * should be inserted
0N/A * @see java.awt.Menu#add(java.lang.String)
0N/A * @see java.awt.Menu#add(java.awt.MenuItem)
0N/A * @exception IllegalArgumentException if the value of
0N/A * <code>index</code> is less than zero
0N/A * @since JDK1.1
0N/A */
0N/A
0N/A public void insert(String label, int index) {
0N/A insert(new MenuItem(label), index);
0N/A }
0N/A
0N/A /**
0N/A * Adds a separator line, or a hypen, to the menu at the current position.
0N/A * @see java.awt.Menu#insertSeparator(int)
0N/A */
0N/A public void addSeparator() {
0N/A add("-");
0N/A }
0N/A
0N/A /**
0N/A * Inserts a separator at the specified position.
0N/A * @param index the position at which the
0N/A * menu separator should be inserted.
0N/A * @exception IllegalArgumentException if the value of
0N/A * <code>index</code> is less than 0.
0N/A * @see java.awt.Menu#addSeparator
0N/A * @since JDK1.1
0N/A */
0N/A
0N/A public void insertSeparator(int index) {
0N/A synchronized (getTreeLock()) {
0N/A if (index < 0) {
0N/A throw new IllegalArgumentException("index less than zero.");
0N/A }
0N/A
0N/A int nitems = getItemCount();
0N/A Vector tempItems = new Vector();
0N/A
0N/A /* Remove the item at index, nitems-index times
0N/A storing them in a temporary vector in the
0N/A order they appear on the menu.
0N/A */
0N/A for (int i = index ; i < nitems; i++) {
0N/A tempItems.addElement(getItem(index));
0N/A remove(index);
0N/A }
0N/A
0N/A addSeparator();
0N/A
0N/A /* Add the removed items back to the menu, they are
0N/A already in the correct order in the temp vector.
0N/A */
0N/A for (int i = 0; i < tempItems.size() ; i++) {
0N/A add((MenuItem)tempItems.elementAt(i));
0N/A }
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Removes the menu item at the specified index from this menu.
0N/A * @param index the position of the item to be removed.
0N/A */
0N/A public void remove(int index) {
0N/A synchronized (getTreeLock()) {
0N/A MenuItem mi = getItem(index);
0N/A items.removeElementAt(index);
0N/A MenuPeer peer = (MenuPeer)this.peer;
0N/A if (peer != null) {
0N/A mi.removeNotify();
0N/A mi.parent = null;
0N/A peer.delItem(index);
0N/A }
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Removes the specified menu item from this menu.
0N/A * @param item the item to be removed from the menu.
0N/A * If <code>item</code> is <code>null</code>
0N/A * or is not in this menu, this method does
0N/A * nothing.
0N/A */
0N/A public void remove(MenuComponent item) {
0N/A synchronized (getTreeLock()) {
0N/A int index = items.indexOf(item);
0N/A if (index >= 0) {
0N/A remove(index);
0N/A }
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Removes all items from this menu.
0N/A * @since JDK1.0.
0N/A */
0N/A public void removeAll() {
0N/A synchronized (getTreeLock()) {
0N/A int nitems = getItemCount();
0N/A for (int i = nitems-1 ; i >= 0 ; i--) {
0N/A remove(i);
0N/A }
0N/A }
0N/A }
0N/A
0N/A /*
0N/A * Post an ActionEvent to the target of the MenuPeer
0N/A * associated with the specified keyboard event (on
0N/A * keydown). Returns true if there is an associated
0N/A * keyboard event.
0N/A */
0N/A boolean handleShortcut(KeyEvent e) {
0N/A int nitems = getItemCount();
0N/A for (int i = 0 ; i < nitems ; i++) {
0N/A MenuItem mi = getItem(i);
0N/A if (mi.handleShortcut(e)) {
0N/A return true;
0N/A }
0N/A }
0N/A return false;
0N/A }
0N/A
0N/A MenuItem getShortcutMenuItem(MenuShortcut s) {
0N/A int nitems = getItemCount();
0N/A for (int i = 0 ; i < nitems ; i++) {
0N/A MenuItem mi = getItem(i).getShortcutMenuItem(s);
0N/A if (mi != null) {
0N/A return mi;
0N/A }
0N/A }
0N/A return null;
0N/A }
0N/A
0N/A synchronized Enumeration shortcuts() {
0N/A Vector shortcuts = new Vector();
0N/A int nitems = getItemCount();
0N/A for (int i = 0 ; i < nitems ; i++) {
0N/A MenuItem mi = getItem(i);
0N/A if (mi instanceof Menu) {
0N/A Enumeration e = ((Menu)mi).shortcuts();
0N/A while (e.hasMoreElements()) {
0N/A shortcuts.addElement(e.nextElement());
0N/A }
0N/A } else {
0N/A MenuShortcut ms = mi.getShortcut();
0N/A if (ms != null) {
0N/A shortcuts.addElement(ms);
0N/A }
0N/A }
0N/A }
0N/A return shortcuts.elements();
0N/A }
0N/A
0N/A void deleteShortcut(MenuShortcut s) {
0N/A int nitems = getItemCount();
0N/A for (int i = 0 ; i < nitems ; i++) {
0N/A getItem(i).deleteShortcut(s);
0N/A }
0N/A }
0N/A
0N/A
0N/A /* Serialization support. A MenuContainer is responsible for
0N/A * restoring the parent fields of its children.
0N/A */
0N/A
0N/A /**
0N/A * The menu serialized Data Version.
0N/A *
0N/A * @serial
0N/A */
0N/A private int menuSerializedDataVersion = 1;
0N/A
0N/A /**
0N/A * Writes default serializable fields to stream.
0N/A *
0N/A * @param s the <code>ObjectOutputStream</code> to write
0N/A * @see AWTEventMulticaster#save(ObjectOutputStream, String, EventListener)
0N/A * @see #readObject(ObjectInputStream)
0N/A */
0N/A private void writeObject(java.io.ObjectOutputStream s)
0N/A throws java.io.IOException
0N/A {
0N/A s.defaultWriteObject();
0N/A }
0N/A
0N/A /**
0N/A * Reads the <code>ObjectInputStream</code>.
0N/A * Unrecognized keys or values will be ignored.
0N/A *
0N/A * @param s the <code>ObjectInputStream</code> to read
0N/A * @exception HeadlessException if
0N/A * <code>GraphicsEnvironment.isHeadless</code> returns
0N/A * <code>true</code>
0N/A * @see java.awt.GraphicsEnvironment#isHeadless
0N/A * @see #writeObject(ObjectOutputStream)
0N/A */
0N/A private void readObject(ObjectInputStream s)
0N/A throws IOException, ClassNotFoundException, HeadlessException
0N/A {
0N/A // HeadlessException will be thrown from MenuComponent's readObject
0N/A s.defaultReadObject();
0N/A for(int i = 0; i < items.size(); i++) {
0N/A MenuItem item = (MenuItem)items.elementAt(i);
0N/A item.parent = this;
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Returns a string representing the state of this <code>Menu</code>.
0N/A * This method is intended to be used only for debugging purposes, and the
0N/A * content and format of the returned string may vary between
0N/A * implementations. The returned string may be empty but may not be
0N/A * <code>null</code>.
0N/A *
0N/A * @return the parameter string of this menu
0N/A */
0N/A public String paramString() {
0N/A String str = ",tearOff=" + tearOff+",isHelpMenu=" + isHelpMenu;
0N/A return super.paramString() + str;
0N/A }
0N/A
0N/A /**
0N/A * Initialize JNI field and method IDs
0N/A */
0N/A private static native void initIDs();
0N/A
0N/A
0N/A/////////////////
0N/A// Accessibility support
0N/A////////////////
0N/A
0N/A /**
0N/A * Gets the AccessibleContext associated with this Menu.
0N/A * For menus, the AccessibleContext takes the form of an
0N/A * AccessibleAWTMenu.
0N/A * A new AccessibleAWTMenu instance is created if necessary.
0N/A *
0N/A * @return an AccessibleAWTMenu that serves as the
0N/A * AccessibleContext of this Menu
0N/A * @since 1.3
0N/A */
0N/A public AccessibleContext getAccessibleContext() {
0N/A if (accessibleContext == null) {
0N/A accessibleContext = new AccessibleAWTMenu();
0N/A }
0N/A return accessibleContext;
0N/A }
0N/A
0N/A /**
0N/A * Defined in MenuComponent. Overridden here.
0N/A */
0N/A int getAccessibleChildIndex(MenuComponent child) {
0N/A return items.indexOf(child);
0N/A }
0N/A
0N/A /**
0N/A * Inner class of Menu used to provide default support for
0N/A * accessibility. This class is not meant to be used directly by
0N/A * application developers, but is instead meant only to be
0N/A * subclassed by menu component developers.
0N/A * <p>
0N/A * This class implements accessibility support for the
0N/A * <code>Menu</code> class. It provides an implementation of the
0N/A * Java Accessibility API appropriate to menu user-interface elements.
0N/A * @since 1.3
0N/A */
0N/A protected class AccessibleAWTMenu extends AccessibleAWTMenuItem
0N/A {
0N/A /*
0N/A * JDK 1.3 serialVersionUID
0N/A */
0N/A private static final long serialVersionUID = 5228160894980069094L;
0N/A
0N/A /**
0N/A * Get the role of this object.
0N/A *
0N/A * @return an instance of AccessibleRole describing the role of the
0N/A * object
0N/A */
0N/A public AccessibleRole getAccessibleRole() {
0N/A return AccessibleRole.MENU;
0N/A }
0N/A
0N/A } // class AccessibleAWTMenu
0N/A
0N/A}