| /* Copyright (C) 1999, 2000 Free Software Foundation |
| |
| This file is part of libjava. |
| |
| This software is copyrighted work licensed under the terms of the |
| Libjava License. Please consult the file "LIBJAVA_LICENSE" for |
| details. */ |
| |
| package java.awt; |
| |
| import java.awt.peer.MenuBarPeer; |
| import java.util.Vector; |
| import java.util.Enumeration; |
| import java.util.NoSuchElementException; |
| |
| /** This class implements a MenuBar, such as might appear across the |
| * top of a window. |
| * @author Tom Tromey <tromey@redhat.com> |
| * @date December 25, 2000 |
| */ |
| public class MenuBar extends MenuComponent implements MenuContainer |
| { |
| /** Create a new MenuBar. */ |
| public MenuBar () |
| { |
| menus = new Vector (); |
| } |
| |
| /** Add a menu to this MenuBar. If the menu has already has a |
| * parent, it is first removed from its old parent before being |
| * added. |
| * @param menu The menu to add. |
| * @returns menu |
| */ |
| public synchronized Menu add (Menu menu) |
| { |
| if (menu.parent != null) |
| menu.parent.remove (menu); |
| |
| menu.parent = this; |
| menus.add (menu); |
| |
| if (peer != null) |
| { |
| MenuBarPeer mp = (MenuBarPeer) peer; |
| mp.add (menu); |
| } |
| |
| return menu; |
| } |
| |
| /** This creates the component's peer. */ |
| public void addNotify () |
| { |
| if (peer != null) |
| { |
| // This choice of toolkit seems unsatisfying, but I'm not sure |
| // what else to do. |
| peer = Toolkit.getDefaultToolkit ().createMenuBar (this); |
| } |
| } |
| |
| /** @deprecated Use getMenuCount() instead. */ |
| public int countMenus () |
| { |
| return getMenuCount (); |
| } |
| |
| /** Delete a keyboard shortcut. |
| * @param shortcut The short cut which should be deleted from all |
| * menus on this MenuBar. |
| */ |
| public void deleteShortcut (MenuShortcut shortcut) |
| { |
| MenuItem it; |
| // This is a slow implementation, but it probably doesn't matter. |
| while ((it = getShortcutMenuItem (shortcut)) != null) |
| it.deleteShortcut (); |
| } |
| |
| /** Returns the current Help menu. */ |
| public Menu getHelpMenu () |
| { |
| return help_menu; |
| } |
| |
| /** Returns a menu from this object. |
| * @param index Index of menu to return. |
| */ |
| public Menu getMenu (int index) |
| { |
| return (Menu) menus.get (index); |
| } |
| |
| /** Returns the number of menus on this MenuBar. */ |
| public int getMenuCount () |
| { |
| return menus.size (); |
| } |
| |
| /** Returns the menu item on this MenuBar with the specified |
| * shortcut. |
| * @param shortcut Shortcut to look for |
| */ |
| public MenuItem getShortcutMenuItem (MenuShortcut shortcut) |
| { |
| Enumeration m = new MenuEnumeration (this); |
| while (m.hasMoreElements ()) |
| { |
| MenuItem item = (MenuItem) m.nextElement (); |
| if (item.getShortcut () == shortcut) |
| return item; |
| } |
| return null; |
| } |
| |
| /** Remove a menu from the menu bar. If the menu is specified by |
| * component (and not index), and does not exist on the menu, then |
| * the method does nothing. If the removed menu has a peer, it is |
| * destroyed. |
| * @param menu The menu to remove |
| * @param index The index of the menu to remove |
| */ |
| public synchronized void remove (MenuComponent menu) |
| { |
| int s = menus.size (); |
| for (int i = 0; i < s; ++i) |
| { |
| if (menus.get (i) == menu) |
| { |
| remove (i); |
| break; |
| } |
| } |
| } |
| |
| public synchronized void remove (int index) |
| { |
| Menu m = (Menu) menus.get (index); |
| menus.remove (index); |
| m.removeNotify (); |
| m.parent = null; |
| |
| if (peer != null) |
| { |
| MenuBarPeer mp = (MenuBarPeer) peer; |
| mp.remove (index); |
| } |
| } |
| |
| /** Set the Help menu for this MenuBar. If a Help menu already |
| * exists, it is first removed. |
| * @param menu The new Help menu. |
| */ |
| public synchronized void setHelpMenu (Menu menu) |
| { |
| if (help_menu != null) |
| { |
| help_menu.removeNotify (); |
| help_menu.parent = null; |
| } |
| |
| if (menu.parent != null) |
| menu.parent.remove (menu); |
| if (menu.parent != null) |
| menu.parent.remove (menu); |
| menu.parent = this; |
| |
| if (peer != null) |
| { |
| MenuBarPeer mp = (MenuBarPeer) peer; |
| mp.addHelpMenu (menu); |
| } |
| } |
| |
| /** Returns an Enumeration which lists the keyboard shortcuts |
| * associated with menu items on this MenuBar. |
| */ |
| public synchronized Enumeration shortcuts () |
| { |
| return new ShortcutEnumeration (new MenuEnumeration (this)); |
| } |
| |
| // Iterate over the items of a menu. |
| private static class MenuEnumeration implements Enumeration |
| { |
| // Enumerate over the menu's items. |
| Enumeration main; |
| // Enumerate over a submenu. |
| Enumeration sub; |
| // Menubar so we can keep track of help menu too. |
| MenuBar menubar; |
| |
| MenuEnumeration (Menu m) |
| { |
| sub = null; |
| menubar = null; |
| main = m.items.elements (); |
| } |
| |
| MenuEnumeration (MenuBar mb) |
| { |
| sub = null; |
| menubar = mb; |
| main = mb.menus.elements (); |
| } |
| |
| public boolean hasMoreElements () |
| { |
| boolean r = false; |
| if (sub != null) |
| r = sub.hasMoreElements (); |
| if (! r) |
| r = main.hasMoreElements (); |
| if (! r && menubar != null) |
| { |
| if (menubar.help_menu != null) |
| { |
| main = new MenuEnumeration (menubar.help_menu); |
| r = main.hasMoreElements (); |
| } |
| menubar = null; |
| } |
| return r; |
| } |
| |
| public Object nextElement () throws NoSuchElementException |
| { |
| while (true) |
| { |
| if (! sub.hasMoreElements ()) |
| sub = null; |
| else |
| return sub.nextElement (); |
| |
| if (! main.hasMoreElements () && menubar != null |
| && menubar.help_menu != null) |
| { |
| main = new MenuEnumeration (menubar.help_menu); |
| menubar = null; |
| } |
| |
| Object r = main.nextElement (); |
| if (r instanceof Menu) |
| { |
| sub = new MenuEnumeration ((Menu) r); |
| continue; |
| } |
| |
| return r; |
| } |
| } |
| } |
| |
| // This is an enumeration that shadows another enumeration and |
| // returns the shortcut for each item returned. I wonder if we're |
| // only supposed to return unique shortcuts? If so then we could |
| // keep a hash table here and remove duplicates. |
| private static class ShortcutEnumeration implements Enumeration |
| { |
| Enumeration back; |
| |
| ShortcutEnumeration (Enumeration back) |
| { |
| this.back = back; |
| } |
| |
| public boolean hasMoreElements () |
| { |
| return back.hasMoreElements (); |
| } |
| |
| public Object nextElement () throws NoSuchElementException |
| { |
| while (true) |
| { |
| MenuItem item = (MenuItem) back.nextElement (); |
| if (item.getShortcut () != null) |
| return item.getShortcut (); |
| } |
| } |
| } |
| |
| // We use Vector because it makes enumerating easier than ArrayList |
| // in this case. |
| Vector menus; |
| Menu help_menu; |
| } |