jdk/src/share/classes/javax/swing/JMenuBar.java
changeset 2 90ce3da70b43
child 466 6acd5ec503a8
equal deleted inserted replaced
0:fd16c54261b3 2:90ce3da70b43
       
     1 /*
       
     2  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Sun designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Sun in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    23  * have any questions.
       
    24  */
       
    25 
       
    26 package javax.swing;
       
    27 
       
    28 import java.awt.Component;
       
    29 import java.awt.Dimension;
       
    30 import java.awt.Graphics;
       
    31 import java.awt.Insets;
       
    32 import java.awt.Point;
       
    33 import java.awt.Rectangle;
       
    34 import java.awt.event.*;
       
    35 import java.util.Vector;
       
    36 import java.util.Enumeration;
       
    37 
       
    38 import java.io.Serializable;
       
    39 import java.io.ObjectOutputStream;
       
    40 import java.io.ObjectInputStream;
       
    41 import java.io.IOException;
       
    42 
       
    43 import javax.swing.event.*;
       
    44 import javax.swing.border.Border;
       
    45 import javax.swing.plaf.*;
       
    46 import javax.accessibility.*;
       
    47 
       
    48 /**
       
    49  * An implementation of a menu bar. You add <code>JMenu</code> objects to the
       
    50  * menu bar to construct a menu. When the user selects a <code>JMenu</code>
       
    51  * object, its associated <code>JPopupMenu</code> is displayed, allowing the
       
    52  * user to select one of the <code>JMenuItems</code> on it.
       
    53  * <p>
       
    54  * For information and examples of using menu bars see
       
    55  * <a
       
    56  href="http://java.sun.com/docs/books/tutorial/uiswing/components/menu.html">How to Use Menus</a>,
       
    57  * a section in <em>The Java Tutorial.</em>
       
    58  * <p>
       
    59  * <strong>Warning:</strong> Swing is not thread safe. For more
       
    60  * information see <a
       
    61  * href="package-summary.html#threading">Swing's Threading
       
    62  * Policy</a>.
       
    63  * <p>
       
    64  * <strong>Warning:</strong>
       
    65  * Serialized objects of this class will not be compatible with
       
    66  * future Swing releases. The current serialization support is
       
    67  * appropriate for short term storage or RMI between applications running
       
    68  * the same version of Swing.  As of 1.4, support for long term storage
       
    69  * of all JavaBeans<sup><font size="-2">TM</font></sup>
       
    70  * has been added to the <code>java.beans</code> package.
       
    71  * Please see {@link java.beans.XMLEncoder}.
       
    72  *
       
    73  * @beaninfo
       
    74  *   attribute: isContainer true
       
    75  * description: A container for holding and displaying menus.
       
    76  *
       
    77  * @author Georges Saab
       
    78  * @author David Karlton
       
    79  * @author Arnaud Weber
       
    80  * @see JMenu
       
    81  * @see JPopupMenu
       
    82  * @see JMenuItem
       
    83  */
       
    84 public class JMenuBar extends JComponent implements Accessible,MenuElement
       
    85 {
       
    86     /**
       
    87      * @see #getUIClassID
       
    88      * @see #readObject
       
    89      */
       
    90     private static final String uiClassID = "MenuBarUI";
       
    91 
       
    92     /*
       
    93      * Model for the selected subcontrol.
       
    94      */
       
    95     private transient SingleSelectionModel selectionModel;
       
    96 
       
    97     private boolean paintBorder           = true;
       
    98     private Insets     margin             = null;
       
    99 
       
   100     /* diagnostic aids -- should be false for production builds. */
       
   101     private static final boolean TRACE =   false; // trace creates and disposes
       
   102     private static final boolean VERBOSE = false; // show reuse hits/misses
       
   103     private static final boolean DEBUG =   false;  // show bad params, misc.
       
   104 
       
   105     /**
       
   106      * Creates a new menu bar.
       
   107      */
       
   108     public JMenuBar() {
       
   109         super();
       
   110         setFocusTraversalKeysEnabled(false);
       
   111         setSelectionModel(new DefaultSingleSelectionModel());
       
   112         updateUI();
       
   113     }
       
   114 
       
   115     /**
       
   116      * Returns the menubar's current UI.
       
   117      * @see #setUI
       
   118      */
       
   119     public MenuBarUI getUI() {
       
   120         return (MenuBarUI)ui;
       
   121     }
       
   122 
       
   123     /**
       
   124      * Sets the L&F object that renders this component.
       
   125      *
       
   126      * @param ui the new MenuBarUI L&F object
       
   127      * @see UIDefaults#getUI
       
   128      * @beaninfo
       
   129      *        bound: true
       
   130      *       hidden: true
       
   131      *    attribute: visualUpdate true
       
   132      *  description: The UI object that implements the Component's LookAndFeel.
       
   133      */
       
   134     public void setUI(MenuBarUI ui) {
       
   135         super.setUI(ui);
       
   136     }
       
   137 
       
   138     /**
       
   139      * Resets the UI property with a value from the current look and feel.
       
   140      *
       
   141      * @see JComponent#updateUI
       
   142      */
       
   143     public void updateUI() {
       
   144         setUI((MenuBarUI)UIManager.getUI(this));
       
   145     }
       
   146 
       
   147 
       
   148     /**
       
   149      * Returns the name of the L&F class that renders this component.
       
   150      *
       
   151      * @return the string "MenuBarUI"
       
   152      * @see JComponent#getUIClassID
       
   153      * @see UIDefaults#getUI
       
   154      */
       
   155     public String getUIClassID() {
       
   156         return uiClassID;
       
   157     }
       
   158 
       
   159 
       
   160     /**
       
   161      * Returns the model object that handles single selections.
       
   162      *
       
   163      * @return the <code>SingleSelectionModel</code> property
       
   164      * @see SingleSelectionModel
       
   165      */
       
   166     public SingleSelectionModel getSelectionModel() {
       
   167         return selectionModel;
       
   168     }
       
   169 
       
   170     /**
       
   171      * Sets the model object to handle single selections.
       
   172      *
       
   173      * @param model the <code>SingleSelectionModel</code> to use
       
   174      * @see SingleSelectionModel
       
   175      * @beaninfo
       
   176      *       bound: true
       
   177      * description: The selection model, recording which child is selected.
       
   178      */
       
   179     public void setSelectionModel(SingleSelectionModel model) {
       
   180         SingleSelectionModel oldValue = selectionModel;
       
   181         this.selectionModel = model;
       
   182         firePropertyChange("selectionModel", oldValue, selectionModel);
       
   183     }
       
   184 
       
   185 
       
   186     /**
       
   187      * Appends the specified menu to the end of the menu bar.
       
   188      *
       
   189      * @param c the <code>JMenu</code> component to add
       
   190      * @return the menu component
       
   191      */
       
   192     public JMenu add(JMenu c) {
       
   193         super.add(c);
       
   194         return c;
       
   195     }
       
   196 
       
   197     /**
       
   198      * Returns the menu at the specified position in the menu bar.
       
   199      *
       
   200      * @param index  an integer giving the position in the menu bar, where
       
   201      *               0 is the first position
       
   202      * @return the <code>JMenu</code> at that position, or <code>null</code> if
       
   203      *          if there is no <code>JMenu</code> at that position (ie. if
       
   204      *          it is a <code>JMenuItem</code>)
       
   205      */
       
   206     public JMenu getMenu(int index) {
       
   207         Component c = getComponentAtIndex(index);
       
   208         if (c instanceof JMenu)
       
   209             return (JMenu) c;
       
   210         return null;
       
   211     }
       
   212 
       
   213     /**
       
   214      * Returns the number of items in the menu bar.
       
   215      *
       
   216      * @return the number of items in the menu bar
       
   217      */
       
   218     public int getMenuCount() {
       
   219         return getComponentCount();
       
   220     }
       
   221 
       
   222     /**
       
   223      * Sets the help menu that appears when the user selects the
       
   224      * "help" option in the menu bar. This method is not yet implemented
       
   225      * and will throw an exception.
       
   226      *
       
   227      * @param menu the JMenu that delivers help to the user
       
   228      */
       
   229     public void setHelpMenu(JMenu menu) {
       
   230         throw new Error("setHelpMenu() not yet implemented.");
       
   231     }
       
   232 
       
   233     /**
       
   234      * Gets the help menu for the menu bar.  This method is not yet
       
   235      * implemented and will throw an exception.
       
   236      *
       
   237      * @return the <code>JMenu</code> that delivers help to the user
       
   238      */
       
   239     public JMenu getHelpMenu() {
       
   240         throw new Error("getHelpMenu() not yet implemented.");
       
   241     }
       
   242 
       
   243     /**
       
   244      * Returns the component at the specified index.
       
   245      *
       
   246      * @param i an integer specifying the position, where 0 is first
       
   247      * @return the <code>Component</code> at the position,
       
   248      *          or <code>null</code> for an invalid index
       
   249      * @deprecated replaced by <code>getComponent(int i)</code>
       
   250      */
       
   251     @Deprecated
       
   252     public Component getComponentAtIndex(int i) {
       
   253         if(i < 0 || i >= getComponentCount()) {
       
   254             return null;
       
   255         }
       
   256         return getComponent(i);
       
   257     }
       
   258 
       
   259     /**
       
   260      * Returns the index of the specified component.
       
   261      *
       
   262      * @param c  the <code>Component</code> to find
       
   263      * @return an integer giving the component's position, where 0 is first;
       
   264      *          or -1 if it can't be found
       
   265      */
       
   266     public int getComponentIndex(Component c) {
       
   267         int ncomponents = this.getComponentCount();
       
   268         Component[] component = this.getComponents();
       
   269         for (int i = 0 ; i < ncomponents ; i++) {
       
   270             Component comp = component[i];
       
   271             if (comp == c)
       
   272                 return i;
       
   273         }
       
   274         return -1;
       
   275     }
       
   276 
       
   277     /**
       
   278      * Sets the currently selected component, producing a
       
   279      * a change to the selection model.
       
   280      *
       
   281      * @param sel the <code>Component</code> to select
       
   282      */
       
   283     public void setSelected(Component sel) {
       
   284         SingleSelectionModel model = getSelectionModel();
       
   285         int index = getComponentIndex(sel);
       
   286         model.setSelectedIndex(index);
       
   287     }
       
   288 
       
   289     /**
       
   290      * Returns true if the menu bar currently has a component selected.
       
   291      *
       
   292      * @return true if a selection has been made, else false
       
   293      */
       
   294     public boolean isSelected() {
       
   295         return selectionModel.isSelected();
       
   296     }
       
   297 
       
   298     /**
       
   299      * Returns true if the menu bars border should be painted.
       
   300      *
       
   301      * @return  true if the border should be painted, else false
       
   302      */
       
   303     public boolean isBorderPainted() {
       
   304         return paintBorder;
       
   305     }
       
   306 
       
   307     /**
       
   308      * Sets whether the border should be painted.
       
   309      *
       
   310      * @param b if true and border property is not <code>null</code>,
       
   311      *          the border is painted.
       
   312      * @see #isBorderPainted
       
   313      * @beaninfo
       
   314      *        bound: true
       
   315      *    attribute: visualUpdate true
       
   316      *  description: Whether the border should be painted.
       
   317      */
       
   318     public void setBorderPainted(boolean b) {
       
   319         boolean oldValue = paintBorder;
       
   320         paintBorder = b;
       
   321         firePropertyChange("borderPainted", oldValue, paintBorder);
       
   322         if (b != oldValue) {
       
   323             revalidate();
       
   324             repaint();
       
   325         }
       
   326     }
       
   327 
       
   328     /**
       
   329      * Paints the menubar's border if <code>BorderPainted</code>
       
   330      * property is true.
       
   331      *
       
   332      * @param g the <code>Graphics</code> context to use for painting
       
   333      * @see JComponent#paint
       
   334      * @see JComponent#setBorder
       
   335      */
       
   336     protected void paintBorder(Graphics g) {
       
   337         if (isBorderPainted()) {
       
   338             super.paintBorder(g);
       
   339         }
       
   340     }
       
   341 
       
   342     /**
       
   343      * Sets the margin between the menubar's border and
       
   344      * its menus. Setting to <code>null</code> will cause the menubar to
       
   345      * use the default margins.
       
   346      *
       
   347      * @param m an Insets object containing the margin values
       
   348      * @see Insets
       
   349      * @beaninfo
       
   350      *        bound: true
       
   351      *    attribute: visualUpdate true
       
   352      *  description: The space between the menubar's border and its contents
       
   353      */
       
   354     public void setMargin(Insets m) {
       
   355         Insets old = margin;
       
   356         this.margin = m;
       
   357         firePropertyChange("margin", old, m);
       
   358         if (old == null || !old.equals(m)) {
       
   359             revalidate();
       
   360             repaint();
       
   361         }
       
   362     }
       
   363 
       
   364     /**
       
   365      * Returns the margin between the menubar's border and
       
   366      * its menus.  If there is no previous margin, it will create
       
   367      * a default margin with zero size.
       
   368      *
       
   369      * @return an <code>Insets</code> object containing the margin values
       
   370      * @see Insets
       
   371      */
       
   372     public Insets getMargin() {
       
   373         if(margin == null) {
       
   374             return new Insets(0,0,0,0);
       
   375         } else {
       
   376             return margin;
       
   377         }
       
   378     }
       
   379 
       
   380 
       
   381     /**
       
   382      * Implemented to be a <code>MenuElement</code> -- does nothing.
       
   383      *
       
   384      * @see #getSubElements
       
   385      */
       
   386     public void processMouseEvent(MouseEvent event,MenuElement path[],MenuSelectionManager manager) {
       
   387     }
       
   388 
       
   389     /**
       
   390      * Implemented to be a <code>MenuElement</code> -- does nothing.
       
   391      *
       
   392      * @see #getSubElements
       
   393      */
       
   394     public void processKeyEvent(KeyEvent e,MenuElement path[],MenuSelectionManager manager) {
       
   395     }
       
   396 
       
   397     /**
       
   398      * Implemented to be a <code>MenuElement</code> -- does nothing.
       
   399      *
       
   400      * @see #getSubElements
       
   401      */
       
   402     public void menuSelectionChanged(boolean isIncluded) {
       
   403     }
       
   404 
       
   405     /**
       
   406      * Implemented to be a <code>MenuElement</code> -- returns the
       
   407      * menus in this menu bar.
       
   408      * This is the reason for implementing the <code>MenuElement</code>
       
   409      * interface -- so that the menu bar can be treated the same as
       
   410      * other menu elements.
       
   411      * @return an array of menu items in the menu bar.
       
   412      */
       
   413     public MenuElement[] getSubElements() {
       
   414         MenuElement result[];
       
   415         Vector tmp = new Vector();
       
   416         int c = getComponentCount();
       
   417         int i;
       
   418         Component m;
       
   419 
       
   420         for(i=0 ; i < c ; i++) {
       
   421             m = getComponent(i);
       
   422             if(m instanceof MenuElement)
       
   423                 tmp.addElement(m);
       
   424         }
       
   425 
       
   426         result = new MenuElement[tmp.size()];
       
   427         for(i=0,c=tmp.size() ; i < c ; i++)
       
   428             result[i] = (MenuElement) tmp.elementAt(i);
       
   429         return result;
       
   430     }
       
   431 
       
   432     /**
       
   433      * Implemented to be a <code>MenuElement</code>. Returns this object.
       
   434      *
       
   435      * @return the current <code>Component</code> (this)
       
   436      * @see #getSubElements
       
   437      */
       
   438     public Component getComponent() {
       
   439         return this;
       
   440     }
       
   441 
       
   442 
       
   443     /**
       
   444      * Returns a string representation of this <code>JMenuBar</code>.
       
   445      * This method
       
   446      * is intended to be used only for debugging purposes, and the
       
   447      * content and format of the returned string may vary between
       
   448      * implementations. The returned string may be empty but may not
       
   449      * be <code>null</code>.
       
   450      *
       
   451      * @return  a string representation of this <code>JMenuBar</code>
       
   452      */
       
   453     protected String paramString() {
       
   454         String paintBorderString = (paintBorder ?
       
   455                                     "true" : "false");
       
   456         String marginString = (margin != null ?
       
   457                                margin.toString() : "");
       
   458 
       
   459         return super.paramString() +
       
   460         ",margin=" + marginString +
       
   461         ",paintBorder=" + paintBorderString;
       
   462     }
       
   463 
       
   464 /////////////////
       
   465 // Accessibility support
       
   466 ////////////////
       
   467 
       
   468     /**
       
   469      * Gets the AccessibleContext associated with this JMenuBar.
       
   470      * For JMenuBars, the AccessibleContext takes the form of an
       
   471      * AccessibleJMenuBar.
       
   472      * A new AccessibleJMenuBar instance is created if necessary.
       
   473      *
       
   474      * @return an AccessibleJMenuBar that serves as the
       
   475      *         AccessibleContext of this JMenuBar
       
   476      */
       
   477     public AccessibleContext getAccessibleContext() {
       
   478         if (accessibleContext == null) {
       
   479             accessibleContext = new AccessibleJMenuBar();
       
   480         }
       
   481         return accessibleContext;
       
   482     }
       
   483 
       
   484     /**
       
   485      * This class implements accessibility support for the
       
   486      * <code>JMenuBar</code> class.  It provides an implementation of the
       
   487      * Java Accessibility API appropriate to menu bar user-interface
       
   488      * elements.
       
   489      * <p>
       
   490      * <strong>Warning:</strong>
       
   491      * Serialized objects of this class will not be compatible with
       
   492      * future Swing releases. The current serialization support is
       
   493      * appropriate for short term storage or RMI between applications running
       
   494      * the same version of Swing.  As of 1.4, support for long term storage
       
   495      * of all JavaBeans<sup><font size="-2">TM</font></sup>
       
   496      * has been added to the <code>java.beans</code> package.
       
   497      * Please see {@link java.beans.XMLEncoder}.
       
   498      */
       
   499     protected class AccessibleJMenuBar extends AccessibleJComponent
       
   500         implements AccessibleSelection {
       
   501 
       
   502         /**
       
   503          * Get the accessible state set of this object.
       
   504          *
       
   505          * @return an instance of AccessibleState containing the current state
       
   506          *         of the object
       
   507          */
       
   508         public AccessibleStateSet getAccessibleStateSet() {
       
   509             AccessibleStateSet states = super.getAccessibleStateSet();
       
   510             return states;
       
   511         }
       
   512 
       
   513         /**
       
   514          * Get the role of this object.
       
   515          *
       
   516          * @return an instance of AccessibleRole describing the role of the
       
   517          * object
       
   518          */
       
   519         public AccessibleRole getAccessibleRole() {
       
   520             return AccessibleRole.MENU_BAR;
       
   521         }
       
   522 
       
   523         /**
       
   524          * Get the AccessibleSelection associated with this object.  In the
       
   525          * implementation of the Java Accessibility API for this class,
       
   526          * return this object, which is responsible for implementing the
       
   527          * AccessibleSelection interface on behalf of itself.
       
   528          *
       
   529          * @return this object
       
   530          */
       
   531         public AccessibleSelection getAccessibleSelection() {
       
   532             return this;
       
   533         }
       
   534 
       
   535         /**
       
   536          * Returns 1 if a menu is currently selected in this menu bar.
       
   537          *
       
   538          * @return 1 if a menu is currently selected, else 0
       
   539          */
       
   540          public int getAccessibleSelectionCount() {
       
   541             if (isSelected()) {
       
   542                 return 1;
       
   543             } else {
       
   544                 return 0;
       
   545             }
       
   546          }
       
   547 
       
   548         /**
       
   549          * Returns the currently selected menu if one is selected,
       
   550          * otherwise null.
       
   551          */
       
   552          public Accessible getAccessibleSelection(int i) {
       
   553             if (isSelected()) {
       
   554                 if (i != 0) {   // single selection model for JMenuBar
       
   555                     return null;
       
   556                 }
       
   557                 int j = getSelectionModel().getSelectedIndex();
       
   558                 if (getComponentAtIndex(j) instanceof Accessible) {
       
   559                     return (Accessible) getComponentAtIndex(j);
       
   560                 }
       
   561             }
       
   562             return null;
       
   563          }
       
   564 
       
   565         /**
       
   566          * Returns true if the current child of this object is selected.
       
   567          *
       
   568          * @param i the zero-based index of the child in this Accessible
       
   569          * object.
       
   570          * @see AccessibleContext#getAccessibleChild
       
   571          */
       
   572         public boolean isAccessibleChildSelected(int i) {
       
   573             return (i == getSelectionModel().getSelectedIndex());
       
   574         }
       
   575 
       
   576         /**
       
   577          * Selects the nth menu in the menu bar, forcing it to
       
   578          * pop up.  If another menu is popped up, this will force
       
   579          * it to close.  If the nth menu is already selected, this
       
   580          * method has no effect.
       
   581          *
       
   582          * @param i the zero-based index of selectable items
       
   583          * @see #getAccessibleStateSet
       
   584          */
       
   585         public void addAccessibleSelection(int i) {
       
   586             // first close up any open menu
       
   587             int j = getSelectionModel().getSelectedIndex();
       
   588             if (i == j) {
       
   589                 return;
       
   590             }
       
   591             if (j >= 0 && j < getMenuCount()) {
       
   592                 JMenu menu = getMenu(j);
       
   593                 if (menu != null) {
       
   594                     MenuSelectionManager.defaultManager().setSelectedPath(null);
       
   595 //                  menu.setPopupMenuVisible(false);
       
   596                 }
       
   597             }
       
   598             // now popup the new menu
       
   599             getSelectionModel().setSelectedIndex(i);
       
   600             JMenu menu = getMenu(i);
       
   601             if (menu != null) {
       
   602                 MenuElement me[] = new MenuElement[3];
       
   603                 me[0] = JMenuBar.this;
       
   604                 me[1] = menu;
       
   605                 me[2] = menu.getPopupMenu();
       
   606                 MenuSelectionManager.defaultManager().setSelectedPath(me);
       
   607 //              menu.setPopupMenuVisible(true);
       
   608             }
       
   609         }
       
   610 
       
   611         /**
       
   612          * Removes the nth selected item in the object from the object's
       
   613          * selection.  If the nth item isn't currently selected, this
       
   614          * method has no effect.  Otherwise, it closes the popup menu.
       
   615          *
       
   616          * @param i the zero-based index of selectable items
       
   617          */
       
   618         public void removeAccessibleSelection(int i) {
       
   619             if (i >= 0 && i < getMenuCount()) {
       
   620                 JMenu menu = getMenu(i);
       
   621                 if (menu != null) {
       
   622                     MenuSelectionManager.defaultManager().setSelectedPath(null);
       
   623 //                  menu.setPopupMenuVisible(false);
       
   624                 }
       
   625                 getSelectionModel().setSelectedIndex(-1);
       
   626             }
       
   627         }
       
   628 
       
   629         /**
       
   630          * Clears the selection in the object, so that nothing in the
       
   631          * object is selected.  This will close any open menu.
       
   632          */
       
   633         public void clearAccessibleSelection() {
       
   634             int i = getSelectionModel().getSelectedIndex();
       
   635             if (i >= 0 && i < getMenuCount()) {
       
   636                 JMenu menu = getMenu(i);
       
   637                 if (menu != null) {
       
   638                     MenuSelectionManager.defaultManager().setSelectedPath(null);
       
   639 //                  menu.setPopupMenuVisible(false);
       
   640                 }
       
   641             }
       
   642             getSelectionModel().setSelectedIndex(-1);
       
   643         }
       
   644 
       
   645         /**
       
   646          * Normally causes every selected item in the object to be selected
       
   647          * if the object supports multiple selections.  This method
       
   648          * makes no sense in a menu bar, and so does nothing.
       
   649          */
       
   650         public void selectAllAccessibleSelection() {
       
   651         }
       
   652     } // internal class AccessibleJMenuBar
       
   653 
       
   654 
       
   655     /**
       
   656      * Subclassed to check all the child menus.
       
   657      * @since 1.3
       
   658      */
       
   659     protected boolean processKeyBinding(KeyStroke ks, KeyEvent e,
       
   660                                         int condition, boolean pressed) {
       
   661         // See if we have a local binding.
       
   662         boolean retValue = super.processKeyBinding(ks, e, condition, pressed);
       
   663         if (!retValue) {
       
   664             MenuElement[] subElements = getSubElements();
       
   665             for (int i=0; i<subElements.length; i++) {
       
   666                 if (processBindingForKeyStrokeRecursive(
       
   667                                                         subElements[i], ks, e, condition, pressed)) {
       
   668                     return true;
       
   669                 }
       
   670             }
       
   671         }
       
   672         return retValue;
       
   673     }
       
   674 
       
   675     static boolean processBindingForKeyStrokeRecursive(MenuElement elem,
       
   676                                                        KeyStroke ks, KeyEvent e, int condition, boolean pressed) {
       
   677         if (elem == null) {
       
   678             return false;
       
   679         }
       
   680 
       
   681         Component c = elem.getComponent();
       
   682 
       
   683         if ( !(c.isVisible() || (c instanceof JPopupMenu)) || !c.isEnabled() ) {
       
   684             return false;
       
   685         }
       
   686 
       
   687         if (c != null && c instanceof JComponent &&
       
   688             ((JComponent)c).processKeyBinding(ks, e, condition, pressed)) {
       
   689 
       
   690             return true;
       
   691         }
       
   692 
       
   693         MenuElement[] subElements = elem.getSubElements();
       
   694         for(int i=0; i<subElements.length; i++) {
       
   695             if (processBindingForKeyStrokeRecursive(subElements[i], ks, e,
       
   696                                                     condition, pressed)) {
       
   697                 return true;
       
   698                 // We don't, pass along to children JMenu's
       
   699             }
       
   700         }
       
   701         return false;
       
   702     }
       
   703 
       
   704     /**
       
   705      * Overrides <code>JComponent.addNotify</code> to register this
       
   706      * menu bar with the current keyboard manager.
       
   707      */
       
   708     public void addNotify() {
       
   709         super.addNotify();
       
   710         KeyboardManager.getCurrentManager().registerMenuBar(this);
       
   711     }
       
   712 
       
   713     /**
       
   714      * Overrides <code>JComponent.removeNotify</code> to unregister this
       
   715      * menu bar with the current keyboard manager.
       
   716      */
       
   717     public void removeNotify() {
       
   718         super.removeNotify();
       
   719         KeyboardManager.getCurrentManager().unregisterMenuBar(this);
       
   720     }
       
   721 
       
   722 
       
   723     private void writeObject(ObjectOutputStream s) throws IOException {
       
   724         s.defaultWriteObject();
       
   725         if (getUIClassID().equals(uiClassID)) {
       
   726             byte count = JComponent.getWriteObjCounter(this);
       
   727             JComponent.setWriteObjCounter(this, --count);
       
   728             if (count == 0 && ui != null) {
       
   729                 ui.installUI(this);
       
   730             }
       
   731         }
       
   732 
       
   733         Object[] kvData = new Object[4];
       
   734         int n = 0;
       
   735 
       
   736         if (selectionModel instanceof Serializable) {
       
   737             kvData[n++] = "selectionModel";
       
   738             kvData[n++] = selectionModel;
       
   739         }
       
   740 
       
   741         s.writeObject(kvData);
       
   742     }
       
   743 
       
   744 
       
   745     /**
       
   746      * See JComponent.readObject() for information about serialization
       
   747      * in Swing.
       
   748      */
       
   749     private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException
       
   750     {
       
   751         s.defaultReadObject();
       
   752         Object[] kvData = (Object[])(s.readObject());
       
   753 
       
   754         for(int i = 0; i < kvData.length; i += 2) {
       
   755             if (kvData[i] == null) {
       
   756                 break;
       
   757             }
       
   758             else if (kvData[i].equals("selectionModel")) {
       
   759                 selectionModel = (SingleSelectionModel)kvData[i + 1];
       
   760             }
       
   761         }
       
   762 
       
   763     }
       
   764 }