OSDN Git Service

* java/awt/MenuItem.java (paramString): Now protected.
[pf3gnuchains/gcc-fork.git] / libjava / java / awt / MenuBar.java
index ce7d3bc..6e25bc9 100644 (file)
@@ -8,40 +8,281 @@ details.  */
 
 package java.awt;
 
-/* A very incomplete placeholder. */
+import java.awt.peer.MenuBarPeer;
+import java.util.Vector;
+import java.util.Enumeration;
+import java.util.NoSuchElementException;
 
-public class MenuBar extends MenuComponent  implements MenuContainer
+/** 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
 {
-  Menu[] menus;
-  int count;
+  /** 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;
+  }
 
-  public synchronized Menu add (Menu m)
+  /** Returns a menu from this object.
+   * @param index Index of menu to return.
+   */
+  public Menu getMenu (int index)
   {
-    if (menus == null)
-      menus = new Menu[1];
-    else if (count == menus.length)
+    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 ())
       {
-       Menu[] newMenus = new Menu[2 * count];
-       System.arraycopy(menus, 0, newMenus, 0, count);
+       MenuItem item = (MenuItem) m.nextElement ();
+       if (item.getShortcut () == shortcut)
+         return item;
       }
-    menus[count++] = m;
-    return m;
+    return null;
   }
 
-  public void remove (MenuComponent comp)
+  /** 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)
   {
-    for (int i = count; --i >= 0; )
+    int s = menus.size ();
+    for (int i = 0; i < s; ++i)
       {
-       if (menus[i] == comp)
+       if (menus.get (i) == menu)
          {
-           System.arraycopy(menus, i, menus, i+1, count-i-1);
-           count--;
-           // FIXME:  destroy peer
-           return;
+           remove (i);
+           break;
          }
       }
   }
 
-  public Font getFont() { return null; } // FIXME
-  public boolean postEvent(Event evt) { return false; } // FIXME
+  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;
 }