1 /* MenuBar.java -- An AWT menu bar class
2    Copyright (C) 1999, 2000, 2001, 2002, 2004, 2005, 2006
3    Free Software Foundation, Inc.
4 
5 This file is part of GNU Classpath.
6 
7 GNU Classpath is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11 
12 GNU Classpath is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with GNU Classpath; see the file COPYING.  If not, write to the
19 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301 USA.
21 
22 Linking this library statically or dynamically with other modules is
23 making a combined work based on this library.  Thus, the terms and
24 conditions of the GNU General Public License cover the whole
25 combination.
26 
27 As a special exception, the copyright holders of this library give you
28 permission to link this library with independent modules to produce an
29 executable, regardless of the license terms of these independent
30 modules, and to copy and distribute the resulting executable under
31 terms of your choice, provided that you also meet, for each linked
32 independent module, the terms and conditions of the license of that
33 module.  An independent module is a module which is not derived from
34 or based on this library.  If you modify this library, you may extend
35 this exception to your version of the library, but you are not
36 obligated to do so.  If you do not wish to do so, delete this
37 exception statement from your version. */
38 
39 
40 package java.awt;
41 
42 import java.awt.peer.MenuBarPeer;
43 
44 import java.io.Serializable;
45 import java.util.Enumeration;
46 import java.util.Vector;
47 
48 import javax.accessibility.Accessible;
49 import javax.accessibility.AccessibleContext;
50 import javax.accessibility.AccessibleRole;
51 
52 /**
53   * This class implements a menu bar in the AWT system.
54   *
55   * @author Aaron M. Renn (arenn@urbanophile.com)
56   * @author Tom Tromey (tromey@redhat.com)
57   * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
58   */
59 public class MenuBar extends MenuComponent
60   implements MenuContainer, Serializable, Accessible
61 {
62 
63   // Serialization Constant
64   private static final long serialVersionUID = -4930327919388951260L;
65 
66   /**
67    * The number used to generate the name returned by getName.
68    */
69   private static transient long next_menubar_number;
70 
71   /**
72    * @serial The menu used for providing help information
73    */
74   private Menu helpMenu;
75 
76   /**
77    * @serial The menus contained in this menu bar.
78    */
79   private Vector menus = new Vector();
80 
81   /**
82    * Initializes a new instance of <code>MenuBar</code>.
83    *
84    * @throws HeadlessException if GraphicsEnvironment.isHeadless() is true
85    */
MenuBar()86   public MenuBar()
87   {
88     if (GraphicsEnvironment.isHeadless())
89       throw new HeadlessException();
90   }
91 
92   /**
93    * Returns the help menu for this menu bar.  This may be <code>null</code>.
94    *
95    * @return the help menu for this menu bar
96    */
getHelpMenu()97   public Menu getHelpMenu()
98   {
99     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    */
setHelpMenu(Menu menu)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    */
add(Menu menu)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    */
remove(int index)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    */
remove(MenuComponent menu)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    */
getMenuCount()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    */
countMenus()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    */
getMenu(int index)224   public Menu getMenu(int index)
225   {
226     return (Menu) menus.elementAt(index);
227   }
228 
229   /**
230    * Creates this object's native peer.
231    */
addNotify()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    */
removeNotify()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    */
shortcuts()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    */
getShortcutMenuItem(MenuShortcut shortcut)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    */
deleteShortcut(MenuShortcut shortcut)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    */
getAccessibleContext()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    */
generateName()345   String generateName()
346   {
347     return "menubar" + getUniqueLong();
348   }
349 
getUniqueLong()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      */
AccessibleAWTMenuBar()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      */
getAccessibleRole()383     public AccessibleRole getAccessibleRole()
384     {
385       return AccessibleRole.MENU_BAR;
386     }
387 
388   }
389 
390 }
391