001/* MenuBar.java -- An AWT menu bar class
002   Copyright (C) 1999, 2000, 2001, 2002, 2004, 2005, 2006
003   Free Software Foundation, Inc.
004
005This file is part of GNU Classpath.
006
007GNU Classpath is free software; you can redistribute it and/or modify
008it under the terms of the GNU General Public License as published by
009the Free Software Foundation; either version 2, or (at your option)
010any later version.
011
012GNU Classpath is distributed in the hope that it will be useful, but
013WITHOUT ANY WARRANTY; without even the implied warranty of
014MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
015General Public License for more details.
016
017You should have received a copy of the GNU General Public License
018along with GNU Classpath; see the file COPYING.  If not, write to the
019Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02002110-1301 USA.
021
022Linking this library statically or dynamically with other modules is
023making a combined work based on this library.  Thus, the terms and
024conditions of the GNU General Public License cover the whole
025combination.
026
027As a special exception, the copyright holders of this library give you
028permission to link this library with independent modules to produce an
029executable, regardless of the license terms of these independent
030modules, and to copy and distribute the resulting executable under
031terms of your choice, provided that you also meet, for each linked
032independent module, the terms and conditions of the license of that
033module.  An independent module is a module which is not derived from
034or based on this library.  If you modify this library, you may extend
035this exception to your version of the library, but you are not
036obligated to do so.  If you do not wish to do so, delete this
037exception statement from your version. */
038
039
040package java.awt;
041
042import java.awt.peer.MenuBarPeer;
043
044import java.io.Serializable;
045import java.util.Enumeration;
046import java.util.Vector;
047
048import javax.accessibility.Accessible;
049import javax.accessibility.AccessibleContext;
050import javax.accessibility.AccessibleRole;
051
052/**
053  * This class implements a menu bar in the AWT system.
054  *
055  * @author Aaron M. Renn (arenn@urbanophile.com)
056  * @author Tom Tromey (tromey@redhat.com)
057  * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
058  */
059public class MenuBar extends MenuComponent
060  implements MenuContainer, Serializable, Accessible
061{
062
063  // Serialization Constant
064  private static final long serialVersionUID = -4930327919388951260L;
065
066  /**
067   * The number used to generate the name returned by getName.
068   */
069  private static transient long next_menubar_number;
070  
071  /**
072   * @serial The menu used for providing help information
073   */
074  private Menu helpMenu;
075
076  /**
077   * @serial The menus contained in this menu bar.
078   */
079  private Vector menus = new Vector();
080
081  /**
082   * Initializes a new instance of <code>MenuBar</code>.
083   *
084   * @throws HeadlessException if GraphicsEnvironment.isHeadless() is true
085   */
086  public MenuBar()
087  {
088    if (GraphicsEnvironment.isHeadless())
089      throw new HeadlessException();
090  }
091
092  /**
093   * Returns the help menu for this menu bar.  This may be <code>null</code>.
094   *
095   * @return the help menu for this menu bar
096   */
097  public Menu getHelpMenu()
098  {
099    return helpMenu;
100  }
101
102  /**
103   * Sets the help menu for this menu bar.
104   *
105   * @param menu the new help menu for this menu bar
106   */
107  public synchronized void setHelpMenu(Menu menu)
108  {
109    MenuBarPeer myPeer = (MenuBarPeer) getPeer ();
110
111    if (helpMenu != null)
112      {
113        if (myPeer != null)
114          helpMenu.removeNotify();
115        helpMenu.setParent(null);
116      }
117    helpMenu = menu;
118
119    MenuContainer parent = menu.getParent();
120    if (parent != null)
121      parent.remove(menu);
122    menu.setParent(this);
123
124    if (myPeer != null)
125      {
126        menu.addNotify();
127        myPeer.addHelpMenu(menu);
128      }
129  }
130
131  /**
132   * Add a menu to this MenuBar.  If the menu has already has a
133   * parent, it is first removed from its old parent before being
134   * added.
135   *
136   * @param menu the menu to add
137   *
138   * @return the menu that was added
139   */
140  public synchronized Menu add(Menu menu)
141  {
142    MenuBarPeer myPeer = (MenuBarPeer) getPeer ();
143
144    MenuContainer parent = menu.getParent();
145    if (parent != null)
146      parent.remove(menu);
147
148    menus.addElement(menu);
149    menu.setParent(this);
150
151    if (myPeer != null)
152      {
153        menu.addNotify();
154        myPeer.addMenu(menu);
155      }
156    return menu;
157  }
158
159  /**
160   * Removes the menu at the specified index.
161   *
162   * @param index the index of the menu to remove from the menu bar
163   */
164  public synchronized void remove(int index)
165  {
166    Menu m = (Menu) menus.remove(index);
167    MenuBarPeer mp = (MenuBarPeer) getPeer();
168
169    if (mp != null)
170      m.removeNotify();
171
172    m.setParent(null);
173
174    if (mp != null)
175      mp.delMenu(index);
176  }
177
178  /**
179   * Removes the specified menu from the menu bar.
180   *
181   * @param menu the menu to remove from the menu bar
182   */
183  public void remove(MenuComponent menu)
184  {
185    int index = menus.indexOf(menu);
186    if (index == -1)
187      return;
188
189    remove(index);
190  }
191
192  /**
193   * Returns the number of elements in this menu bar.
194   *
195   * @return the number of elements in the menu bar
196   */
197  public int getMenuCount()
198  {
199    return countMenus();
200  }
201
202  /**
203   * Returns the number of elements in this menu bar.
204   *
205   * @return the number of elements in the menu bar
206   *
207   * @deprecated This method is deprecated in favor of
208   *             <code>getMenuCount()</code>.
209   */
210  public int countMenus()
211  {
212    return menus.size() + (getHelpMenu() == null ? 0 : 1);
213  }
214
215  /**
216   * Returns the menu at the specified index.
217   *
218   * @param index the index of the menu
219   *
220   * @return the requested menu
221   *
222   * @throws ArrayIndexOutOfBoundsException if the index is not valid
223   */
224  public Menu getMenu(int index)
225  {
226    return (Menu) menus.elementAt(index);
227  }
228
229  /**
230   * Creates this object's native peer.
231   */
232  public void addNotify()
233  {
234    MenuBarPeer peer = (MenuBarPeer) getPeer();
235    if (peer == null)
236      {
237        peer = getToolkit().createMenuBar(this);
238        setPeer(peer);
239      }
240
241    Enumeration e = menus.elements();
242    while (e.hasMoreElements())
243      {
244        Menu mi = (Menu)e.nextElement();
245        mi.addNotify();
246        peer.addMenu(mi);
247      }
248
249    if (helpMenu != null)
250      {
251        helpMenu.addNotify();
252        peer.addHelpMenu(helpMenu);
253      }
254  }
255
256  /**
257   * Destroys this object's native peer.
258   */
259  public void removeNotify()
260  {
261    Enumeration e = menus.elements();
262    while (e.hasMoreElements())
263      {
264        Menu mi = (Menu) e.nextElement();
265        mi.removeNotify();
266      }
267    super.removeNotify();
268  }
269
270  /**
271   * Returns a list of all shortcuts for the menus in this menu bar.
272   *
273   * @return a list of all shortcuts for the menus in this menu bar
274   */
275  public synchronized Enumeration<MenuShortcut> shortcuts()
276  {
277    Vector shortcuts = new Vector();
278    Enumeration e = menus.elements();
279
280    while (e.hasMoreElements())
281      {
282        Menu menu = (Menu)e.nextElement();
283        if (menu.getShortcut() != null)
284          shortcuts.addElement(menu.getShortcut());
285      }
286
287    return shortcuts.elements();
288  }
289
290  /**
291   * Returns the menu item for the specified shortcut, or <code>null</code>
292   * if no such item exists.
293   *
294   * @param shortcut the shortcut to return the menu item for
295   *
296   * @return the menu item for the specified shortcut
297   */
298  public MenuItem getShortcutMenuItem(MenuShortcut shortcut)
299  {
300    Enumeration e = menus.elements();
301
302    while (e.hasMoreElements())
303      {
304        Menu menu = (Menu) e.nextElement();
305        MenuShortcut s = menu.getShortcut();
306        if ((s != null) && s.equals(shortcut))
307          return menu;
308      }
309
310    return null;
311  }
312
313  /**
314   * Deletes the specified menu shortcut.
315   *
316   * @param shortcut the shortcut to delete
317   */
318  public void deleteShortcut(MenuShortcut shortcut)
319  {
320    MenuItem it;
321    // This is a slow implementation, but it probably doesn't matter.
322    while ((it = getShortcutMenuItem (shortcut)) != null)
323      it.deleteShortcut();
324  }
325
326  /**
327   * Gets the AccessibleContext associated with this <code>MenuBar</code>.
328   * The context is created, if necessary.
329   *
330   * @return the associated context
331   */
332  public AccessibleContext getAccessibleContext()
333  {
334    // Create the context if this is the first request.
335    if (accessibleContext == null)
336      accessibleContext = new AccessibleAWTMenuBar();
337    return accessibleContext;
338  }
339  
340  /**
341   * Generate a unique name for this <code>MenuBar</code>.
342   *
343   * @return A unique name for this <code>MenuBar</code>.
344   */
345  String generateName()
346  {
347    return "menubar" + getUniqueLong();
348  }
349
350  private static synchronized long getUniqueLong()
351  {
352    return next_menubar_number++;
353  }
354
355  /**
356   * This class provides accessibility support for AWT menu bars.
357   *
358   * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
359   */
360  protected class AccessibleAWTMenuBar
361    extends AccessibleAWTMenuComponent
362  {
363  
364    /**
365     * Compatible with JDK 1.4.2 revision 5
366     */
367    private static final long serialVersionUID = -8577604491830083815L;
368
369    /**
370     * This is the default constructor, which simply calls the default
371     * constructor of the superclass.
372     */
373    protected AccessibleAWTMenuBar()
374    {
375      super();
376    }
377
378    /**
379     * Returns the accessible role relating to the menu bar.
380     *
381     * @return <code>AccessibleRole.MENU_BAR</code>
382     */
383    public AccessibleRole getAccessibleRole()
384    {
385      return AccessibleRole.MENU_BAR;
386    }
387
388  }
389
390}