aboutsummaryrefslogtreecommitdiff
path: root/libjava/java/awt/MenuBar.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/java/awt/MenuBar.java')
-rw-r--r--libjava/java/awt/MenuBar.java283
1 files changed, 262 insertions, 21 deletions
diff --git a/libjava/java/awt/MenuBar.java b/libjava/java/awt/MenuBar.java
index ce7d3bc..6e25bc9 100644
--- a/libjava/java/awt/MenuBar.java
+++ b/libjava/java/awt/MenuBar.java
@@ -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;
}