1 /*
   2  * Copyright (c) 1995, 2006, Oracle and/or its affiliates. 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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package java.awt;
  26 
  27 import java.awt.peer.MenuComponentPeer;
  28 import java.awt.event.ActionEvent;
  29 import java.io.IOException;
  30 import java.io.ObjectInputStream;
  31 import sun.awt.AppContext;
  32 import sun.awt.SunToolkit;
  33 import sun.awt.AWTAccessor;
  34 import javax.accessibility.*;
  35 
  36 import java.security.AccessControlContext;
  37 import java.security.AccessController;
  38 
  39 /**
  40  * The abstract class <code>MenuComponent</code> is the superclass
  41  * of all menu-related components. In this respect, the class
  42  * <code>MenuComponent</code> is analogous to the abstract superclass
  43  * <code>Component</code> for AWT components.
  44  * <p>
  45  * Menu components receive and process AWT events, just as components do,
  46  * through the method <code>processEvent</code>.
  47  *
  48  * @author      Arthur van Hoff
  49  * @since       JDK1.0
  50  */
  51 public abstract class MenuComponent implements java.io.Serializable {
  52 
  53     static {
  54         /* ensure that the necessary native libraries are loaded */
  55         Toolkit.loadLibraries();
  56         if (!GraphicsEnvironment.isHeadless()) {
  57             initIDs();
  58         }
  59     }
  60 
  61     transient MenuComponentPeer peer;
  62     transient MenuContainer parent;
  63 
  64     /**
  65      * The <code>AppContext</code> of the <code>MenuComponent</code>.
  66      * This is set in the constructor and never changes.
  67      */
  68     transient AppContext appContext;
  69 
  70     /**
  71      * The menu component's font. This value can be
  72      * <code>null</code> at which point a default will be used.
  73      * This defaults to <code>null</code>.
  74      *
  75      * @serial
  76      * @see #setFont(Font)
  77      * @see #getFont()
  78      */
  79     Font font;
  80 
  81     /**
  82      * The menu component's name, which defaults to <code>null</code>.
  83      * @serial
  84      * @see #getName()
  85      * @see #setName(String)
  86      */
  87     private String name;
  88 
  89     /**
  90      * A variable to indicate whether a name is explicitly set.
  91      * If <code>true</code> the name will be set explicitly.
  92      * This defaults to <code>false</code>.
  93      * @serial
  94      * @see #setName(String)
  95      */
  96     private boolean nameExplicitlySet = false;
  97 
  98     /**
  99      * Defaults to <code>false</code>.
 100      * @serial
 101      * @see #dispatchEvent(AWTEvent)
 102      */
 103     boolean newEventsOnly = false;
 104 
 105     /*
 106      * The menu's AccessControlContext.
 107      */
 108     private transient volatile AccessControlContext acc =
 109             AccessController.getContext();
 110 
 111     /*
 112      * Returns the acc this menu component was constructed with.
 113      */
 114     final AccessControlContext getAccessControlContext() {
 115         if (acc == null) {
 116             throw new SecurityException(
 117                     "MenuComponent is missing AccessControlContext");
 118         }
 119         return acc;
 120     }
 121 
 122     /*
 123      * Internal constants for serialization.
 124      */
 125     final static String actionListenerK = Component.actionListenerK;
 126     final static String itemListenerK = Component.itemListenerK;
 127 
 128     /*
 129      * JDK 1.1 serialVersionUID
 130      */
 131     private static final long serialVersionUID = -4536902356223894379L;
 132 
 133     static {
 134         AWTAccessor.setMenuComponentAccessor(
 135             new AWTAccessor.MenuComponentAccessor() {
 136                 public AppContext getAppContext(MenuComponent menuComp) {
 137                     return menuComp.appContext;
 138                 }
 139                 public void setAppContext(MenuComponent menuComp,
 140                                           AppContext appContext) {
 141                     menuComp.appContext = appContext;
 142                 }
 143                 public MenuContainer getParent(MenuComponent menuComp) {
 144                     return menuComp.parent;
 145                 }
 146             });
 147     }
 148 
 149     /**
 150      * Creates a <code>MenuComponent</code>.
 151      * @exception HeadlessException if
 152      *    <code>GraphicsEnvironment.isHeadless</code>
 153      *    returns <code>true</code>
 154      * @see java.awt.GraphicsEnvironment#isHeadless
 155      */
 156     public MenuComponent() throws HeadlessException {
 157         GraphicsEnvironment.checkHeadless();
 158         appContext = AppContext.getAppContext();
 159     }
 160 
 161     /**
 162      * Constructs a name for this <code>MenuComponent</code>.
 163      * Called by <code>getName</code> when the name is <code>null</code>.
 164      * @return a name for this <code>MenuComponent</code>
 165      */
 166     String constructComponentName() {
 167         return null; // For strict compliance with prior platform versions, a MenuComponent
 168                      // that doesn't set its name should return null from
 169                      // getName()
 170     }
 171 
 172     /**
 173      * Gets the name of the menu component.
 174      * @return        the name of the menu component
 175      * @see           java.awt.MenuComponent#setName(java.lang.String)
 176      * @since         JDK1.1
 177      */
 178     public String getName() {
 179         if (name == null && !nameExplicitlySet) {
 180             synchronized(this) {
 181                 if (name == null && !nameExplicitlySet)
 182                     name = constructComponentName();
 183             }
 184         }
 185         return name;
 186     }
 187 
 188     /**
 189      * Sets the name of the component to the specified string.
 190      * @param         name    the name of the menu component
 191      * @see           java.awt.MenuComponent#getName
 192      * @since         JDK1.1
 193      */
 194     public void setName(String name) {
 195         synchronized(this) {
 196             this.name = name;
 197             nameExplicitlySet = true;
 198         }
 199     }
 200 
 201     /**
 202      * Returns the parent container for this menu component.
 203      * @return    the menu component containing this menu component,
 204      *                 or <code>null</code> if this menu component
 205      *                 is the outermost component, the menu bar itself
 206      */
 207     public MenuContainer getParent() {
 208         return getParent_NoClientCode();
 209     }
 210     // NOTE: This method may be called by privileged threads.
 211     //       This functionality is implemented in a package-private method
 212     //       to insure that it cannot be overridden by client subclasses.
 213     //       DO NOT INVOKE CLIENT CODE ON THIS THREAD!
 214     final MenuContainer getParent_NoClientCode() {
 215         return parent;
 216     }
 217 
 218     /**
 219      * @deprecated As of JDK version 1.1,
 220      * programs should not directly manipulate peers.
 221      */
 222     @Deprecated
 223     public MenuComponentPeer getPeer() {
 224         return peer;
 225     }
 226 
 227     /**
 228      * Gets the font used for this menu component.
 229      * @return   the font used in this menu component, if there is one;
 230      *                  <code>null</code> otherwise
 231      * @see     java.awt.MenuComponent#setFont
 232      */
 233     public Font getFont() {
 234         Font font = this.font;
 235         if (font != null) {
 236             return font;
 237         }
 238         MenuContainer parent = this.parent;
 239         if (parent != null) {
 240             return parent.getFont();
 241         }
 242         return null;
 243     }
 244 
 245     // NOTE: This method may be called by privileged threads.
 246     //       This functionality is implemented in a package-private method
 247     //       to insure that it cannot be overridden by client subclasses.
 248     //       DO NOT INVOKE CLIENT CODE ON THIS THREAD!
 249     final Font getFont_NoClientCode() {
 250         Font font = this.font;
 251         if (font != null) {
 252             return font;
 253         }
 254 
 255         // The MenuContainer interface does not have getFont_NoClientCode()
 256         // and it cannot, because it must be package-private. Because of
 257         // this, we must manually cast classes that implement
 258         // MenuContainer.
 259         Object parent = this.parent;
 260         if (parent != null) {
 261             if (parent instanceof Component) {
 262                 font = ((Component)parent).getFont_NoClientCode();
 263             } else if (parent instanceof MenuComponent) {
 264                 font = ((MenuComponent)parent).getFont_NoClientCode();
 265             }
 266         }
 267         return font;
 268     } // getFont_NoClientCode()
 269 
 270 
 271     /**
 272      * Sets the font to be used for this menu component to the specified
 273      * font. This font is also used by all subcomponents of this menu
 274      * component, unless those subcomponents specify a different font.
 275      * <p>
 276      * Some platforms may not support setting of all font attributes
 277      * of a menu component; in such cases, calling <code>setFont</code>
 278      * will have no effect on the unsupported font attributes of this
 279      * menu component.  Unless subcomponents of this menu component
 280      * specify a different font, this font will be used by those
 281      * subcomponents if supported by the underlying platform.
 282      *
 283      * @param     f   the font to be set
 284      * @see       #getFont
 285      * @see       Font#getAttributes
 286      * @see       java.awt.font.TextAttribute
 287      */
 288     public void setFont(Font f) {
 289         font = f;
 290         //Fixed 6312943: NullPointerException in method MenuComponent.setFont(Font)
 291         MenuComponentPeer peer = (MenuComponentPeer)this.peer;
 292         if (peer != null) {
 293             peer.setFont(f);
 294         }
 295     }
 296 
 297     /**
 298      * Removes the menu component's peer.  The peer allows us to modify the
 299      * appearance of the menu component without changing the functionality of
 300      * the menu component.
 301      */
 302     public void removeNotify() {
 303         synchronized (getTreeLock()) {
 304             MenuComponentPeer p = (MenuComponentPeer)this.peer;
 305             if (p != null) {
 306                 Toolkit.getEventQueue().removeSourceEvents(this, true);
 307                 this.peer = null;
 308                 p.dispose();
 309             }
 310         }
 311     }
 312 
 313     /**
 314      * Posts the specified event to the menu.
 315      * This method is part of the Java&nbsp;1.0 event system
 316      * and it is maintained only for backwards compatibility.
 317      * Its use is discouraged, and it may not be supported
 318      * in the future.
 319      * @param evt the event which is to take place
 320      * @deprecated As of JDK version 1.1, replaced by {@link
 321      * #dispatchEvent(AWTEvent) dispatchEvent}.
 322      */
 323     @Deprecated
 324     public boolean postEvent(Event evt) {
 325         MenuContainer parent = this.parent;
 326         if (parent != null) {
 327             parent.postEvent(evt);
 328         }
 329         return false;
 330     }
 331 
 332     /**
 333      * Delivers an event to this component or one of its sub components.
 334      * @param e the event
 335      */
 336     public final void dispatchEvent(AWTEvent e) {
 337         dispatchEventImpl(e);
 338     }
 339 
 340     void dispatchEventImpl(AWTEvent e) {
 341         EventQueue.setCurrentEventAndMostRecentTime(e);
 342 
 343         Toolkit.getDefaultToolkit().notifyAWTEventListeners(e);
 344 
 345         if (newEventsOnly ||
 346             (parent != null && parent instanceof MenuComponent &&
 347              ((MenuComponent)parent).newEventsOnly)) {
 348             if (eventEnabled(e)) {
 349                 processEvent(e);
 350             } else if (e instanceof ActionEvent && parent != null) {
 351                 e.setSource(parent);
 352                 ((MenuComponent)parent).dispatchEvent(e);
 353             }
 354 
 355         } else { // backward compatibility
 356             Event olde = e.convertToOld();
 357             if (olde != null) {
 358                 postEvent(olde);
 359             }
 360         }
 361     }
 362 
 363     // REMIND: remove when filtering is done at lower level
 364     boolean eventEnabled(AWTEvent e) {
 365         return false;
 366     }
 367     /**
 368      * Processes events occurring on this menu component.
 369      * <p>Note that if the event parameter is <code>null</code>
 370      * the behavior is unspecified and may result in an
 371      * exception.
 372      *
 373      * @param e the event
 374      * @since JDK1.1
 375      */
 376     protected void processEvent(AWTEvent e) {
 377     }
 378 
 379     /**
 380      * Returns a string representing the state of this
 381      * <code>MenuComponent</code>. This method is intended to be used
 382      * only for debugging purposes, and the content and format of the
 383      * returned string may vary between implementations. The returned
 384      * string may be empty but may not be <code>null</code>.
 385      *
 386      * @return     the parameter string of this menu component
 387      */
 388     protected String paramString() {
 389         String thisName = getName();
 390         return (thisName != null? thisName : "");
 391     }
 392 
 393     /**
 394      * Returns a representation of this menu component as a string.
 395      * @return  a string representation of this menu component
 396      */
 397     public String toString() {
 398         return getClass().getName() + "[" + paramString() + "]";
 399     }
 400 
 401     /**
 402      * Gets this component's locking object (the object that owns the thread
 403      * sychronization monitor) for AWT component-tree and layout
 404      * operations.
 405      * @return this component's locking object
 406      */
 407     protected final Object getTreeLock() {
 408         return Component.LOCK;
 409     }
 410 
 411     /**
 412      * Reads the menu component from an object input stream.
 413      *
 414      * @param s the <code>ObjectInputStream</code> to read
 415      * @exception HeadlessException if
 416      *   <code>GraphicsEnvironment.isHeadless</code> returns
 417      *   <code>true</code>
 418      * @serial
 419      * @see java.awt.GraphicsEnvironment#isHeadless
 420      */
 421     private void readObject(ObjectInputStream s)
 422         throws ClassNotFoundException, IOException, HeadlessException
 423     {
 424         GraphicsEnvironment.checkHeadless();
 425 
 426         acc = AccessController.getContext();
 427 
 428         s.defaultReadObject();
 429 
 430         appContext = AppContext.getAppContext();
 431     }
 432 
 433     /**
 434      * Initialize JNI field and method IDs.
 435      */
 436     private static native void initIDs();
 437 
 438 
 439     /*
 440      * --- Accessibility Support ---
 441      *
 442      *  MenuComponent will contain all of the methods in interface Accessible,
 443      *  though it won't actually implement the interface - that will be up
 444      *  to the individual objects which extend MenuComponent.
 445      */
 446 
 447     AccessibleContext accessibleContext = null;
 448 
 449     /**
 450      * Gets the <code>AccessibleContext</code> associated with
 451      * this <code>MenuComponent</code>.
 452      *
 453      * The method implemented by this base class returns <code>null</code>.
 454      * Classes that extend <code>MenuComponent</code>
 455      * should implement this method to return the
 456      * <code>AccessibleContext</code> associated with the subclass.
 457      *
 458      * @return the <code>AccessibleContext</code> of this
 459      *     <code>MenuComponent</code>
 460      * @since 1.3
 461      */
 462     public AccessibleContext getAccessibleContext() {
 463         return accessibleContext;
 464     }
 465 
 466     /**
 467      * Inner class of <code>MenuComponent</code> used to provide
 468      * default support for accessibility.  This class is not meant
 469      * to be used directly by application developers, but is instead
 470      * meant only to be subclassed by menu component developers.
 471      * <p>
 472      * The class used to obtain the accessible role for this object.
 473      * @since 1.3
 474      */
 475     protected abstract class AccessibleAWTMenuComponent
 476         extends AccessibleContext
 477         implements java.io.Serializable, AccessibleComponent,
 478                    AccessibleSelection
 479     {
 480         /*
 481          * JDK 1.3 serialVersionUID
 482          */
 483         private static final long serialVersionUID = -4269533416223798698L;
 484 
 485         /**
 486          * Although the class is abstract, this should be called by
 487          * all sub-classes.
 488          */
 489         protected AccessibleAWTMenuComponent() {
 490         }
 491 
 492         // AccessibleContext methods
 493         //
 494 
 495         /**
 496          * Gets the <code>AccessibleSelection</code> associated with this
 497          * object which allows its <code>Accessible</code> children to be selected.
 498          *
 499          * @return <code>AccessibleSelection</code> if supported by object;
 500          *      else return <code>null</code>
 501          * @see AccessibleSelection
 502          */
 503         public AccessibleSelection getAccessibleSelection() {
 504             return this;
 505         }
 506 
 507         /**
 508          * Gets the accessible name of this object.  This should almost never
 509          * return <code>java.awt.MenuComponent.getName</code>, as that
 510          * generally isn't a localized name, and doesn't have meaning for the
 511          * user.  If the object is fundamentally a text object (e.g. a menu item), the
 512          * accessible name should be the text of the object (e.g. "save").
 513          * If the object has a tooltip, the tooltip text may also be an
 514          * appropriate String to return.
 515          *
 516          * @return the localized name of the object -- can be <code>null</code>
 517          *         if this object does not have a name
 518          * @see AccessibleContext#setAccessibleName
 519          */
 520         public String getAccessibleName() {
 521             return accessibleName;
 522         }
 523 
 524         /**
 525          * Gets the accessible description of this object.  This should be
 526          * a concise, localized description of what this object is - what
 527          * is its meaning to the user.  If the object has a tooltip, the
 528          * tooltip text may be an appropriate string to return, assuming
 529          * it contains a concise description of the object (instead of just
 530          * the name of the object - e.g. a "Save" icon on a toolbar that
 531          * had "save" as the tooltip text shouldn't return the tooltip
 532          * text as the description, but something like "Saves the current
 533          * text document" instead).
 534          *
 535          * @return the localized description of the object -- can be
 536          *     <code>null</code> if this object does not have a description
 537          * @see AccessibleContext#setAccessibleDescription
 538          */
 539         public String getAccessibleDescription() {
 540             return accessibleDescription;
 541         }
 542 
 543         /**
 544          * Gets the role of this object.
 545          *
 546          * @return an instance of <code>AccessibleRole</code>
 547          *     describing the role of the object
 548          * @see AccessibleRole
 549          */
 550         public AccessibleRole getAccessibleRole() {
 551             return AccessibleRole.AWT_COMPONENT; // Non-specific -- overridden in subclasses
 552         }
 553 
 554         /**
 555          * Gets the state of this object.
 556          *
 557          * @return an instance of <code>AccessibleStateSet</code>
 558          *     containing the current state set of the object
 559          * @see AccessibleState
 560          */
 561         public AccessibleStateSet getAccessibleStateSet() {
 562             return MenuComponent.this.getAccessibleStateSet();
 563         }
 564 
 565         /**
 566          * Gets the <code>Accessible</code> parent of this object.
 567          * If the parent of this object implements <code>Accessible</code>,
 568          * this method should simply return <code>getParent</code>.
 569          *
 570          * @return the <code>Accessible</code> parent of this object -- can
 571          *    be <code>null</code> if this object does not have an
 572          *    <code>Accessible</code> parent
 573          */
 574         public Accessible getAccessibleParent() {
 575             if (accessibleParent != null) {
 576                 return accessibleParent;
 577             } else {
 578                 MenuContainer parent = MenuComponent.this.getParent();
 579                 if (parent instanceof Accessible) {
 580                     return (Accessible) parent;
 581                 }
 582             }
 583             return null;
 584         }
 585 
 586         /**
 587          * Gets the index of this object in its accessible parent.
 588          *
 589          * @return the index of this object in its parent; -1 if this
 590          *     object does not have an accessible parent
 591          * @see #getAccessibleParent
 592          */
 593         public int getAccessibleIndexInParent() {
 594             return MenuComponent.this.getAccessibleIndexInParent();
 595         }
 596 
 597         /**
 598          * Returns the number of accessible children in the object.  If all
 599          * of the children of this object implement <code>Accessible</code>,
 600          * then this method should return the number of children of this object.
 601          *
 602          * @return the number of accessible children in the object
 603          */
 604         public int getAccessibleChildrenCount() {
 605             return 0; // MenuComponents don't have children
 606         }
 607 
 608         /**
 609          * Returns the nth <code>Accessible</code> child of the object.
 610          *
 611          * @param i zero-based index of child
 612          * @return the nth Accessible child of the object
 613          */
 614         public Accessible getAccessibleChild(int i) {
 615             return null; // MenuComponents don't have children
 616         }
 617 
 618         /**
 619          * Returns the locale of this object.
 620          *
 621          * @return the locale of this object
 622          */
 623         public java.util.Locale getLocale() {
 624             MenuContainer parent = MenuComponent.this.getParent();
 625             if (parent instanceof Component)
 626                 return ((Component)parent).getLocale();
 627             else
 628                 return java.util.Locale.getDefault();
 629         }
 630 
 631         /**
 632          * Gets the <code>AccessibleComponent</code> associated with
 633          * this object if one exists.  Otherwise return <code>null</code>.
 634          *
 635          * @return the component
 636          */
 637         public AccessibleComponent getAccessibleComponent() {
 638             return this;
 639         }
 640 
 641 
 642         // AccessibleComponent methods
 643         //
 644         /**
 645          * Gets the background color of this object.
 646          *
 647          * @return the background color, if supported, of the object;
 648          *     otherwise, <code>null</code>
 649          */
 650         public Color getBackground() {
 651             return null; // Not supported for MenuComponents
 652         }
 653 
 654         /**
 655          * Sets the background color of this object.
 656          * (For transparency, see <code>isOpaque</code>.)
 657          *
 658          * @param c the new <code>Color</code> for the background
 659          * @see Component#isOpaque
 660          */
 661         public void setBackground(Color c) {
 662             // Not supported for MenuComponents
 663         }
 664 
 665         /**
 666          * Gets the foreground color of this object.
 667          *
 668          * @return the foreground color, if supported, of the object;
 669          *     otherwise, <code>null</code>
 670          */
 671         public Color getForeground() {
 672             return null; // Not supported for MenuComponents
 673         }
 674 
 675         /**
 676          * Sets the foreground color of this object.
 677          *
 678          * @param c the new <code>Color</code> for the foreground
 679          */
 680         public void setForeground(Color c) {
 681             // Not supported for MenuComponents
 682         }
 683 
 684         /**
 685          * Gets the <code>Cursor</code> of this object.
 686          *
 687          * @return the <code>Curso</code>, if supported, of the object;
 688          *     otherwise, <code>null</code>
 689          */
 690         public Cursor getCursor() {
 691             return null; // Not supported for MenuComponents
 692         }
 693 
 694         /**
 695          * Sets the <code>Cursor</code> of this object.
 696          * <p>
 697          * The method may have no visual effect if the Java platform
 698          * implementation and/or the native system do not support
 699          * changing the mouse cursor shape.
 700          * @param cursor the new <code>Cursor</code> for the object
 701          */
 702         public void setCursor(Cursor cursor) {
 703             // Not supported for MenuComponents
 704         }
 705 
 706         /**
 707          * Gets the <code>Font</code> of this object.
 708          *
 709          * @return the <code>Font</code>,if supported, for the object;
 710          *     otherwise, <code>null</code>
 711          */
 712         public Font getFont() {
 713             return MenuComponent.this.getFont();
 714         }
 715 
 716         /**
 717          * Sets the <code>Font</code> of this object.
 718          *
 719          * @param f the new <code>Font</code> for the object
 720          */
 721         public void setFont(Font f) {
 722             MenuComponent.this.setFont(f);
 723         }
 724 
 725         /**
 726          * Gets the <code>FontMetrics</code> of this object.
 727          *
 728          * @param f the <code>Font</code>
 729          * @return the FontMetrics, if supported, the object;
 730          *              otherwise, <code>null</code>
 731          * @see #getFont
 732          */
 733         public FontMetrics getFontMetrics(Font f) {
 734             return null; // Not supported for MenuComponents
 735         }
 736 
 737         /**
 738          * Determines if the object is enabled.
 739          *
 740          * @return true if object is enabled; otherwise, false
 741          */
 742         public boolean isEnabled() {
 743             return true; // Not supported for MenuComponents
 744         }
 745 
 746         /**
 747          * Sets the enabled state of the object.
 748          *
 749          * @param b if true, enables this object; otherwise, disables it
 750          */
 751         public void setEnabled(boolean b) {
 752             // Not supported for MenuComponents
 753         }
 754 
 755         /**
 756          * Determines if the object is visible.  Note: this means that the
 757          * object intends to be visible; however, it may not in fact be
 758          * showing on the screen because one of the objects that this object
 759          * is contained by is not visible.  To determine if an object is
 760          * showing on the screen, use <code>isShowing</code>.
 761          *
 762          * @return true if object is visible; otherwise, false
 763          */
 764         public boolean isVisible() {
 765             return true; // Not supported for MenuComponents
 766         }
 767 
 768         /**
 769          * Sets the visible state of the object.
 770          *
 771          * @param b if true, shows this object; otherwise, hides it
 772          */
 773         public void setVisible(boolean b) {
 774             // Not supported for MenuComponents
 775         }
 776 
 777         /**
 778          * Determines if the object is showing.  This is determined by checking
 779          * the visibility of the object and ancestors of the object.  Note:
 780          * this will return true even if the object is obscured by another
 781          * (for example, it happens to be underneath a menu that was pulled
 782          * down).
 783          *
 784          * @return true if object is showing; otherwise, false
 785          */
 786         public boolean isShowing() {
 787             return true; // Not supported for MenuComponents
 788         }
 789 
 790         /**
 791          * Checks whether the specified point is within this object's bounds,
 792          * where the point's x and y coordinates are defined to be relative to
 793          * the coordinate system of the object.
 794          *
 795          * @param p the <code>Point</code> relative to the coordinate
 796          *     system of the object
 797          * @return true if object contains <code>Point</code>; otherwise false
 798          */
 799         public boolean contains(Point p) {
 800             return false; // Not supported for MenuComponents
 801         }
 802 
 803         /**
 804          * Returns the location of the object on the screen.
 805          *
 806          * @return location of object on screen -- can be <code>null</code>
 807          *     if this object is not on the screen
 808          */
 809         public Point getLocationOnScreen() {
 810             return null; // Not supported for MenuComponents
 811         }
 812 
 813         /**
 814          * Gets the location of the object relative to the parent in the form
 815          * of a point specifying the object's top-left corner in the screen's
 816          * coordinate space.
 817          *
 818          * @return an instance of <code>Point</code> representing the
 819          *    top-left corner of the object's bounds in the coordinate
 820          *    space of the screen; <code>null</code> if
 821          *    this object or its parent are not on the screen
 822          */
 823         public Point getLocation() {
 824             return null; // Not supported for MenuComponents
 825         }
 826 
 827         /**
 828          * Sets the location of the object relative to the parent.
 829          */
 830         public void setLocation(Point p) {
 831             // Not supported for MenuComponents
 832         }
 833 
 834         /**
 835          * Gets the bounds of this object in the form of a
 836          * <code>Rectangle</code> object.
 837          * The bounds specify this object's width, height, and location
 838          * relative to its parent.
 839          *
 840          * @return a rectangle indicating this component's bounds;
 841          *     <code>null</code> if this object is not on the screen
 842          */
 843         public Rectangle getBounds() {
 844             return null; // Not supported for MenuComponents
 845         }
 846 
 847         /**
 848          * Sets the bounds of this object in the form of a
 849          * <code>Rectangle</code> object.
 850          * The bounds specify this object's width, height, and location
 851          * relative to its parent.
 852          *
 853          * @param r a rectangle indicating this component's bounds
 854          */
 855         public void setBounds(Rectangle r) {
 856             // Not supported for MenuComponents
 857         }
 858 
 859         /**
 860          * Returns the size of this object in the form of a
 861          * <code>Dimension</code> object. The height field of
 862          * the <code>Dimension</code> object contains this object's
 863          * height, and the width field of the <code>Dimension</code>
 864          * object contains this object's width.
 865          *
 866          * @return a <code>Dimension</code> object that indicates the
 867          *         size of this component; <code>null</code>
 868          *         if this object is not on the screen
 869          */
 870         public Dimension getSize() {
 871             return null; // Not supported for MenuComponents
 872         }
 873 
 874         /**
 875          * Resizes this object.
 876          *
 877          * @param d - the <code>Dimension</code> specifying the
 878          *    new size of the object
 879          */
 880         public void setSize(Dimension d) {
 881             // Not supported for MenuComponents
 882         }
 883 
 884         /**
 885          * Returns the <code>Accessible</code> child, if one exists,
 886          * contained at the local coordinate <code>Point</code>.
 887          * If there is no <code>Accessible</code> child, <code>null</code>
 888          * is returned.
 889          *
 890          * @param p the point defining the top-left corner of the
 891          *    <code>Accessible</code>, given in the coordinate space
 892          *    of the object's parent
 893          * @return the <code>Accessible</code>, if it exists,
 894          *    at the specified location; else <code>null</code>
 895          */
 896         public Accessible getAccessibleAt(Point p) {
 897             return null; // MenuComponents don't have children
 898         }
 899 
 900         /**
 901          * Returns whether this object can accept focus or not.
 902          *
 903          * @return true if object can accept focus; otherwise false
 904          */
 905         public boolean isFocusTraversable() {
 906             return true; // Not supported for MenuComponents
 907         }
 908 
 909         /**
 910          * Requests focus for this object.
 911          */
 912         public void requestFocus() {
 913             // Not supported for MenuComponents
 914         }
 915 
 916         /**
 917          * Adds the specified focus listener to receive focus events from this
 918          * component.
 919          *
 920          * @param l the focus listener
 921          */
 922         public void addFocusListener(java.awt.event.FocusListener l) {
 923             // Not supported for MenuComponents
 924         }
 925 
 926         /**
 927          * Removes the specified focus listener so it no longer receives focus
 928          * events from this component.
 929          *
 930          * @param l the focus listener
 931          */
 932         public void removeFocusListener(java.awt.event.FocusListener l) {
 933             // Not supported for MenuComponents
 934         }
 935 
 936         // AccessibleSelection methods
 937         //
 938 
 939         /**
 940          * Returns the number of <code>Accessible</code> children currently selected.
 941          * If no children are selected, the return value will be 0.
 942          *
 943          * @return the number of items currently selected
 944          */
 945          public int getAccessibleSelectionCount() {
 946              return 0;  //  To be fully implemented in a future release
 947          }
 948 
 949         /**
 950          * Returns an <code>Accessible</code> representing the specified
 951          * selected child in the object.  If there isn't a selection, or there are
 952          * fewer children selected than the integer passed in, the return
 953          * value will be <code>null</code>.
 954          * <p>Note that the index represents the i-th selected child, which
 955          * is different from the i-th child.
 956          *
 957          * @param i the zero-based index of selected children
 958          * @return the i-th selected child
 959          * @see #getAccessibleSelectionCount
 960          */
 961          public Accessible getAccessibleSelection(int i) {
 962              return null;  //  To be fully implemented in a future release
 963          }
 964 
 965         /**
 966          * Determines if the current child of this object is selected.
 967          *
 968          * @return true if the current child of this object is selected;
 969          *    else false
 970          * @param i the zero-based index of the child in this
 971          *      <code>Accessible</code> object
 972          * @see AccessibleContext#getAccessibleChild
 973          */
 974          public boolean isAccessibleChildSelected(int i) {
 975              return false;  //  To be fully implemented in a future release
 976          }
 977 
 978         /**
 979          * Adds the specified <code>Accessible</code> child of the object
 980          * to the object's selection.  If the object supports multiple selections,
 981          * the specified child is added to any existing selection, otherwise
 982          * it replaces any existing selection in the object.  If the
 983          * specified child is already selected, this method has no effect.
 984          *
 985          * @param i the zero-based index of the child
 986          * @see AccessibleContext#getAccessibleChild
 987          */
 988          public void addAccessibleSelection(int i) {
 989                //  To be fully implemented in a future release
 990          }
 991 
 992         /**
 993          * Removes the specified child of the object from the object's
 994          * selection.  If the specified item isn't currently selected, this
 995          * method has no effect.
 996          *
 997          * @param i the zero-based index of the child
 998          * @see AccessibleContext#getAccessibleChild
 999          */
1000          public void removeAccessibleSelection(int i) {
1001                //  To be fully implemented in a future release
1002          }
1003 
1004         /**
1005          * Clears the selection in the object, so that no children in the
1006          * object are selected.
1007          */
1008          public void clearAccessibleSelection() {
1009                //  To be fully implemented in a future release
1010          }
1011 
1012         /**
1013          * Causes every child of the object to be selected
1014          * if the object supports multiple selections.
1015          */
1016          public void selectAllAccessibleSelection() {
1017                //  To be fully implemented in a future release
1018          }
1019 
1020     } // inner class AccessibleAWTComponent
1021 
1022     /**
1023      * Gets the index of this object in its accessible parent.
1024      *
1025      * @return -1 if this object does not have an accessible parent;
1026      *      otherwise, the index of the child in its accessible parent.
1027      */
1028     int getAccessibleIndexInParent() {
1029         MenuContainer localParent = parent;
1030         if (!(localParent instanceof MenuComponent)) {
1031             // MenuComponents only have accessible index when inside MenuComponents
1032             return -1;
1033         }
1034         MenuComponent localParentMenu = (MenuComponent)localParent;
1035         return localParentMenu.getAccessibleChildIndex(this);
1036     }
1037 
1038     /**
1039      * Gets the index of the child within this MenuComponent.
1040      *
1041      * @param child MenuComponent whose index we are interested in.
1042      * @return -1 if this object doesn't contain the child,
1043      *      otherwise, index of the child.
1044      */
1045     int getAccessibleChildIndex(MenuComponent child) {
1046         return -1; // Overridden in subclasses.
1047     }
1048 
1049     /**
1050      * Gets the state of this object.
1051      *
1052      * @return an instance of <code>AccessibleStateSet</code>
1053      *     containing the current state set of the object
1054      * @see AccessibleState
1055      */
1056     AccessibleStateSet getAccessibleStateSet() {
1057         AccessibleStateSet states = new AccessibleStateSet();
1058         return states;
1059     }
1060 
1061 }