KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > awt > MenuBar


1 /*
2  * @(#)MenuBar.java 1.69 04/05/18
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7 package java.awt;
8
9 import java.io.IOException JavaDoc;
10 import java.io.ObjectInputStream JavaDoc;
11 import java.util.Vector JavaDoc;
12 import java.util.Enumeration JavaDoc;
13 import java.awt.peer.MenuBarPeer;
14 import java.awt.event.KeyEvent JavaDoc;
15 import javax.accessibility.*;
16
17 /**
18  * The <code>MenuBar</code> class encapsulates the platform's
19  * concept of a menu bar bound to a frame. In order to associate
20  * the menu bar with a <code>Frame</code> object, call the
21  * frame's <code>setMenuBar</code> method.
22  * <p>
23  * <A NAME="mbexample"></A><!-- target for cross references -->
24  * This is what a menu bar might look like:
25  * <p>
26  * <img SRC="doc-files/MenuBar-1.gif"
27  * <alt="Diagram of MenuBar containing 2 menus: Examples and Options.
28  * Examples menu is expanded showing items: Basic, Simple, Check, and More Examples.">
29  * ALIGN=center HSPACE=10 VSPACE=7>
30  * <p>
31  * A menu bar handles keyboard shortcuts for menu items, passing them
32  * along to its child menus.
33  * (Keyboard shortcuts, which are optional, provide the user with
34  * an alternative to the mouse for invoking a menu item and the
35  * action that is associated with it.)
36  * Each menu item can maintain an instance of <code>MenuShortcut</code>.
37  * The <code>MenuBar</code> class defines several methods,
38  * {@link MenuBar#shortcuts} and
39  * {@link MenuBar#getShortcutMenuItem}
40  * that retrieve information about the shortcuts a given
41  * menu bar is managing.
42  *
43  * @version 1.69, 05/18/04
44  * @author Sami Shaio
45  * @see java.awt.Frame
46  * @see java.awt.Frame#setMenuBar(java.awt.MenuBar)
47  * @see java.awt.Menu
48  * @see java.awt.MenuItem
49  * @see java.awt.MenuShortcut
50  * @since JDK1.0
51  */

52 public class MenuBar extends MenuComponent JavaDoc implements MenuContainer JavaDoc, Accessible {
53
54     static {
55         /* ensure that the necessary native libraries are loaded */
56     Toolkit.loadLibraries();
57         if (!GraphicsEnvironment.isHeadless()) {
58             initIDs();
59         }
60     }
61
62     /**
63      * This field represents a vector of the
64      * actual menus that will be part of the MenuBar.
65      *
66      * @serial
67      * @see #countMenus()
68      */

69     Vector JavaDoc menus = new Vector JavaDoc();
70
71     /**
72      * This menu is a special menu dedicated to
73      * help. The one thing to note about this menu
74      * is that on some platforms it appears at the
75      * right edge of the menubar.
76      *
77      * @serial
78      * @see #getHelpMenu()
79      * @see #setHelpMenu(Menu)
80      */

81     Menu JavaDoc helpMenu;
82
83     private static final String JavaDoc base = "menubar";
84     private static int nameCounter = 0;
85
86     /*
87      * JDK 1.1 serialVersionUID
88      */

89      private static final long serialVersionUID = -4930327919388951260L;
90
91     /**
92      * Creates a new menu bar.
93      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
94      * returns true.
95      * @see java.awt.GraphicsEnvironment#isHeadless
96      */

97     public MenuBar() throws HeadlessException JavaDoc {
98     }
99
100     /**
101      * Construct a name for this MenuComponent. Called by getName() when
102      * the name is null.
103      */

104     String JavaDoc constructComponentName() {
105         synchronized (getClass()) {
106         return base + nameCounter++;
107     }
108     }
109
110     /**
111      * Creates the menu bar's peer. The peer allows us to change the
112      * appearance of the menu bar without changing any of the menu bar's
113      * functionality.
114      */

115     public void addNotify() {
116         synchronized (getTreeLock()) {
117         if (peer == null)
118             peer = Toolkit.getDefaultToolkit().createMenuBar(this);
119
120         int nmenus = getMenuCount();
121         for (int i = 0 ; i < nmenus ; i++) {
122             getMenu(i).addNotify();
123         }
124     }
125     }
126
127     /**
128      * Removes the menu bar's peer. The peer allows us to change the
129      * appearance of the menu bar without changing any of the menu bar's
130      * functionality.
131      */

132     public void removeNotify() {
133         synchronized (getTreeLock()) {
134         int nmenus = getMenuCount();
135         for (int i = 0 ; i < nmenus ; i++) {
136             getMenu(i).removeNotify();
137         }
138         super.removeNotify();
139     }
140     }
141
142     /**
143      * Gets the help menu on the menu bar.
144      * @return the help menu on this menu bar.
145      */

146     public Menu JavaDoc getHelpMenu() {
147     return helpMenu;
148     }
149
150     /**
151      * Sets the specified menu to be this menu bar's help menu.
152      * If this menu bar has an existing help menu, the old help menu is
153      * removed from the menu bar, and replaced with the specified menu.
154      * @param m the menu to be set as the help menu
155      */

156     public void setHelpMenu(Menu JavaDoc m) {
157         synchronized (getTreeLock()) {
158         if (helpMenu == m) {
159             return;
160         }
161         if (helpMenu != null) {
162                 remove(helpMenu);
163         }
164         if (m.parent != this) {
165             add(m);
166         }
167         helpMenu = m;
168         if (m != null) {
169             m.isHelpMenu = true;
170         m.parent = this;
171         MenuBarPeer peer = (MenuBarPeer)this.peer;
172         if (peer != null) {
173             if (m.peer == null) {
174                 m.addNotify();
175             }
176             peer.addHelpMenu(m);
177         }
178         }
179     }
180     }
181
182     /**
183      * Adds the specified menu to the menu bar.
184      * If the menu has been part of another menu bar,
185      * removes it from that menu bar.
186      *
187      * @param m the menu to be added
188      * @return the menu added
189      * @see java.awt.MenuBar#remove(int)
190      * @see java.awt.MenuBar#remove(java.awt.MenuComponent)
191      */

192     public Menu JavaDoc add(Menu JavaDoc m) {
193         synchronized (getTreeLock()) {
194         if (m.parent != null) {
195             m.parent.remove(m);
196         }
197         menus.addElement(m);
198         m.parent = this;
199
200         MenuBarPeer peer = (MenuBarPeer)this.peer;
201         if (peer != null) {
202             if (m.peer == null) {
203             m.addNotify();
204         }
205         peer.addMenu(m);
206         }
207         return m;
208     }
209     }
210
211     /**
212      * Removes the menu located at the specified
213      * index from this menu bar.
214      * @param index the position of the menu to be removed.
215      * @see java.awt.MenuBar#add(java.awt.Menu)
216      */

217     public void remove(int index) {
218         synchronized (getTreeLock()) {
219             Menu JavaDoc m = getMenu(index);
220             menus.removeElementAt(index);
221         MenuBarPeer peer = (MenuBarPeer)this.peer;
222         if (peer != null) {
223         m.removeNotify();
224         m.parent = null;
225         peer.delMenu(index);
226         }
227     }
228     }
229
230     /**
231      * Removes the specified menu component from this menu bar.
232      * @param m the menu component to be removed.
233      * @see java.awt.MenuBar#add(java.awt.Menu)
234      */

235     public void remove(MenuComponent JavaDoc m) {
236         synchronized (getTreeLock()) {
237         int index = menus.indexOf(m);
238         if (index >= 0) {
239             remove(index);
240         }
241     }
242     }
243
244     /**
245      * Gets the number of menus on the menu bar.
246      * @return the number of menus on the menu bar.
247      * @since JDK1.1
248      */

249     public int getMenuCount() {
250     return countMenus();
251     }
252
253     /**
254      * @deprecated As of JDK version 1.1,
255      * replaced by <code>getMenuCount()</code>.
256      */

257     @Deprecated JavaDoc
258     public int countMenus() {
259     return getMenuCountImpl();
260     }
261
262     /*
263      * This is called by the native code, so client code can't
264      * be called on the toolkit thread.
265      */

266     final int getMenuCountImpl() {
267     return menus.size();
268     }
269
270     /**
271      * Gets the specified menu.
272      * @param i the index position of the menu to be returned.
273      * @return the menu at the specified index of this menu bar.
274      */

275     public Menu JavaDoc getMenu(int i) {
276     return getMenuImpl(i);
277     }
278
279     /*
280      * This is called by the native code, so client code can't
281      * be called on the toolkit thread.
282      */

283     final Menu JavaDoc getMenuImpl(int i) {
284     return (Menu JavaDoc)menus.elementAt(i);
285     }
286
287     /**
288      * Gets an enumeration of all menu shortcuts this menu bar
289      * is managing.
290      * @return an enumeration of menu shortcuts that this
291      * menu bar is managing.
292      * @see java.awt.MenuShortcut
293      * @since JDK1.1
294      */

295     public synchronized Enumeration JavaDoc<MenuShortcut JavaDoc> shortcuts() {
296         Vector JavaDoc shortcuts = new Vector JavaDoc();
297     int nmenus = getMenuCount();
298     for (int i = 0 ; i < nmenus ; i++) {
299             Enumeration JavaDoc e = getMenu(i).shortcuts();
300             while (e.hasMoreElements()) {
301                 shortcuts.addElement(e.nextElement());
302             }
303     }
304         return shortcuts.elements();
305     }
306
307     /**
308      * Gets the instance of <code>MenuItem</code> associated
309      * with the specified <code>MenuShortcut</code> object,
310      * or <code>null</code> if none of the menu items being managed
311      * by this menu bar is associated with the specified menu
312      * shortcut.
313      * @param s the specified menu shortcut.
314      * @see java.awt.MenuItem
315      * @see java.awt.MenuShortcut
316      * @since JDK1.1
317      */

318      public MenuItem JavaDoc getShortcutMenuItem(MenuShortcut JavaDoc s) {
319     int nmenus = getMenuCount();
320     for (int i = 0 ; i < nmenus ; i++) {
321             MenuItem JavaDoc mi = getMenu(i).getShortcutMenuItem(s);
322             if (mi != null) {
323                 return mi;
324             }
325     }
326         return null; // MenuShortcut wasn't found
327
}
328
329     /*
330      * Post an ACTION_EVENT to the target of the MenuPeer
331      * associated with the specified keyboard event (on
332      * keydown). Returns true if there is an associated
333      * keyboard event.
334      */

335     boolean handleShortcut(KeyEvent JavaDoc e) {
336         // Is it a key event?
337
int id = e.getID();
338         if (id != KeyEvent.KEY_PRESSED && id != KeyEvent.KEY_RELEASED) {
339             return false;
340         }
341
342         // Is the accelerator modifier key pressed?
343
int accelKey = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
344         if ((e.getModifiers() & accelKey) == 0) {
345             return false;
346         }
347
348         // Pass MenuShortcut on to child menus.
349
int nmenus = getMenuCount();
350     for (int i = 0 ; i < nmenus ; i++) {
351         Menu JavaDoc m = getMenu(i);
352             if (m.handleShortcut(e)) {
353                 return true;
354             }
355         }
356         return false;
357     }
358
359     /**
360      * Deletes the specified menu shortcut.
361      * @param s the menu shortcut to delete.
362      * @since JDK1.1
363      */

364     public void deleteShortcut(MenuShortcut JavaDoc s) {
365     int nmenus = getMenuCount();
366     for (int i = 0 ; i < nmenus ; i++) {
367         getMenu(i).deleteShortcut(s);
368         }
369     }
370
371     /* Serialization support. Restore the (transient) parent
372      * fields of Menubar menus here.
373      */

374  
375     /**
376      * The MenuBar's serialized data version.
377      *
378      * @serial
379      */

380     private int menuBarSerializedDataVersion = 1;
381
382     /**
383      * Writes default serializable fields to stream.
384      *
385      * @param s the <code>ObjectOutputStream</code> to write
386      * @see AWTEventMulticaster#save(ObjectOutputStream, String, EventListener)
387      * @see #readObject(java.io.ObjectInputStream)
388      */

389     private void writeObject(java.io.ObjectOutputStream JavaDoc s)
390       throws java.lang.ClassNotFoundException JavaDoc,
391          java.io.IOException JavaDoc
392     {
393       s.defaultWriteObject();
394     }
395
396     /**
397      * Reads the <code>ObjectInputStream</code>.
398      * Unrecognized keys or values will be ignored.
399      *
400      * @param s the <code>ObjectInputStream</code> to read
401      * @exception HeadlessException if
402      * <code>GraphicsEnvironment.isHeadless</code> returns
403      * <code>true</code>
404      * @see java.awt.GraphicsEnvironment#isHeadless
405      * @see #writeObject(java.io.ObjectOutputStream)
406      */

407     private void readObject(ObjectInputStream JavaDoc s)
408       throws ClassNotFoundException JavaDoc, IOException JavaDoc, HeadlessException JavaDoc
409     {
410       // HeadlessException will be thrown from MenuComponent's readObject
411
s.defaultReadObject();
412       for (int i = 0; i < menus.size(); i++) {
413     Menu JavaDoc m = (Menu JavaDoc)menus.elementAt(i);
414     m.parent = this;
415       }
416     }
417
418     /**
419      * Initialize JNI field and method IDs
420      */

421     private static native void initIDs();
422
423
424 /////////////////
425
// Accessibility support
426
////////////////
427

428     /**
429      * Gets the AccessibleContext associated with this MenuBar.
430      * For menu bars, the AccessibleContext takes the form of an
431      * AccessibleAWTMenuBar.
432      * A new AccessibleAWTMenuBar instance is created if necessary.
433      *
434      * @return an AccessibleAWTMenuBar that serves as the
435      * AccessibleContext of this MenuBar
436      */

437     public AccessibleContext getAccessibleContext() {
438         if (accessibleContext == null) {
439             accessibleContext = new AccessibleAWTMenuBar();
440         }
441         return accessibleContext;
442     }
443
444     /**
445      * Defined in MenuComponent. Overridden here.
446      */

447     int getAccessibleChildIndex(MenuComponent JavaDoc child) {
448         return menus.indexOf(child);
449     }
450
451     /**
452      * Inner class of MenuBar used to provide default support for
453      * accessibility. This class is not meant to be used directly by
454      * application developers, but is instead meant only to be
455      * subclassed by menu component developers.
456      * <p>
457      * This class implements accessibility support for the
458      * <code>MenuBar</code> class. It provides an implementation of the
459      * Java Accessibility API appropriate to menu bar user-interface elements.
460      */

461     protected class AccessibleAWTMenuBar extends AccessibleAWTMenuComponent
462     {
463         /*
464          * JDK 1.3 serialVersionUID
465          */

466         private static final long serialVersionUID = -8577604491830083815L;
467
468         /**
469          * Get the role of this object.
470          *
471          * @return an instance of AccessibleRole describing the role of the
472          * object
473          */

474         public AccessibleRole getAccessibleRole() {
475             return AccessibleRole.MENU_BAR;
476         }
477
478     } // class AccessibleAWTMenuBar
479

480 }
481
Popular Tags