/* MenuComponent.java -- Superclass of all AWT menu components
   Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005, 2006
   Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package java.awt;

import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.peer.MenuComponentPeer;
import java.io.Serializable;
import java.util.Locale;

import javax.accessibility.Accessible;
import javax.accessibility.AccessibleComponent;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
import javax.accessibility.AccessibleSelection;
import javax.accessibility.AccessibleStateSet;

/**
  * This is the superclass of all menu AWT widgets. 
  *
  * @author Aaron M. Renn (arenn@urbanophile.com)
  * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
  */
public abstract class MenuComponent implements Serializable
{

//Serialization Constant
  private static final long serialVersionUID = -4536902356223894379L;

  /**
   * The font for this component.
   *
   * @see #getFont()
   * @see #setFont(java.awt.Font)
   * @serial the component's font.
   */
  private Font font;

  /**
   * The name of the component.
   *
   * @see #getName()
   * @see #setName(String)
   * @serial the component's name.
   */
  private String name;

  /**
   * The parent of this component.
   *
   * @see #getParent()
   * @see #setParent(java.awt.MenuContainer)
   * @serial ignored.
   */
  transient MenuContainer parent;

  /**
   * The native peer for this component.
   *
   * @see #getPeer()
   * @see #setPeer(java.awt.peer.MenuComponentPeer)
   * @serial ignored.
   */
  transient MenuComponentPeer peer;

  /**
   * The synchronization locking object for this component.
   *
   * @serial ignored.
   */
  private transient Object tree_lock = this;

  /**
   * The toolkit for this object.
   *
   * @see #getToolkit()
   * @serial ignored.
   */
  private static transient Toolkit toolkit = Toolkit.getDefaultToolkit();

  /**
   * The accessible context for this component.
   *
   * @see #getAccessibleContext()
   * @serial the accessibility information for this component.
   */
  AccessibleContext accessibleContext;

  /**
   * Was the name of the component set?  This value defaults
   * to false and becomes true after a call to <code>setName()</code>.
   * Please note that this does not guarantee that name will then
   * be non-null, as this may be the value passed to <code>setName()</code>.
   *
   * @see #setName(String)
   * @serial true if the name value has been explicitly set by calling
   *         <code>setName()</code>.
   */
  private boolean nameExplicitlySet;

  /**
   * Does this component handle new events?  Events will be handled
   * by this component if this is true.  Otherwise, they will be forwarded
   * up the component hierarchy.  This implementation does not use this
   * variable; it is merely provided for serialization compatability.
   *
   * @see #dispatchEvent(AWTEvent)
   * @serial true if events are to be processed locally.  Unused.
   */
  private boolean newEventsOnly;

  /**
   * The focus listener chain handler which deals with focus events for
   * the accessible context of this component.
   *
   * @see AccessibleAWTMenuComponent#addFocusListener(java.awt.event.FocusListener)
   * @serial ignored.
   * This is package-private to avoid an accessor method.
   */
  transient FocusListener focusListener;

  /**
   * Default constructor for subclasses.
   *
   * @throws HeadlessException ff GraphicsEnvironment.isHeadless() is true
   */
  public MenuComponent()
  {
    if (GraphicsEnvironment.isHeadless())
      throw new HeadlessException();
  }

/**
  * Returns the font in use for this component.
  *
  * @return the font for this component
  */
  public Font getFont()
  {
    if (font != null)
      return font;

    if (parent != null)
      return parent.getFont();

    return null;
  }

  /**
   * Sets the font for this component to the specified font.
   *
   * @param font the new font for this component
   */
  public void setFont(Font font)
  {
    this.font = font;
  }

  /**
   * Returns the name of this component.
   *
   * @return the name of this component
   */
  public String getName()
  {
    if (name == null && ! nameExplicitlySet)
      name = generateName();
    return name;
  }
  
  /**
   * Subclasses should override this to return unique component names like
   * "menuitem0".
   *
   * @return the generated name for this menu component
   */
  String generateName()
  {
    // MenuComponent is abstract.
    return null;
  }

  /**
   * Sets the name of this component to the specified name.
   *
   * @param name the new name of this component
   */
  public void setName(String name)
  {
    this.name = name;
    nameExplicitlySet = true;
  }

  /**
   * Returns the parent of this component.
   * 
   * @return the parent of this component
   */
  public MenuContainer getParent()
  {
    return parent;
  } 

  /**
   * Sets the parent of this component.
   *
   * @param parent the parent to set
   */
  final void setParent(MenuContainer parent)
  {
    this.parent = parent;
  }

  /**
   * Returns the native windowing system peer for this component.
   *
   * @return the peer for this component
   *
   * @deprecated
   */
  public MenuComponentPeer getPeer()
  {
    return peer;
  }

  /**
   * Sets the peer for this component.
   *
   * @param peer the peer to set
   */
  final void setPeer(MenuComponentPeer peer)
  {
    this.peer = peer;
  }

  /**
   * Destroys this component's native peer
   */
  public void removeNotify()
  {
    if (peer != null)
      peer.dispose();
    peer = null;
  }

  /**
   * Returns the toolkit in use for this component.
   *
   * @return the toolkit for this component
   */
  final Toolkit getToolkit()
  {
    return toolkit;
  }

  /**
   * Returns the object used for synchronization locks on this component
   * when performing tree and layout functions.
   *
   * @return the synchronization lock for this component
   */
  protected final Object getTreeLock()
  {
    return tree_lock;
  }

  /**
   * Sets the sync lock object for this component.
   *
   * @param treeLock the sync lock to set
   */
  final void setTreeLock(Object treeLock)
  {
    this.tree_lock = treeLock;
  }

  /**
   * AWT 1.0 event dispatcher.
   *
   * @return true if the event was dispatched, false otherwise
   *
   * @deprecated Deprecated in favor of <code>dispatchEvent()</code>.
   */
  public boolean
  postEvent(Event event)
  {
    boolean retVal = false;
    MenuContainer parent = getParent();
    if (parent != null)
      retVal = parent.postEvent(event);

    return retVal;
  }

  /**
   * Sends this event to this component or a subcomponent for processing.
   *
   * @param event The event to dispatch
   */
  public final void dispatchEvent(AWTEvent event)
  {
    // Convert AWT 1.1 event to AWT 1.0 event.
    Event oldStyleEvent = Component.translateEvent(event);
    if (oldStyleEvent != null)
      {
        postEvent(oldStyleEvent);
      }

    // See comment in Component.dispatchEvent().
    dispatchEventImpl(event);
  }

  /**
   * Implementation of dispatchEvent. Allows trusted package classes
   * to dispatch additional events first.  This implementation first
   * translates <code>event</code> to an AWT 1.0 event and sends the
   * result to {@link #postEvent}.  The event is then
   * passed on to {@link #processEvent} for local processing.
   *
   * @param event the event to dispatch
   */
  void dispatchEventImpl(AWTEvent event)
  {
    // Do local processing.
    processEvent(event);
  }

  /**
   * Processes the specified event.  In this class, this method simply
   * calls one of the more specific event handlers.
   * 
   * @param event the event to process
   */
  protected void processEvent(AWTEvent event)
  {
    // Pass a focus event to the focus listener for
    // the accessibility context.
    if (event instanceof FocusEvent)
      {
        if (focusListener != null)
          {
            switch (event.id)
            {
            case FocusEvent.FOCUS_GAINED:
              focusListener.focusGained((FocusEvent) event);
              break;
            case FocusEvent.FOCUS_LOST:
              focusListener.focusLost((FocusEvent) event);
              break;
            }
          }
      }
  }

  /**
   * Returns a string representation of this component.
   *
   * @return a string representation of this component
   */
  public String toString()
  {
    return getClass().getName() + "[" + paramString() + "]";
  }

  /**
   * Returns a debugging string for this component
   */
  protected String paramString()
  {
    return "name=" + getName();
  }

  /**
   * Gets the AccessibleContext associated with this <code>MenuComponent</code>.
   * As an abstract class, we return null.  Concrete subclasses should return
   * their implementation of the accessibility context.
   *
   * @return null
   */
  public AccessibleContext getAccessibleContext()
  {
    return null;
  }

  /**
   * This class provides a base for the accessibility support of menu
   * components.
   *
   * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
   */
  protected abstract class AccessibleAWTMenuComponent
    extends AccessibleContext
    implements Serializable, AccessibleComponent, AccessibleSelection
  {

    /**
     * Compatible with JDK 1.4.2 revision 5
     */
    private static final long serialVersionUID = -4269533416223798698L;

    /**
     * This is the default constructor.  It should be called by
     * concrete subclasses to ensure necessary groundwork is completed.
     */
    protected AccessibleAWTMenuComponent()
    {
      // Nothing to do here.
    }

    /**
     * Replaces or supplements the component's selection with the
     * <code>Accessible</code> child at the supplied index.  If
     * the component supports multiple selection, the child is
     * added to the current selection.  Otherwise, the current
     * selection becomes the specified child.  If the child is
     * already selected, nothing happens.
     * <br />
     * <br />
     * As the existence of children can not be determined from
     * this abstract class, the implementation of this method
     * is left to subclasses.
     *
     * @param index the index of the specified child within a
     *        zero-based list of the component's children
     */
    public void addAccessibleSelection(int index)
    {
      // Subclasses with children should implement this.
    }

    /**
     * Registers the specified focus listener to receive
     * focus events from this component.
     *
     * @param listener the new focus listener
     */
    public void addFocusListener(FocusListener listener)
    {
       // Chain the new focus listener to the existing chain
       // of focus listeners.  Each new focus listener is
       // coupled via multicasting to the existing chain.
      focusListener = AWTEventMulticaster.add(focusListener, listener);
    }

    /**
     * Clears the component's current selection.  Following
     * the calling of this method, no children of the component
     * will be selected.
     * <br />
     * <br />
     * As the existence of children can not be determined from
     * this abstract class, the implementation of this method
     * is left to subclasses.
     */
    public void clearAccessibleSelection()
    {
      // Nothing to do here.
    }

    /**
     * Returns true if the specified point lies within the
     * component.  The supplied co-ordinates are assumed to
     * be relative to the co-ordinate system of the component
     * itself.  Thus, the point (0,0) is the upper left corner
     * of this component.
     * <br />
     * <br />
     * Please note that this method depends on a correctly implemented
     * version of the <code>getBounds()</code> method.  Subclasses
     * must provide the bounding rectangle via <code>getBounds()</code>
     * in order for this method to work.  
     *
     * @param point the point to check against this component
     * @return true if the point is within this component
     * @see #getBounds()
     */
    public boolean contains(Point point)
    {
      // We can simply return the result of a
      // test for containment in the bounding rectangle.
      return getBounds().contains(point);
    }

    /**
     * Returns the <code>Accessible</code> child of this component present
     * at the specified point.  The supplied co-ordinates are
     * assumed to be relative to the co-ordinate system of this
     * component (the parent of any returned accessible).  Thus,
     * the point (0,0) is the upper left corner of this menu
     * component.
     * <br />
     * <br />
     * As the existence of children can not be determined from
     * this abstract class, the implementation of this method
     * is left to subclasses.
     * 
     * @param point the point at which the returned accessible
     *        is located
     * @return null
     */
    public Accessible getAccessibleAt(Point point)
    {
      return null;
    }

    /**
     * Returns the <code>Accessible</code> child at the supplied
     * index within the list of children of this component.
     * <br />
     * <br />
     * As the existence of children can not be determined from
     * this abstract class, the implementation of this method
     * is left to subclasses.
     *
     * @param index the index of the <code>Accessible</code> child
     *        to retrieve
     *
     * @return null
     */
    public Accessible getAccessibleChild(int index)
    {
      return null;
    }

    /**
     * Returns the number of children of this component which
     * implement the <code>Accessible</code> interface.  If
     * all children of this component are accessible, then
     * the returned value will be the same as the number of
     * children.
     * <br />
     * <br />
     *
     * @return 0
     */
    public int getAccessibleChildrenCount()
    {
      return 0;
    }

    /**
     * Retrieves the <code>AccessibleComponent</code> associated
     * with this accessible context and its component.  As the
     * context itself implements <code>AccessibleComponent</code>,
     * this is the return value.
     *
     * @return the context itself
     */
    public AccessibleComponent getAccessibleComponent()
    {
      return this;
    }

    /**
     * Returns the accessible name for this menu component.  This
     * is the name given to the component, which may be null if
     * not set using <code>setName()</code>.
     * <br />
     * <br />
     * The name is not the most appropriate description of this
     * object.  Subclasses should preferably provide a more
     * accurate description.  For example, a File menu could
     * have the description `Lists commands related to the
     * file system'.
     *
     * @return a description of the component.  Currently,
     *         this is just the contents of the name property
     *
     * @see MenuComponent#setName(String)
     */
    public String getAccessibleDescription()
    {
      return MenuComponent.this.getName();
    }

    /**
     * Retrieves the index of this component within its parent.
     * If no parent exists, -1 is returned.
     *
     * @return -1 as the parent, a <code>MenuContainer</code>
     *         is not <code>Accessible</code>
     */
    public int getAccessibleIndexInParent()
    {
      return -1;
    }

    /**
     * Returns the accessible name of this component.  This
     * is the name given to the component, which may be null if
     * not set using <code>setName()</code>.
     * <br />
     * <br />
     * The name property is not the most suitable string to return
     * for this method.  The string should be localized, and
     * relevant to the operation of the component.  For example,
     * it could be the text of a menu item.  However, this can
     * not be used at this level of abstraction, so it is the
     * responsibility of subclasses to provide a more appropriate
     * name.
     *
     * @return a localized name for this component.  Currently, this
     *         is just the contents of the name property
     *
     * @see MenuComponent#setName(String)
     */
    public String getAccessibleName()
    {
      return MenuComponent.this.getName();
    }

    /**
     * Returns the <code>Accessible</code> parent of this component.
     * As the parent of a <code>MenuComponent</code> is a
     * <code>MenuContainer</code>, which doesn't implement
     * <code>Accessible</code>, this method returns null.
     *
     * @return null
     */
    public Accessible getAccessibleParent()
    {
      return null;
    }

    /**
     * Returns the accessible role of this component.
     * <br />
     * <br />
     * The abstract implementation of this method returns
     * <code>AccessibleRole.AWT_COMPONENT</code>,
     * as the abstract component has no specific role.  This
     * method should be overridden by concrete subclasses, so
     * as to return an appropriate role for the component.
     *
     * @return <code>AccessibleRole.AWT_COMPONENT</code>
     */
    public AccessibleRole getAccessibleRole()
    {
      return AccessibleRole.AWT_COMPONENT;
    }

    /**
     * Retrieves the <code>AccessibleSelection</code> associated
     * with this accessible context and its component.  As the
     * context itself implements <code>AccessibleSelection</code>,
     * this is the return value.
     *
     * @return the context itself
     */
    public AccessibleSelection getAccessibleSelection()
    {
      return this;
    }

    /**
     * Retrieves the <code>Accessible</code> selected child
     * at the specified index.  If there are no selected children
     * or the index is outside the range of selected children,
     * null is returned.  Please note that the index refers
     * to the index of the child in the list of <strong>selected
     * children</strong>, and not the index of the child in
     * the list of all <code>Accessible</code> children.
     * <br />
     * <br />
     * As the existence of children can not be determined from
     * this abstract class, the implementation of this method
     * is left to subclasses.
     *
     * @param index the index of the selected <code>Accessible</code>
     *        child
     */
    public Accessible getAccessibleSelection(int index)
    {
      return null;
    }

    /**
     * Returns a count of the number of <code>Accessible</code>
     * children of this component which are currently selected.
     * If there are no children currently selected, 0 is returned.
     * <br />
     * <br />
     * As the existence of children can not be determined from
     * this abstract class, the implementation of this method
     * is left to subclasses.
     *
     * @return 0
     */
    public int getAccessibleSelectionCount()
    {
      return 0;
    }

    /**
     * Retrieves the current state of this component
     * in an accessible form.  For example, a given component
     * may be visible, selected, disabled, etc.
     * <br />
     * <br />
     * As this class tells us virtually nothing about the component,
     * except for its name and font, no state information can be
     * provided.  This implementation thus returns an empty
     * state set, and it is left to concrete subclasses to provide
     * a more acceptable and relevant state set.  Changes to these
     * properties also need to be handled using
     * <code>PropertyChangeListener</code>s.
     *
     * @return an empty <code>AccessibleStateSet</code>
     */
    public AccessibleStateSet getAccessibleStateSet()
    {
      return new AccessibleStateSet();
    }

    /**
     * Returns the background color of the component, or null
     * if this property is unsupported.
     * <br />
     * <br />
     * This abstract class knows nothing about how the component
     * is drawn on screen, so this method simply returns the
     * default system background color used for rendering menus.
     * Concrete subclasses which handle the drawing of an onscreen
     * menu component should override this method and provide
     * the appropriate information.
     *
     * @return the default system background color for menus
     *
     * @see #setBackground(java.awt.Color)
     */
    public Color getBackground()
    {
      return SystemColor.menu;
    }

    /**
     * Returns a <code>Rectangle</code> which represents the
     * bounds of this component.  The returned rectangle has the
     * height and width of the component's bounds, and is positioned
     * at a location relative to this component's parent, the
     * <code>MenuContainer</code>.  null is returned if bounds
     * are not supported by the component.
     * <br />
     * <br />
     * This abstract class knows nothing about how the component
     * is drawn on screen, so this method simply returns null.
     * Concrete subclasses which handle the drawing of an onscreen
     * menu component should override this method and provide
     * the appropriate information.
     *
     * @return null
     *
     * @see #setBounds(java.awt.Rectangle)
     */
    public Rectangle getBounds()
    {
      return null;
    }

    /**
     * Returns the <code>Cursor</code> displayed when the pointer
     * is positioned over this component.  Alternatively, null
     * is returned if the component doesn't support the cursor
     * property.
     * <br />
     * <br />
     * This abstract class knows nothing about how the component
     * is drawn on screen, so this method simply returns the default
     * system cursor.  Concrete subclasses which handle the drawing
     * of an onscreen menu component may override this method and provide
     * the appropriate information.
     *
     * @return the default system cursor
     *
     * @see #setCursor(java.awt.Cursor)
     */
    public Cursor getCursor()
    {
      return Cursor.getDefaultCursor();
    }

    /**
     * Returns the <code>Font</code> used for text created by this component.
     *
     * @return the current font
     *
     * @see #setFont(java.awt.Font)
     */
    public Font getFont()
    {
      return MenuComponent.this.getFont();
    }

    /**
     * Retrieves information on the rendering and metrics of the supplied
     * font.  If font metrics are not supported by this component, null
     * is returned.
     * <br />
     * <br />
     * The abstract implementation of this method simply uses the toolkit
     * to obtain the <code>FontMetrics</code>.  Concrete subclasses may
     * find it more efficient to invoke their peer class directly, if one
     * is available.
     *
     * @param font the font about which to retrieve rendering and metric
     *        information
     *
     * @return the metrics of the given font, as provided by the system
     *         toolkit
     *
     * @throws NullPointerException if the supplied font was null
     */
    public FontMetrics getFontMetrics(Font font)
    {
      return MenuComponent.this.getToolkit().getFontMetrics(font);
    }

    /**
     * Returns the foreground color of the component, or null
     * if this property is unsupported.
     * <br />
     * <br />
     * This abstract class knows nothing about how the component
     * is drawn on screen, so this method simply returns the
     * default system text color used for rendering menus.
     * Concrete subclasses which handle the drawing of an onscreen
     * menu component should override this method and provide
     * the appropriate information.
     *
     * @return the default system text color for menus
     *
     * @see #setForeground(java.awt.Color)
     */
    public Color getForeground()
    {
      return SystemColor.menuText;
    }

    /**
     * Returns the locale currently in use by this component.
     * <br />
     * <br />
     * This abstract class has no property relating to the
     * locale used by the component, so this method simply
     * returns the default locale for the current instance
     * of the Java Virtual Machine (JVM).  Concrete subclasses
     * which maintain such a property should override this method
     * and provide the locale information more accurately.
     *
     * @return the default locale for this JVM instance
     */
    public Locale getLocale()
    {
      return Locale.getDefault();
    }

    /**
     * Returns the location of the component, with co-ordinates
     * relative to the parent component and using the co-ordinate
     * space of the screen.  Thus, the point (0,0) is the upper
     * left corner of the parent component.
     * <br />
     * <br />
     * Please note that this method depends on a correctly implemented
     * version of the <code>getBounds()</code> method.  Subclasses
     * must provide the bounding rectangle via <code>getBounds()</code>
     * in order for this method to work.  
     *
     * @return the location of the component, relative to its parent
     *
     * @see #setLocation(java.awt.Point)
     */
    public Point getLocation()
    {
      // Simply return the location of the bounding rectangle.
      return getBounds().getLocation();
    }

    /**
     * Returns the location of the component, with co-ordinates
     * relative to the screen.  Thus, the point (0,0) is the upper
     * left corner of the screen.  null is returned if the component
     * is either not on screen or if this property is unsupported.
     * <br />
     * <br />
     * This abstract class knows nothing about how the component
     * is drawn on screen, so this method simply returns null.
     * Concrete subclasses which handle the drawing of an onscreen
     * menu component should override this method and provide
     * the appropriate information.
     *
     * @return the location of the component, relative to the screen
     */
    public Point getLocationOnScreen()
    {
      return null;
    }

    /**
     * Returns the size of the component.
     * <br />
     * <br />
     * Please note that this method depends on a correctly implemented
     * version of the <code>getBounds()</code> method.  Subclasses
     * must provide the bounding rectangle via <code>getBounds()</code>
     * in order for this method to work.  
     *
     * @return the size of the component
     *
     * @see #setSize(java.awt.Dimension)
     */
    public Dimension getSize()
    {
      // Simply return the size of the bounding rectangle.
      return getBounds().getSize();
    }

    /**
     * Returns true if the accessible child specified by the supplied index
     * is currently selected.
     * <br />
     * <br />
     * As the existence of children can not be determined from
     * this abstract class, the implementation of this method
     * is left to subclasses.
     *
     * @param index the index of the accessible child to check for selection
     *
     * @return false
     */
    public boolean isAccessibleChildSelected(int index)
    {
      return false;
    }

    /**
     * Returns true if this component is currently enabled.
     * <br />
     * <br />
     * As this abstract component has no properties related to
     * its enabled or disabled state, the implementation of this
     * method is left to subclasses.
     *
     * @return false
     *
     * @see #setEnabled(boolean)
     */
    public boolean isEnabled()
    {
      return false;
    }

    /**
     * Returns true if this component is included in the traversal
     * of the current focus from one component to the other.
     * <br />
     * <br />
     * As this abstract component has no properties related to
     * its ability to accept the focus, the implementation of this
     * method is left to subclasses.
     *
     * @return false
     */
    public boolean isFocusTraversable()
    {
      return false;
    }

    /**
     * Returns true if the component is being shown on screen.
     * A component is determined to be shown if it is visible,
     * and each parent component is also visible.  Please note
     * that, even when a component is showing, it may still be
     * obscured by other components in front.  This method only
     * determines if the component is being drawn on the screen.
     * <br />
     * <br />
     * As this abstract component and its parent have no properties
     * relating to visibility, the implementation of this method is
     * left to subclasses.
     *
     * @return false
     *
     * @see #isVisible()
     */
    public boolean isShowing()
    {
      return false;
    }

    /**
     * Returns true if the component is visible.  A component may
     * be visible but not drawn on the screen if one of its parent
     * components is not visible.  To determine if the component is
     * actually drawn on screen, <code>isShowing()</code> should be
     * used.
     * <br />
     * <br />
     * As this abstract component has no properties relating to its
     * visibility, the implementation of this method is left to subclasses.
     *
     * @return false
     *
     * @see #isShowing()
     * @see #setVisible(boolean)
     */
    public boolean isVisible()
    {
      return false;
    }

    /**
     * Removes the accessible child specified by the supplied index from
     * the list of currently selected children.  If the child specified
     * is not selected, nothing happens.
     * <br />
     * <br />
     * As the existence of children can not be determined from
     * this abstract class, the implementation of this method
     * is left to subclasses.
     *
     * @param index the index of the <code>Accessible</code> child
     */
    public void removeAccessibleSelection(int index)
    {
      // Subclasses with children should implement this.
    }

    /**
     * Removes the specified focus listener from the list of registered
     * focus listeners for this component.
     *
     * @param listener the listener to remove
     */
    public void removeFocusListener(FocusListener listener)
    {
      // Remove the focus listener from the chain.
      focusListener = AWTEventMulticaster.remove(focusListener, listener);
    }

    /**
     * Requests that this component gains focus.  This depends on the
     * component being focus traversable.
     * <br />
     * <br />
     * As this abstract component has no properties relating to its
     * focus traversability, or access to a peer with request focusing
     * abilities, the implementation of this method is left to subclasses.
     */
    public void requestFocus()
    {
      // Ignored.
    }

    /**
     * Selects all <code>Accessible</code> children of this component which
     * it is possible to select.  The component needs to support multiple
     * selections.
     * <br />
     * <br />
     * This abstract component provides a simplistic implementation of this
     * method, which ignores the ability of the component to support multiple
     * selections and simply uses <code>addAccessibleSelection</code> to
     * add each <code>Accessible</code> child to the selection.  The last
     * <code>Accessible</code> component is thus selected for components
     * which don't support multiple selections.  Concrete implementations should
     * override this with a more appopriate and efficient implementation, which
     * properly takes into account the ability of the component to support multiple
     * selections. 
     */
    public void selectAllAccessibleSelection()
    {
      // Simply call addAccessibleSelection() on all accessible children.
      for (int a = 0; a < getAccessibleChildrenCount(); ++a)
        {
          addAccessibleSelection(a);
        }
    }

    /**
     * Sets the background color of the component to that specified.
     * Unspecified behaviour occurs when null is given as the new
     * background color.
     * <br />
     * <br />
     * This abstract class knows nothing about how the component
     * is drawn on screen, so this method simply ignores the supplied
     * color and continues to use the default system color.   
     * Concrete subclasses which handle the drawing of an onscreen
     * menu component should override this method and provide
     * the appropriate information.
     *
     * @param color the new color to use for the background
     *
     * @see #getBackground()
     */
    public void setBackground(Color color)
    {
      // Ignored.
    }

    /**
     * Sets the height and width of the component, and its position
     * relative to this component's parent, to the values specified
     * by the supplied rectangle.  Unspecified behaviour occurs when
     * null is given as the new bounds.
     * <br />
     * <br />
     * This abstract class knows nothing about how the component
     * is drawn on screen, so this method simply ignores the new
     * rectangle and continues to return null from <code>getBounds()</code>.
     * Concrete subclasses which handle the drawing of an onscreen
     * menu component should override this method and provide
     * the appropriate information.
     *
     * @param rectangle a rectangle which specifies the new bounds of
     *        the component
     *
     * @see #getBounds()
     */
    public void setBounds(Rectangle rectangle)
    {
      // Ignored.
    }

    /**
     * Sets the <code>Cursor</code> used when the pointer is positioned over the
     * component.  Unspecified behaviour occurs when null is given as the new
     * cursor.
     * <br />
     * <br />
     * This abstract class knows nothing about how the component
     * is drawn on screen, so this method simply ignores the new cursor
     * and continues to return the default system cursor.  Concrete
     * subclasses which handle the drawing of an onscreen menu component
     * may override this method and provide the appropriate information.
     *
     * @param cursor the new cursor to use
     *
     * @see #getCursor()
     */
    public void setCursor(Cursor cursor)
    {
      // Ignored.
    }

    /**
     * Sets the enabled/disabled state of this component.
     * <br />
     * <br />
     * As this abstract component has no properties related to
     * its enabled or disabled state, the implementation of this
     * method is left to subclasses.
     *
     * @param enabled true if the component should be enabled,
     *        false otherwise
     *
     * @see #isEnabled()
     */
    public void setEnabled(boolean enabled)
    {
      // Ignored.
    }

    /**
     * Sets the <code>Font</code> used for text created by this component.
     * Unspecified behaviour occurs when null is given as the new
     * font.
     *
     * @param font the new font to use for text.
     * @see #getFont()
     */
    public void setFont(Font font)
    {
      // Call the method of the enclosing component.
      MenuComponent.this.setFont(font);
    }

    /**
     * Sets the foreground color of the component to that specified.
     * Unspecified behaviour occurs when null is given as the new
     * background color.
     * <br />
     * <br />
     * This abstract class knows nothing about how the component
     * is drawn on screen, so this method simply ignores the supplied
     * color and continues to return the default system text color used
     * for rendering menus.
     * Concrete subclasses which handle the drawing of an onscreen
     * menu component should override this method and provide
     * the appropriate information.
     *
     * @param color the new foreground color
     *
     * @see #getForeground()
     */
    public void setForeground(Color color)
    {
      // Ignored.
    }

    /**
     * Sets the location of the component, with co-ordinates
     * relative to the parent component and using the co-ordinate
     * space of the screen.  Thus, the point (0,0) is the upper
     * left corner of the parent component.
     * <br />
     * <br />
     * Please note that this method depends on a correctly implemented
     * version of the <code>getBounds()</code> method.  Subclasses
     * must provide the bounding rectangle via <code>getBounds()</code>
     * in order for this method to work.  
     *
     * @param point the location of the component, relative to its parent
     *
     * @see #getLocation()
     */
    public void setLocation(Point point)
    {
      getBounds().setLocation(point);
    }

    /**
     * Sets the size of the component.
     * <br />
     * <br />
     * Please note that this method depends on a correctly implemented
     * version of the <code>getBounds()</code> method.  Subclasses
     * must provide the bounding rectangle via <code>getBounds()</code>
     * in order for this method to work.  
     *
     * @param size the new size of the component
     *
     * @see #getSize()
     */
    public void setSize(Dimension size)
    {
      getBounds().setSize(size);
    }

    /**
     * Sets the visibility state of the component.  A component may
     * be visible but not drawn on the screen if one of its parent
     * components is not visible.  To determine if the component is
     * actually drawn on screen, <code>isShowing()</code> should be
     * used.
     * <br />
     * <br />
     * As this abstract component has no properties relating to its
     * visibility, the implementation of this method is left to subclasses.
     *
     * @param visibility the new visibility of the component -- true if
     *        the component is visible, false if not
     *
     * @see #isShowing()
     * @see #isVisible()
     */
    public void setVisible(boolean visibility)
    {
      // Ignored.
    }

  }

}
