/* JComponent.java -- Every component in swing inherits from this class.
   Copyright (C) 2002, 2004, 2005  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., 59 Temple Place, Suite 330, Boston, MA
02111-1307 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 javax.swing;

import java.awt.AWTEvent;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.dnd.DropTarget;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ContainerEvent;
import java.awt.event.ContainerListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.geom.Rectangle2D;
import java.awt.image.ImageObserver;
import java.awt.peer.LightweightPeer;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyVetoException;
import java.beans.VetoableChangeListener;
import java.io.Serializable;
import java.util.EventListener;
import java.util.Hashtable;
import java.util.Locale;

import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleKeyBinding;
import javax.accessibility.AccessibleRole;
import javax.accessibility.AccessibleStateSet;
import javax.swing.border.Border;
import javax.swing.event.AncestorListener;
import javax.swing.event.EventListenerList;
import javax.swing.event.SwingPropertyChangeSupport;
import javax.swing.plaf.ComponentUI;

/**
 * Every component in swing inherits from this class (JLabel, JButton, etc).
 * It contains generic methods to manage events, properties and sizes. Actual
 * drawing of the component is channeled to a look-and-feel class that is
 * implemented elsewhere.
 *
 * @author Ronald Veldema (rveldema&064;cs.vu.nl)
 * @author Graydon Hoare (graydon&064;redhat.com)
 */
public abstract class JComponent extends Container implements Serializable
{
  private static final long serialVersionUID = -7908749299918704233L;

  /** 
   * Accessibility support is currently missing.
   */

  protected AccessibleContext accessibleContext;

  public abstract class AccessibleJComponent 
    extends AccessibleAWTContainer
  {
    protected class AccessibleFocusHandler 
      implements FocusListener
    {
      protected AccessibleFocusHandler(){}
      public void focusGained(FocusEvent event){}
      public void focusLost(FocusEvent valevent){}
    }

    protected class AccessibleContainerHandler 
      implements ContainerListener
    {
      protected AccessibleContainerHandler() {}
      public void componentAdded(ContainerEvent event) {}
      public void componentRemoved(ContainerEvent valevent) {}
    }

    private static final long serialVersionUID = -7047089700479897799L;
  
    protected ContainerListener accessibleContainerHandler;
    protected FocusListener accessibleFocusHandler;

    protected AccessibleJComponent() {}
    public void addPropertyChangeListener(PropertyChangeListener listener) {}
    public void removePropertyChangeListener(PropertyChangeListener listener) {}
    public int getAccessibleChildrenCount() { return 0; }
    public Accessible getAccessibleChild(int value0) { return null; }
    public AccessibleStateSet getAccessibleStateSet() { return null; } 
    public String getAccessibleName() { return null; }
    public String getAccessibleDescription() { return null; }
    public AccessibleRole getAccessibleRole() { return null; }
    protected String getBorderTitle(Border value0) { return null; }
    public String getToolTipText() { return null; }
    public String getTitledBorderText() { return null; }
    public AccessibleKeyBinding getAccessibleKeyBinding() { return null; }
  }

  /** 
   * An explicit value for the component's preferred size; if not set by a
   * user, this is calculated on the fly by delegating to the {@link
   * ComponentUI.getPreferredSize} method on the {@link #ui} property. 
   */
  Dimension preferredSize;

  /** 
   * An explicit value for the component's minimum size; if not set by a
   * user, this is calculated on the fly by delegating to the {@link
   * ComponentUI.getMinimumSize} method on the {@link #ui} property. 
   */
  Dimension minimumSize;

  /** 
   * An explicit value for the component's maximum size; if not set by a
   * user, this is calculated on the fly by delegating to the {@link
   * ComponentUI.getMaximumSize} method on the {@link #ui} property.
   */
  Dimension maximumSize;


  /**
   * A value between 0.0 and 1.0 indicating the preferred horizontal
   * alignment of the component, relative to its siblings. The values
   * {@link #LEFT_ALIGNMENT}, {@link #CENTER_ALIGNMENT}, and {@link
   * #RIGHT_ALIGNMENT} can also be used, as synonyms for <code>0.0</code>,
   * <code>0.5</code>, and <code>1.0</code>, respectively. Not all layout
   * managers use this property.
   *
   * @see #getAlignmentX
   * @see #setAlignmentX
   * @see javax.swing.OverlayLayout
   * @see javax.swing.BoxLayout
   */
  float alignmentX = 0.0f;

  /**
   * A value between 0.0 and 1.0 indicating the preferred vertical
   * alignment of the component, relative to its siblings. The values
   * {@link #TOP_ALIGNMENT}, {@link #CENTER_ALIGNMENT}, and {@link
   * #BOTTOM_ALIGNMENT} can also be used, as synonyms for <code>0.0</code>,
   * <code>0.5</code>, and <code>1.0</code>, respectively. Not all layout
   * managers use this property.
   *
   * @see #getAlignmentY
   * @see #setAlignmentY
   * @see javax.swing.OverlayLayout
   * @see javax.swing.BoxLayout
   */
  float alignmentY = 0.0f;

  /** 
   * The border painted around this component.
   * 
   * @see #paintBorder
   */
  Border border;

  /** 
   * The text to show in the tooltip associated with this component.
   * 
   * @see #setToolTipText
   * @see #getToolTipText
   */
   String toolTipText;

  /** 
   * <p>Whether to double buffer this component when painting. This flag
   * should generally be <code>false</code>, except for top level
   * components such as {@link JFrame} or {@link JApplet}.</p>
   *
   * <p>All children of a double buffered component are painted into the
   * double buffer automatically, so only the top widget in a window needs
   * to be double buffered.</p>
   *
   * @see #setDoubleBuffered
   * @see #isDoubleBuffered
   * @see #paintLock
   * @see #paint
   */
  boolean doubleBuffered = false;

  /**
   * A set of flags indicating which debugging graphics facilities should
   * be enabled on this component. The values should be a combination of
   * {@link DebugGraphics.NONE_OPTION}, {@link DebugGraphics.LOG_OPTION},
   * {@link DebugGraphics.FLASH_OPTION}, or {@link
   * DebugGraphics.BUFFERED_OPTION}.
   *
   * @see setDebugGraphicsOptions
   * @see getDebugGraphicsOptions
   * @see DebugGraphics
   * @see getComponentGraphics
   */
  int debugGraphicsOptions;

  /** 
   * <p>This property controls two independent behaviors simultaneously.</p>
   *
   * <p>First, it controls whether to fill the background of this widget
   * when painting its body. This affects calls to {@link
   * JComponent#paintComponent}, which in turn calls {@link
   * ComponentUI#update} on the component's {@link #ui} property. If the
   * component is opaque during this call, the background will be filled
   * before calling {@link ComponentUI#paint}. This happens merely as a
   * convenience; you may fill the component's background yourself too,
   * but there is no need to do so if you will be filling with the same
   * color.</p>
   *
   * <p>Second, it the opaque property informs swing's repaint system
   * whether it will be necessary to paint the components "underneath" this
   * component, in Z-order. If the component is opaque, it is considered to
   * completely occlude components "underneath" it, so they will not be
   * repainted along with the opaque component.</p>
   *
   * <p>The default value for this property is <code>false</code>, but most
   * components will want to set it to <code>true</code> when installing UI
   * defaults in {@link ComponentUI#installUI}.</p>
   *
   * @see #setOpaque
   * @see #isOpaque
   * @see #paintComponent
   */
  boolean opaque = false;

  /** 
   * The user interface delegate for this component. Event delivery and
   * repainting of the component are usually delegated to this object. 
   *
   * @see #setUI
   * @see #getUI
   * @see #updateUI
   */
  protected ComponentUI ui;

  /**
   * A hint to the focus system that this component should or should not
   * get focus. If this is <code>false</code>, swing will not try to
   * request focus on this component; if <code>true</code>, swing might
   * try to request focus, but the request might fail. Thus it is only 
   * a hint guiding swing's behavior.
   *
   * @see #requestFocus
   * @see #isRequestFocusEnabled
   * @see #setRequestFocusEnabled
   */
  boolean requestFocusEnabled;

  /**
   * Flag indicating behavior of this component when the mouse is dragged
   * outside the component and the mouse <em>stops moving</em>. If
   * <code>true</code>, synthetic mouse events will be delivered on regular
   * timed intervals, continuing off in the direction the mouse exited the
   * component, until the mouse is released or re-enters the component.
   *
   * @see setAutoscrolls
   * @see getAutoscrolls
   */
  boolean autoscrolls = false;

  /**
   * Listeners for events other than {@link PropertyChangeEvent} are
   * handled by this listener list. PropertyChangeEvents are handled in
   * {@link #changeSupport}.
   */
  protected EventListenerList listenerList = new EventListenerList();

  /** 
   * Support for {@link PropertyChangeEvent} events. This is constructed
   * lazily when the component gets its first {@link
   * PropertyChangeListener} subscription; until then it's an empty slot.
   */
  private SwingPropertyChangeSupport changeSupport;


  /** 
   * Storage for "client properties", which are key/value pairs associated
   * with this component by a "client", such as a user application or a
   * layout manager. This is lazily constructed when the component gets its
   * first client property.
   */
  private Hashtable clientProperties;
  
  private InputMap inputMap_whenFocused;
  private InputMap inputMap_whenAncestorOfFocused;
  private InputMap inputMap_whenInFocusedWindow;
  private ActionMap actionMap;
  /** @since 1.3 */
  private boolean verifyInputWhenFocusTarget;
  private InputVerifier inputVerifier;

  private TransferHandler transferHandler;

  /** 
   * A lock held during recursive painting; this is used to serialize
   * access to the double buffer, and also to select the "top level" 
   * object which should acquire the double buffer in a given widget
   * tree (which may have multiple double buffered children).
   *
   * @see #doubleBuffered
   * @see #paint
   */
  private static final Object paintLock = new Object();


  /**
   * The default locale of the component.
   * 
   * @see #getDefaultLocale
   * @see #setDefaultLocale
   */
  private static Locale defaultLocale;
  
  public static final String TOOL_TIP_TEXT_KEY = "ToolTipText";

  /**
   * Constant used to indicate that no condition has been assigned to a
   * particular action.
   *
   * @see #registerKeyboardAction
   */
  public static final int UNDEFINED_CONDITION = -1;

  /**
   * Constant used to indicate that an action should be performed only when 
   * the component has focus.
   *
   * @see #registerKeyboardAction
   */
  public static final int WHEN_FOCUSED = 0;

  /**
   * Constant used to indicate that an action should be performed only when 
   * the component is an ancestor of the component which has focus.
   *
   * @see #registerKeyboardAction
   */
  public static final int WHEN_ANCESTOR_OF_FOCUSED_COMPONENT = 1;

  /**
   * Constant used to indicate that an action should be performed only when 
   * the component is in the window which has focus.
   *
   * @see #registerKeyboardAction
   */
  public static final int WHEN_IN_FOCUSED_WINDOW = 2;


  /**
   * Creates a new <code>JComponent</code> instance.
   */
  public JComponent()
  {
    super();
    super.setLayout(new FlowLayout());
    setDropTarget(new DropTarget());
    defaultLocale = Locale.getDefault();
    debugGraphicsOptions = DebugGraphics.NONE_OPTION;
  }

  /**
   * Helper to lazily construct and return the client properties table.
   * 
   * @return The current client properties table
   *
   * @see #clientProperties
   * @see #getClientProperty
   * @see #putClientProperty
   */
  private Hashtable getClientProperties()
  {
    if (clientProperties == null)
      clientProperties = new Hashtable();
    return clientProperties;
  }

  /**
   * Get a client property associated with this component and a particular
   * key.
   *
   * @param key The key with which to look up the client property
   *
   * @return A client property associated with this object and key
   *
   * @see #clientProperties
   * @see #getClientProperties
   * @see #putClientProperty
   */
  public final Object getClientProperty(Object key)
  {
    return getClientProperties().get(key);
  }

  /**
   * Add a client property <code>value</code> to this component, associated
   * with <code>key</code>. If there is an existing client property
   * associated with <code>key</code>, it will be replaced.
   *
   * @param key The key of the client property association to add
   * @param value The value of the client property association to add
   *
   * @see #clientProperties
   * @see #getClientProperties
   * @see #getClientProperty
   */
  public final void putClientProperty(Object key, Object value)
  {
    getClientProperties().put(key, value);
  }

  /**
   * Unregister an <code>AncestorListener</code>.
   *
   * @param listener The listener to unregister
   * 
   * @see addAncestorListener
   */
  public void removeAncestorListener(AncestorListener listener)
  {
    listenerList.remove(AncestorListener.class, listener);
  }

  /**
   * Unregister a <code>PropertyChangeListener</code>.
   *
   * @param listener The listener to register
   *
   * @see #addPropertyChangeListener
   * @see #changeSupport
   */
  public void removePropertyChangeListener(PropertyChangeListener listener)
  {
    if (changeSupport != null)
      changeSupport.removePropertyChangeListener(listener);
  }

  /**
   * Unregister a <code>PropertyChangeListener</code>.
   *
   * @param propertyName The property name to unregister the listener from
   * @param listener The listener to unregister
   *
   * @see #addPropertyChangeListener
   * @see #changeSupport
   */
  public void removePropertyChangeListener(String propertyName,
                                           PropertyChangeListener listener)
  {
    if (changeSupport != null)
      changeSupport.removePropertyChangeListener(propertyName, listener);
  }

  /**
   * Unregister a <code>VetoableChangeChangeListener</code>.
   *
   * @param listener The listener to unregister
   *
   * @see #addVetoableChangeListener
   */
  public void removeVetoableChangeListener(VetoableChangeListener listener)
  {
    listenerList.remove(VetoableChangeListener.class, listener);
  }

  /**
   * Register an <code>AncestorListener</code>.
   *
   * @param listener The listener to register
   *
   * @see #removeVetoableChangeListener
   */
  public void addAncestorListener(AncestorListener listener)
  {
    listenerList.add(AncestorListener.class, listener);
  }

  /**
   * Register a <code>PropertyChangeListener</code>. This listener will
   * receive any PropertyChangeEvent, regardless of property name. To
   * listen to a specific property name, use {@link
   * #addPropertyChangeListener(String,PropertyChangeListener)} instead.
   *
   * @param listener The listener to register
   *
   * @see #removePropertyChangeListener
   * @see #changeSupport
   */
  public void addPropertyChangeListener(PropertyChangeListener listener)
  {
    if (changeSupport == null)
      changeSupport = new SwingPropertyChangeSupport(this);
    changeSupport.addPropertyChangeListener(listener);
  }

  /**
   * Register a <code>PropertyChangeListener</code> for a specific, named
   * property. To listen to all property changes, regardless of name, use
   * {@link #addPropertyChangeListener(PropertyChangeListener)} instead.
   *
   * @param propertyName The property name to listen to
   * @param listener The listener to register
   *
   * @see #removePropertyChangeListener
   * @see #changeSupport
   */
  public void addPropertyChangeListener(String propertyName,
                                        PropertyChangeListener listener)
  {
    listenerList.add(PropertyChangeListener.class, listener);
  }

  /**
   * Register a <code>VetoableChangeListener</code>.
   *
   * @param listener The listener to register
   *
   * @see #removeVetoableChangeListener
   * @see #listenerList
   */
  public void addVetoableChangeListener(VetoableChangeListener listener)
  {
    listenerList.add(VetoableChangeListener.class, listener);
  }

  /**
   * Return all registered listeners of a particular type.
   *
   * @param listenerType The type of listener to return
   *
   * @return All listeners in the {@link #listenerList} which 
   * are of the specified type
   *
   * @see #listenerList
   */
  public EventListener[] getListeners(Class listenerType)
  {
    return listenerList.getListeners(listenerType);
  }

  /**
   * Return all registered <code>AncestorListener</code> objects.
   *
   * @return The set of <code>AncestorListener</code> objects in {@link
   * #listenerList}
   */
  public AncestorListener[] getAncestorListeners()
  {
    return (AncestorListener[]) getListeners(AncestorListener.class);
  }

  /**
   * Return all registered <code>VetoableChangeListener</code> objects.
   *
   * @return The set of <code>VetoableChangeListener</code> objects in {@link
   * #listenerList}
   */
  public VetoableChangeListener[] getVetoableChangeListeners()
  {
    return (VetoableChangeListener[]) getListeners(VetoableChangeListener.class);
  }

  /**
   * Return all <code>PropertyChangeListener</code> objects registered to listen
   * for a particular property.
   *
   * @param property The property to return the listeners of
   *
   * @return The set of <code>PropertyChangeListener</code> objects in 
   * {@link #changeSupport} registered to listen on the specified propert
   */
  public PropertyChangeListener[] getPropertyChangeListeners(String property)
  {
    return changeSupport == null ? new PropertyChangeListener[0]
                                 : changeSupport.getPropertyChangeListeners(property);
  }

  /**
   * A variant of {@link #firePropertyChange(String,Object,Object)} 
   * for properties with <code>boolean</code> values.
   */
  public void firePropertyChange(String propertyName, boolean oldValue,
                                 boolean newValue)
  {
    if (changeSupport != null)
      changeSupport.firePropertyChange(propertyName, Boolean.valueOf(oldValue),
                                       Boolean.valueOf(newValue));
  }

  /**
   * A variant of {@link #firePropertyChange(String,Object,Object)} 
   * for properties with <code>byte</code> values.
   */
  public void firePropertyChange(String propertyName, byte oldValue,
                                 byte newValue)
  {
    if (changeSupport != null)
      changeSupport.firePropertyChange(propertyName, new Byte(oldValue),
                                       new Byte(newValue));
  }

  /**
   * A variant of {@link #firePropertyChange(String,Object,Object)} 
   * for properties with <code>char</code> values.
   */
  public void firePropertyChange(String propertyName, char oldValue,
                                 char newValue)
  {
    if (changeSupport != null)
      changeSupport.firePropertyChange(propertyName, new Character(oldValue),
                                       new Character(newValue));
  }

  /**
   * A variant of {@link #firePropertyChange(String,Object,Object)} 
   * for properties with <code>double</code> values.
   */
  public void firePropertyChange(String propertyName, double oldValue,
                                 double newValue)
  {
    if (changeSupport != null)
      changeSupport.firePropertyChange(propertyName, new Double(oldValue),
                                       new Double(newValue));
  }

  /**
   * A variant of {@link #firePropertyChange(String,Object,Object)} 
   * for properties with <code>float</code> values.
   */
  public void firePropertyChange(String propertyName, float oldValue,
                                 float newValue)
  {
    if (changeSupport != null)
      changeSupport.firePropertyChange(propertyName, new Float(oldValue),
                                       new Float(newValue));
  }

  /**
   * A variant of {@link #firePropertyChange(String,Object,Object)} 
   * for properties with <code>int</code> values.
   */
  public void firePropertyChange(String propertyName, int oldValue,
                                 int newValue)
  {
    if (changeSupport != null)
      changeSupport.firePropertyChange(propertyName, new Integer(oldValue),
                                       new Integer(newValue));
  }

  /**
   * A variant of {@link #firePropertyChange(String,Object,Object)} 
   * for properties with <code>long</code> values.
   */
  public void firePropertyChange(String propertyName, long oldValue,
                                 long newValue)
  {
    if (changeSupport != null)
      changeSupport.firePropertyChange(propertyName, new Long(oldValue),
                                       new Long(newValue));
  }

  /**
   * Call {@link PropertyChangeListener#propertyChange} on all listeners
   * registered to listen to a given property. Any method which changes
   * the specified property of this component should call this method.
   *
   * @param propertyName The property which changed
   * @param oldValue The old value of the property
   * @param newValue The new value of the property
   *
   * @see #changeSupport
   * @see #addPropertyChangeListener
   * @see #removePropertyChangeListener
   */
  protected void firePropertyChange(String propertyName, Object oldValue,
                                    Object newValue)
  {
    if (changeSupport != null)
      changeSupport.firePropertyChange(propertyName, oldValue, newValue);
  }

  /**
   * A variant of {@link #firePropertyChange(String,Object,Object)} 
   * for properties with <code>short</code> values.
   */
  public void firePropertyChange(String propertyName, short oldValue,
                                 short newValue)
  {
    if (changeSupport != null)
      changeSupport.firePropertyChange(propertyName, new Short(oldValue),
                                       new Short(newValue));
  }

  /**
   * Call {@link VetoableChangeListener#vetoableChange} on all listeners
   * registered to listen to a given property. Any method which changes
   * the specified property of this component should call this method.
   *
   * @param propertyName The property which changed
   * @param oldValue The old value of the property
   * @param newValue The new value of the property
   *
   * @throws PropertyVetoException if the change was vetoed by a listener
   *
   * @see addVetoableChangeListener
   * @see removeVetoableChangeListener
   */
  protected void fireVetoableChange(String propertyName, Object oldValue,
                                    Object newValue)
    throws PropertyVetoException
  {
    VetoableChangeListener[] listeners = getVetoableChangeListeners();
    
    PropertyChangeEvent evt = new PropertyChangeEvent(this, propertyName, oldValue, newValue);
    
    for (int i = 0; i < listeners.length; i++)
      listeners[i].vetoableChange(evt);
  }

  /**
   * Get the value of the accessibleContext property for this component.
   *
   * @return the current value of the property
   */
  public AccessibleContext getAccessibleContext()
  {
    return null;
  }


  /**
   * Get the value of the {@link #alignmentX} property.
   *
   * @return The current value of the property.
   *
   * @see #setAlignmentX
   * @see #alignmentY
   */
  public float getAlignmentX()
  {
    return alignmentX;
  }

  /**
   * Get the value of the {@link #alignmentY} property.
   *
   * @return The current value of the property.
   *
   * @see #setAlignmentY
   * @see #alignmentX
   */
  public float getAlignmentY()
  {
    return alignmentY;
  }

  /**
   * Get the current value of the {@link #autoscrolls} property.
   *
   * @return The current value of the property
   */
  public boolean getAutoscrolls()
  {
    return autoscrolls;
  }

  /**
   * Set the value of the {@link #border} property, revalidate
   * and repaint this component.
   *   
   * @param newBorder The new value of the property
   *
   * @see #getBorder
   */
  public void setBorder(Border newBorder)
  {
    Border oldBorder = border;
    border = newBorder;
    firePropertyChange("border", oldBorder, newBorder);
    revalidate();
    repaint();
  }

  /**
   * Get the value of the {@link #border} property.
   *
   * @return The property's current value
   *
   * @see #setBorder
   */
  public Border getBorder()
  {
    return border;
  }

  /**
   * Get the component's current bounding box. If a rectangle is provided,
   * use this as the return value (adjusting its fields in place);
   * otherwise (of <code>null</code> is provided) return a new {@link
   * Rectangle}.
   *
   * @param rv Optional return value to use
   *
   * @return A rectangle bounding the component
   */
  public Rectangle getBounds(Rectangle rv)
  {
    if (rv == null)
      return new Rectangle(getX(), getY(), getWidth(), getHeight());
    else
      {
        rv.setBounds(getX(), getY(), getWidth(), getHeight());
        return rv;
      }
  }

  /**
   * Prepares a graphics context for painting this object. If {@link
   * #debugGraphicsOptions} is not equal to {@link
   * DebugGraphics#NONE_OPTION}, produce a new {@link DebugGraphics} object
   * wrapping the parameter. Otherwise configure the parameter with this
   * component's foreground color and font.
   *
   * @param g The graphics context to wrap or configure
   *
   * @return A graphics context to paint this object with
   *
   * @see #debugGraphicsOptions
   * @see #paint
   */
  protected Graphics getComponentGraphics(Graphics g)
  {    
    Graphics g2 = g.create();
    g2.setFont(this.getFont());
    g2.setColor(this.getForeground());
    return g2;
  }


  /**
   * Get the value of the {@link #debugGraphicsOptions} property.
   *
   * @return The current value of the property.
   *
   * @see #setDebugGraphicsOptions
   * @see #debugGraphicsOptions
   */
  public int getDebugGraphicsOptions()
  {
    return 0;
  }

  /**
   * Get the component's insets, which are calculated from
   * the {@link #border} property. If the border is <code>null</code>,
   * calls {@link Container#getInsets}.
   *
   * @return The component's current insets
   */
  public Insets getInsets()
  {
    if (border == null)
      return super.getInsets();
    return getBorder().getBorderInsets(this);
  }

  /**
   * Get the component's insets, which are calculated from the {@link
   * #border} property. If the border is <code>null</code>, calls {@link
   * Container#getInsets}. The passed-in {@link Insets} value will be
   * used as the return value, if possible.
   *
   * @param insets Return value object to reuse, if possible
   *
   * @return The component's current insets
   */
  public Insets getInsets(Insets insets)
  {
    Insets t = getInsets();

    if (insets == null)
      return t;

    insets.left = t.left;
    insets.right = t.right;
    insets.top = t.top;
    insets.bottom = t.bottom;
    return insets;
  }

  /**
   * Get the component's location. The passed-in {@link Point} value
   * will be used as the return value, if possible.
   *
   * @param rv Return value object to reuse, if possible
   *
   * @return The component's current location
   */
  public Point getLocation(Point rv)
  {
    if (rv == null)
      return new Point(getX(), getY());

    rv.setLocation(getX(), getY());
    return rv;
  }

  /**
   * Get the component's maximum size. If the {@link #maximumSize} property
   * has been explicitly set, it is returned. If the {@link #maximumSize}
   * property has not been set but the {@link ui} property has been, the
   * result of {@link ComponentUI#getMaximumSize} is returned. If neither
   * property has been set, the result of {@link Container#getMaximumSize}
   * is returned.
   *
   * @return The maximum size of the component
   *
   * @see #maximumSize
   * @see #setMaximumSize
   */
  public Dimension getMaximumSize()
  {
    if (maximumSize != null)
      return maximumSize;

    if (ui != null)
      {
        Dimension s = ui.getMaximumSize(this);
        if (s != null)
          return s;
      }

    Dimension p = super.getMaximumSize();
    return p;
  }

  /**
   * Get the component's minimum size. If the {@link #minimumSize} property
   * has been explicitly set, it is returned. If the {@link #minimumSize}
   * property has not been set but the {@link ui} property has been, the
   * result of {@link ComponentUI#getMinimumSize} is returned. If neither
   * property has been set, the result of {@link Container#getMinimumSize}
   * is returned.
   *
   * @return The minimum size of the component
   *
   * @see #minimumSize
   * @see #setMinimumSize
   */
  public Dimension getMinimumSize()
  {
    if (minimumSize != null)
      return minimumSize;

    if (ui != null)
      {
        Dimension s = ui.getMinimumSize(this);
        if (s != null)
          return s;
      }

    Dimension p = super.getMinimumSize();
    return p;
  }

  /**
   * Get the component's preferred size. If the {@link #preferredSize}
   * property has been explicitly set, it is returned. If the {@link
   * #preferredSize} property has not been set but the {@link ui} property
   * has been, the result of {@link ComponentUI#getPreferredSize} is
   * returned. If neither property has been set, the result of {@link
   * Container#getPreferredSize} is returned.
   *
   * @return The preferred size of the component
   *
   * @see #preferredSize
   * @see #setPreferredSize
   */
  public Dimension getPreferredSize()
  {
    if (preferredSize != null)
      return preferredSize;

    if (ui != null)
      {
        Dimension s = ui.getPreferredSize(this);
        if (s != null)
          return s;
      }
    Dimension p = super.getPreferredSize();
    return p;
  }

  /**
   * Checks if a maximum size was explicitely set on the component.
   *
   * @return <code>true</code> if a maximum size was set,
   * <code>false</code> otherwise
   * 
   * @since 1.3
   */
  public boolean isMaximumSizeSet()
  {
    return maximumSize != null;
  }

  /**
   * Checks if a minimum size was explicitely set on the component.
   *
   * @return <code>true</code> if a minimum size was set,
   * <code>false</code> otherwise
   * 
   * @since 1.3
   */
  public boolean isMinimumSizeSet()
  {
    return minimumSize != null;
  }

  /**
   * Checks if a preferred size was explicitely set on the component.
   *
   * @return <code>true</code> if a preferred size was set,
   * <code>false</code> otherwise
   * 
   * @since 1.3
   */
  public boolean isPreferredSizeSet()
  {
    return preferredSize != null;
  }
  
  /**
   * Return the value of the {@link #nextFocusableComponent} property.
   *
   * @return The current value of the property, or <code>null</code>
   * if none has been set.
   * 
   * @deprecated See {@link java.awt.FocusTraversalPolicy}
   */
  public Component getNextFocusableComponent()
  {
    return null;
  }

  /**
   * Return the set of {@link KeyStroke} objects which are registered
   * to initiate actions on this component.
   *
   * @return An array of the registered keystrokes
   */
  public KeyStroke[] getRegisteredKeyStrokes()
  {
    return null;
  }

  /**
   * Returns the first ancestor of this component which is a {@link JRootPane}.
   * Equivalent to calling <code>SwingUtilities.getRootPane(this);</code>.
   *
   * @return An ancestral JRootPane, or <code>null</code> if none exists.
   */
  public JRootPane getRootPane()
  {
    JRootPane p = SwingUtilities.getRootPane(this);
    return p;
  }

  /**
   * Get the component's size. The passed-in {@link Dimension} value
   * will be used as the return value, if possible.
   *
   * @param rv Return value object to reuse, if possible
   *
   * @return The component's current size
   */
  public Dimension getSize(Dimension rv)
  {
    if (rv == null)
      return new Dimension(getWidth(), getHeight());
    else
      {
        rv.setSize(getWidth(), getHeight());
        return rv;
      }
  }

  /**
   * Return the {@link #toolTip} property of this component, creating it and
   * setting it if it is currently <code>null</code>. This method can be
   * overridden in subclasses which wish to control the exact form of
   * tooltip created.
   *
   * @return The current toolTip
   */
  public JToolTip createToolTip()
  {
	JToolTip toolTip = new JToolTip();
	toolTip.setComponent(this);
	toolTip.setTipText(toolTipText);
    
    return toolTip;
  }

  /**
   * Return the location at which the {@link #toolTip} property should be
   * displayed, when triggered by a particular mouse event. 
   *
   * @param event The event the tooltip is being presented in response to
   *
   * @return The point at which to display a tooltip, or <code>null</code>
   * if swing is to choose a default location.
   */
  public Point getToolTipLocation(MouseEvent event)
  {
    return null;
  }

  /**
   * Set the value of the {@link #toolTipText} property.
   *
   * @param text The new property value
   *
   * @see #getToolTipText
   */
  public void setToolTipText(String text)
  {
    if (text == null)
    {
      ToolTipManager.sharedInstance().unregisterComponent(this);
      toolTipText = null;
      return;
    }
		
    // XXX: The tip text doesn't get updated unless you set it to null
    // and then to something not-null. This is consistent with the behaviour
    // of Sun's ToolTipManager.
			
    String oldText = toolTipText;
    toolTipText = text;
		
    if (oldText == null)
      ToolTipManager.sharedInstance().registerComponent(this);
  }

  /**
   * Get the value of the {@link #toolTipText} property.
   *
   * @return The current property value
   *
   * @see #setToolTipText
   */
  public String getToolTipText()
  {
    return toolTipText;
  }

  /**
   * Get the value of the {@link #toolTipText} property, in response to a
   * particular mouse event.
   *
   * @param event The mouse event which triggered the tooltip
   *
   * @return The current property value
   *
   * @see #setToolTipText
   */
  public String getToolTipText(MouseEvent event)
  {
    return getToolTipText();
  }

  /**
   * Return the top level ancestral container (usually a {@link
   * java.awt.Window} or {@link java.awt.Applet}) which this component is
   * contained within, or <code>null</code> if no ancestors exist.
   *
   * @return The top level container, if it exists
   */
  public Container getTopLevelAncestor()
  {
    Container c = getParent();
    for (Container peek = c; peek != null; peek = peek.getParent())
      c = peek;
    return c;
  }

  /**
   * Compute the component's visible rectangle, which is defined
   * recursively as either the component's bounds, if it has no parent, or
   * the intersection of the component's bounds with the visible rectangle
   * of its parent.
   *
   * @param rect The return value slot to place the visible rectangle in
   */
  public void computeVisibleRect(Rectangle rect)
  {
    Component c = getParent();
    if (c != null && c instanceof JComponent)
      {
        ((JComponent) c).computeVisibleRect(rect);
        rect.translate(-getX(), -getY());
        Rectangle2D.intersect(rect,
                              new Rectangle(0, 0, getWidth(), getHeight()),
                              rect);
      }
    else
      rect.setRect(0, 0, getWidth(), getHeight());
  }

  /**
   * Return the component's visible rectangle in a new {@link Rectangle},
   * rather than via a return slot.
   *
   * @return The component's visible rectangle
   *
   * @see #computeVisibleRect(Rectangle)
   */
  public Rectangle getVisibleRect()
  {
    Rectangle r = new Rectangle();
    computeVisibleRect(r);
    return r;
  }

  /**
   * <p>Requests that this component receive input focus, giving window
   * focus to the top level ancestor of this component. Only works on
   * displayable, focusable, visible components.</p>
   *
   * <p>This method should not be called by clients; it is intended for
   * focus implementations. Use {@link Component#requestFocus} instead.</p>
   *
   * @see {@link Component#requestFocus}
   */
  public void grabFocus()
  {
  }

  /**
   * Get the value of the {@link #doubleBuffered} property.
   *
   * @return The property's current value
   */
  public boolean isDoubleBuffered()
  {
    return doubleBuffered;
  }

  /**
   * Return <code>true</code> if the provided component has no native peer;
   * in other words, if it is a "lightweight component".
   *
   * @param c The component to test for lightweight-ness
   *
   * @return Whether or not the component is lightweight
   */
  public static boolean isLightweightComponent(Component c)
  {
    return c.getPeer() instanceof LightweightPeer;
  }

  /**
   * Return <code>true</code> if you wish this component to manage its own
   * focus. In particular: if you want this component to be sent
   * <code>TAB</code> and <code>SHIFT+TAB</code> key events, and to not
   * have its children considered as focus transfer targets. If
   * <code>true</code>, focus traversal around this component changes to
   * <code>CTRL+TAB</code> and <code>CTRL+SHIFT+TAB</code>.
   *
   * @return <code>true</code> if you want this component to manage its own
   * focus, otherwise (by default) <code>false</code>
   *
   * @deprecated 1.4 Use {@link Component.setFocusTraversalKeys(int,Set)} and
   * {@link Container.setFocusCycleRoot(boolean)} instead
   */
  public boolean isManagingFocus()
  {
    return false;
  }

  /**
   * Return the current value of the {@link opaque} property. 
   *
   * @return The current property value
   */
  public boolean isOpaque()
  {
    return opaque;
  }

  /**
   * Return <code>true</code> if the component can guarantee that none of its
   * children will overlap in Z-order. This is a hint to the painting system.
   * The default is to return <code>true</code>, but some components such as
   * {@link JLayeredPane} should override this to return <code>false</code>.
   *
   * @return Whether the component tiles its children
   */
  public boolean isOptimizedDrawingEnabled()
  {
    return true;
  }

  /**
   * Return <code>true</code> if this component is currently painting a tile.
   *
   * @return Whether the component is painting a tile
   */
  public boolean isPaintingTile()
  {
    return false;
  }

  /**
   * Get the value of the {@link #requestFocusEnabled} property.
   *
   * @return The current value of the property
   */
  public boolean isRequestFocusEnabled()
  {
    return requestFocusEnabled;
  }

  /**
   * Return <code>true</code> if this component is a validation root; this
   * will cause calls to {@link #invalidate} in this component's children
   * to be "captured" at this component, and not propagate to its parents.
   * For most components this should return <code>false</code>, but some
   * components such as {@link JViewPort} will want to return
   * <code>true</code>.
   *
   * @return Whether this component is a validation root
   */
  public boolean isValidateRoot()
  {
    return false;
  }

  /**
   * <p>Paint the component. This is a delicate process, and should only be
   * called from the repaint thread, under control of the {@link
   * RepaintManager}. Client code should usually call {@link #repaint} to
   * trigger painting.</p>
   *
   * <p>This method will acquire a double buffer from the {@link
   * RepaintManager} if the component's {@link #doubleBuffered} property is
   * <code>true</code> and the <code>paint</code> call is the
   * <em>first</em> recursive <code>paint</code> call inside swing.</p>
   *
   * <p>The method will also modify the provided {@link Graphics} context
   * via the {@link #getComponentGraphics} method. If you want to customize
   * the graphics object used for painting, you should override that method
   * rather than <code>paint</code>.</p>
   *
   * <p>The body of the <code>paint</code> call involves calling {@link
   * #paintComponent}, {@link #paintBorder}, and {@link #paintChildren} in
   * order. If you want to customize painting behavior, you should override
   * one of these methods rather than <code>paint</code>.</p>
   *
   * <p>For more details on the painting sequence, see <a
   * href="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">this
   * article</a>.</p>
   *
   * @param g The graphics context to paint with
   *
   * @see #paintImmediately
   */
  public void paint(Graphics g)
  {
    Graphics g2 = g;
    Image doubleBuffer = null;
    RepaintManager rm = RepaintManager.currentManager(this);

    if (isDoubleBuffered()
        && (rm.isDoubleBufferingEnabled())
        && (! Thread.holdsLock(paintLock)))
      {
        doubleBuffer = rm.getOffscreenBuffer(this, getWidth(), getHeight());
      }

    synchronized (paintLock)
      {
        if (doubleBuffer != null)
          {
            g2 = doubleBuffer.getGraphics();
            g2.setClip(g.getClipBounds());
          }
	  
        g2 = getComponentGraphics(g2);
        paintComponent(g2);
        paintBorder(g2);
        paintChildren(g2);
        
        if (doubleBuffer != null)
          g.drawImage(doubleBuffer, 0, 0, (ImageObserver) null);
      }
  }

  /**
   * Paint the component's border. This usually means calling {@link
   * Border#paintBorder} on the {@link #border} property, if it is
   * non-<code>null</code>. You may override this if you wish to customize
   * border painting behavior. The border is painted after the component's
   * body, but before the component's children.
   *
   * @param g The graphics context with which to paint the border
   *
   * @see #paint
   * @see #paintChildren
   * @see #paintComponent
   */
  protected void paintBorder(Graphics g)
  {
    if (getBorder() != null)
      getBorder().paintBorder(this, g, 0, 0, getWidth(), getHeight());
  }

  /**
   * Paint the component's children. This usually means calling {@link
   * Container#paint}, which recursively calls {@link #paint} on any of the
   * component's children, with appropriate changes to coordinate space and
   * clipping region. You may override this if you wish to customize
   * children painting behavior. The children are painted after the
   * component's body and border.
   *
   * @param g The graphics context with which to paint the children
   *
   * @see #paint
   * @see #paintBorder
   * @see #paintComponent
   */
  protected void paintChildren(Graphics g)
  {
    super.paint(g);
  }

  /**
   * Paint the component's body. This usually means calling {@link
   * ComponentUI#update} on the {@link #ui} property of the component, if
   * it is non-<code>null</code>. You may override this if you wish to
   * customize the component's body-painting behavior. The component's body
   * is painted first, before the border and children.
   *
   * @param g The graphics context with which to paint the body
   *
   * @see #paint
   * @see #paintBorder
   * @see #paintChildren
   */
  protected void paintComponent(Graphics g)
  {
    if (ui != null)
      ui.update(g, this);
  }

  /**
   * A variant of {@link #paintImmediately(Rectangle)} which takes
   * integer parameters.
   *
   * @param x The left x coordinate of the dirty region
   * @param y The top y coordinate of the dirty region
   * @param w The width of the dirty region
   * @param h The height of the dirty region
   */
  public void paintImmediately(int x, int y, int w, int h)
  {
    paintImmediately(new Rectangle(x, y, w, h));
  }

  /**
   * Transform the provided dirty rectangle for this component into the
   * appropriate ancestral {@link JRootPane} and call {@link #paint} on
   * that root pane. This method is called from the {@link RepaintManager}
   * and should always be called within the painting thread.
   *
   * @param r The dirty rectangle to paint
   */
  public void paintImmediately(Rectangle r)
  {
    Component root = SwingUtilities.getRoot(this);
    if (root == null || ! root.isShowing())
      return;
    Graphics g = root.getGraphics();
    if (g == null)
      return;

    Rectangle clip = SwingUtilities.convertRectangle(this, r, root);
    g.setClip(clip);
    root.paint(g);
    g.dispose();
  }

  /**
   * Return a string representation for this component, for use in
   * debugging.
   *
   * @return A string describing this component.
   */
  protected String paramString()
  {
    StringBuffer sb = new StringBuffer();
    sb.append(super.paramString());
    sb.append(",alignmentX=").append(getAlignmentX());
    sb.append(",alignmentY=").append(getAlignmentY());
    sb.append(",border=");
    if (getBorder() != null)
      sb.append(getBorder());
    sb.append(",maximumSize=");
    if (getMaximumSize() != null)
      sb.append(getMaximumSize());
    sb.append(",minimumSize=");
    if (getMinimumSize() != null)
      sb.append(getMinimumSize());
    sb.append(",preferredSize=");
    if (getPreferredSize() != null)
      sb.append(getPreferredSize());
    return sb.toString();
  }

  /**
   * A variant of {@link
   * #registerKeyboardAction(ActionListener,String,KeyStroke,int)} which
   * provides <code>null</code> for the command name.   
   */
  public void registerKeyboardAction(ActionListener act,
                                     KeyStroke stroke, 
                                     int cond)
  {
    registerKeyboardAction(act, null, stroke, cond);
  }

  /* 
   * There is some charmingly undocumented behavior sun seems to be using
   * to simulate the old register/unregister keyboard binding API. It's not
   * clear to me why this matters, but we shall endeavour to follow suit.
   *
   * Two main thing seem to be happening when you do registerKeyboardAction():
   * 
   *  - no actionMap() entry gets created, just an entry in inputMap()
   *
   *  - the inputMap() entry is a proxy class which invokes the the
   *  binding's actionListener as a target, and which clobbers the command
   *  name sent in the ActionEvent, providing the binding command name
   *  instead.
   *
   * This much you can work out just by asking the input and action maps
   * what they contain after making bindings, and watching the event which
   * gets delivered to the recipient. Beyond that, it seems to be a
   * sun-private solution so I will only immitate it as much as it matters
   * to external observers.
   */

  private static class ActionListenerProxy
    extends AbstractAction
  {
    ActionListener target;
    String bindingCommandName;

    public ActionListenerProxy(ActionListener li, 
                               String cmd)
    {
      target = li;
      bindingCommandName = cmd;
    }

    public void actionPerformed(ActionEvent e)
    {
      ActionEvent derivedEvent = new ActionEvent(e.getSource(),
                                                 e.getID(),
                                                 bindingCommandName,
                                                 e.getModifiers());
      target.actionPerformed(derivedEvent);
    }
  }

  
  /**
   * An obsolete method to register a keyboard action on this component.
   * You should use <code>getInputMap</code> and <code>getActionMap</code>
   * to fetch mapping tables from keystrokes to commands, and commands to
   * actions, respectively, and modify those mappings directly.
   *
   * @param anAction The action to be registered
   * @param aCommand The command to deliver in the delivered {@link
   * java.awt.ActionEvent}
   * @param aKeyStroke The keystroke to register on
   * @param aCondition One of the values {@link #UNDEFINED_CONDITION},
   * {@link #WHEN_ANCESTOR_OF_FOCUSED_COMPONENT}, {@link #WHEN_FOCUSED}, or
   * {@link #WHEN_IN_FOCUSED_WINDOW}, indicating the condition which must
   * be met for the action to be fired
   *
   * @see #unregisterKeyboardAction
   * @see #getConditionForKeystroke
   * @see #resetKeyboardActiond
   */
  public void registerKeyboardAction(ActionListener act, 
                                     String cmd,
                                     KeyStroke stroke, 
                                     int cond)
  {
    getInputMap(cond).put(stroke, new ActionListenerProxy(act, cmd));
  }



  public final void setInputMap(int condition, InputMap map)
  {
    enableEvents(AWTEvent.KEY_EVENT_MASK);
    switch (condition)
      {
      case WHEN_FOCUSED:
        inputMap_whenFocused = map;
        break;

      case WHEN_ANCESTOR_OF_FOCUSED_COMPONENT:
        inputMap_whenAncestorOfFocused = map;
        break;

      case WHEN_IN_FOCUSED_WINDOW:
        inputMap_whenInFocusedWindow = map;
        break;
        
      case UNDEFINED_CONDITION:
      default:
        throw new IllegalArgumentException();
      }
  }

  public final InputMap getInputMap(int condition)
  {
    enableEvents(AWTEvent.KEY_EVENT_MASK);
    switch (condition)
      {
      case WHEN_FOCUSED:
        if (inputMap_whenFocused == null)
          inputMap_whenFocused = new InputMap();
        return inputMap_whenFocused;

      case WHEN_ANCESTOR_OF_FOCUSED_COMPONENT:
        if (inputMap_whenAncestorOfFocused == null)
          inputMap_whenAncestorOfFocused = new InputMap();
        return inputMap_whenAncestorOfFocused;

      case WHEN_IN_FOCUSED_WINDOW:
        if (inputMap_whenInFocusedWindow == null)
          inputMap_whenInFocusedWindow = new InputMap();
        return inputMap_whenInFocusedWindow;

      case UNDEFINED_CONDITION:
      default:
        return null;
      }
  }

  public final InputMap getInputMap()
  {
    return getInputMap(WHEN_FOCUSED);
  }

  public final ActionMap getActionMap()
  {
    if (actionMap == null)
      actionMap = new ActionMap();
    return actionMap;
  }

  public final void setActionMap(ActionMap map)
  {
    actionMap = map;
  }

  /**
   * Return the condition that determines whether a registered action
   * occurs in response to the specified keystroke.
   *
   * @param aKeyStroke The keystroke to return the condition of
   *
   * @return One of the values {@link #UNDEFINED_CONDITION}, {@link
   * #WHEN_ANCESTOR_OF_FOCUSED_COMPONENT}, {@link #WHEN_FOCUSED}, or {@link
   * #WHEN_IN_FOCUSED_WINDOW}
   *
   * @deprecated As of 1.3 KeyStrokes can be registered with multiple
   * simultaneous conditions.
   *
   * @see #registerKeyboardAction   
   * @see #unregisterKeyboardAction   
   * @see #resetKeyboardActiond
   */
  public int getConditionForKeyStroke(KeyStroke ks)
  {
    if (inputMap_whenFocused != null 
        && inputMap_whenFocused.get(ks) != null)
      return WHEN_FOCUSED;
    else if (inputMap_whenAncestorOfFocused != null 
             && inputMap_whenAncestorOfFocused.get(ks) != null)
      return WHEN_ANCESTOR_OF_FOCUSED_COMPONENT;
    else if (inputMap_whenInFocusedWindow != null 
             && inputMap_whenInFocusedWindow.get(ks) != null)
      return WHEN_IN_FOCUSED_WINDOW;
    else
      return UNDEFINED_CONDITION;
  }

  /**
   * Get the ActionListener (typically an {@link Action} object) which is
   * associated with a particular keystroke. 
   *
   * @param aKeyStroke The keystroke to retrieve the action of
   *
   * @return The action associated with the specified keystroke
   *
   * @deprecated Use {@link #getActionMap()}
   */
  public ActionListener getActionForKeyStroke(KeyStroke ks)
  {
    Object cmd = getInputMap().get(ks);
    if (cmd != null)
      {
        if (cmd instanceof ActionListenerProxy)
          return (ActionListenerProxy) cmd;
        else if (cmd instanceof String)
          return getActionMap().get(cmd);
      }
    return null;
  }

  /**
   * A hook for subclasses which want to customize event processing.
   */
  protected void processComponentKeyEvent(KeyEvent e)
  {
  }

  /**
   * Override the default key dispatch system from Component to hook into
   * the swing {@link InputMap} / {@link ActionMap} system.
   *
   * See <a
   * href="http://java.sun.com/products/jfc/tsc/special_report/kestrel/keybindings.html">this
   * report</a> for more details, it's somewhat complex.
   */
  protected void processKeyEvent(KeyEvent e)
  {
    processComponentKeyEvent(e);

    // FIXME: this needs to be elaborated significantly, to do all the
    // focus / ancestor / window searching for the various binding modes.
    if (! e.isConsumed() &&
        processKeyBinding(KeyStroke.getKeyStrokeForEvent(e), 
                          e, WHEN_FOCUSED, e.getID() == KeyEvent.KEY_PRESSED))
      e.consume();
  }

  protected boolean processKeyBinding(KeyStroke ks,
                                      KeyEvent e,
                                      int condition,
                                      boolean pressed)
  { 
    if (isEnabled())
      {
        Action act = null;
        InputMap map = getInputMap(condition);
        if (map != null)
          {
            Object cmd = map.get(ks);
            if (cmd != null)
              {
                if (cmd instanceof ActionListenerProxy)
                  act = (Action) cmd;
                else 
                  act = (Action) getActionMap().get(cmd);
              }
          }
        if (act != null && act.isEnabled())
          return SwingUtilities.notifyAction(act, ks, e, this, e.getModifiers());
      }
    return false;
  }
  
  /**
   * Remove a keyboard action registry.
   *
   * @param stroke The keystroke to unregister
   *
   * @see #registerKeyboardAction
   * @see #getConditionForKeystroke
   * @see #resetKeyboardActiond
   */
  public void unregisterKeyboardAction(KeyStroke aKeyStroke)
  {
  }


  /**
   * Reset all keyboard action registries.
   *
   * @see #registerKeyboardAction
   * @see #unregisterKeyboardAction
   * @see #getConditionForKeystroke
   */
  public void resetKeyboardActions()
  {
    if (inputMap_whenFocused != null)
      inputMap_whenFocused.clear();
    if (inputMap_whenAncestorOfFocused != null)
      inputMap_whenAncestorOfFocused.clear();
    if (inputMap_whenInFocusedWindow != null)
      inputMap_whenInFocusedWindow.clear();
    if (actionMap != null)
      actionMap.clear();
  }


  /**
   * Mark the described region of this component as dirty in the current
   * {@link RepaintManager}. This will queue an asynchronous repaint using
   * the system painting thread in the near future.
   *
   * @param tm ignored
   * @param x coordinate of the region to mark as dirty
   * @param y coordinate of the region to mark as dirty
   * @param width dimension of the region to mark as dirty
   * @param height dimension of the region to mark as dirty
   */
  public void repaint(long tm, int x, int y, int width, int height)
  {
    Rectangle dirty = new Rectangle(x, y, width, height);
    Rectangle vis = getVisibleRect();
    dirty = dirty.intersection(vis);
    RepaintManager.currentManager(this).addDirtyRegion(this, dirty.x, dirty.y,
                                                       dirty.width,
                                                       dirty.height);
  }

  /**
   * Mark the described region of this component as dirty in the current
   * {@link RepaintManager}. This will queue an asynchronous repaint using
   * the system painting thread in the near future.
   *
   * @param r The rectangle to mark as dirty
   */
  public void repaint(Rectangle r)
  {
    repaint((long) 0, (int) r.getX(), (int) r.getY(), (int) r.getWidth(),
            (int) r.getHeight());
  }

  /**
   * Request focus on the default component of this component's {@link
   * FocusTraversalPolicy}.
   *
   * @return The result of {@link #requestFocus}
   *
   * @deprecated Use {@link #requestFocus()} on the default component provided from
   * the {@link FocusTraversalPolicy} instead.
   */
  public boolean requestDefaultFocus()
  {
    return false;
  }

  /**
   * Queue a an invalidation and revalidation of this component, using 
   * {@link RepaintManager#addInvalidComponent}.
   */
  public void revalidate()
  {
    invalidate();
    RepaintManager.currentManager(this).addInvalidComponent(this);
  }

  /**
   * Calls <code>scrollRectToVisible</code> on the component's parent. 
   * Components which can service this call should override.
   *
   * @param r The rectangle to make visible
   */
  public void scrollRectToVisible(Rectangle r)
  {
    Component p = getParent();
    if (p instanceof JComponent)
      ((JComponent) p).scrollRectToVisible(r);
  }

  /**
   * Set the value of the {@link #alignmentX} property.
   *
   * @param a The new value of the property
   */
  public void setAlignmentX(float a)
  {
    alignmentX = a;
  }

  /**
   * Set the value of the {@link #alignmentY} property.
   *
   * @param a The new value of the property
   */
  public void setAlignmentY(float a)
  {
    alignmentY = a;
  }

  /**
   * Set the value of the {@link #autoscrolls} property.
   *
   * @param a The new value of the property
   */
  public void setAutoscrolls(boolean a)
  {
    autoscrolls = a;
  }

  /**
   * Set the value of the {@link #debugGraphicsOptions} property.
   *
   * @param debugOptions The new value of the property
   */
  public void setDebugGraphicsOptions(int debugOptions)
  {
    debugGraphicsOptions = debugOptions;
  }

  /**
   * Set the value of the {@link #doubleBuffered} property.
   *
   * @param db The new value of the property
   */
  public void setDoubleBuffered(boolean db)
  {
    doubleBuffered = db;
  }

  /**
   * Set the value of the {@link #enabled} property, revalidate
   * and repaint this component.
   *
   * @param enable The new value of the property
   */
  public void setEnabled(boolean enable)
  {
    boolean oldEnabled = isEnabled();
    super.setEnabled(enable);
    firePropertyChange("enabeld", oldEnabled, enable);
    revalidate();
    repaint();
  }

  /**
   * Set the value of the {@link #font} property, revalidate
   * and repaint this component.
   *
   * @param f The new value of the property
   */
  public void setFont(Font f)
  {
    super.setFont(f);
    revalidate();
    repaint();
  }

  /**
   * Set the value of the {@link #background} property, revalidate
   * and repaint this component.
   *
   * @param bg The new value of the property
   */
  public void setBackground(Color bg)
  {
    super.setBackground(bg);
    revalidate();
    repaint();
  }

  /**
   * Set the value of the {@link #foreground} property, revalidate
   * and repaint this component.
   *
   * @param fg The new value of the property
   */
  public void setForeground(Color fg)
  {
    super.setForeground(fg);
    revalidate();
    repaint();
  }

  /**
   * Set the value of the {@link #maximumSize} property, revalidate
   * and repaint this component.
   *
   * @param max The new value of the property
   */
  public void setMaximumSize(Dimension max)
  {
    Dimension oldMaximumSize = maximumSize;
    maximumSize = max;
    firePropertyChange("maximumSize", oldMaximumSize, maximumSize);
    revalidate();
    repaint();
  }

  /**
   * Set the value of the {@link #minimumSize} property, revalidate
   * and repaint this component.
   *
   * @param min The new value of the property
   */
  public void setMinimumSize(Dimension min)
  {
    Dimension oldMinimumSize = minimumSize;
    minimumSize = min;
    firePropertyChange("minimumSize", oldMinimumSize, minimumSize);
    revalidate();
    repaint();
  }

  /**
   * Set the value of the {@link #preferredSize} property, revalidate
   * and repaint this component.
   *
   * @param pref The new value of the property
   */
  public void setPreferredSize(Dimension pref)
  {
    Dimension oldPreferredSize = preferredSize;
    preferredSize = pref;
    firePropertyChange("preferredSize", oldPreferredSize, preferredSize);
  }

  /**
   * Set the specified component to be the next component in the 
   * focus cycle, overriding the {@link FocusTraversalPolicy} for
   * this component.
   *
   * @param aComponent The component to set as the next focusable
   *
   * @deprecated Use FocusTraversalPolicy instead
   */
  public void setNextFocusableComponent(Component aComponent)
  {
  }

  /**
   * Set the value of the {@link #requestFocusEnabled} property.
   *
   * @param e The new value of the property
   */
  public void setRequestFocusEnabled(boolean e)
  {
    requestFocusEnabled = e;
  }

  /**
   * Get the value of the {@link #transferHandler} property.
   *
   * @return The current value of the property
   *
   * @see ComponentUI#setTransferHandler
   */

  public TransferHandler getTransferHandler()
  {
    return transferHandler;
  }

  /**
   * Set the value of the {@link #transferHandler} property.
   *
   * @param newHandler The new value of the property
   *
   * @see ComponentUI#getTransferHandler
   */

  public void setTransferHandler(TransferHandler newHandler)
  {
    if (transferHandler == newHandler)
      return;

    TransferHandler oldHandler = transferHandler;
    transferHandler = newHandler;
    firePropertyChange("transferHandler", oldHandler, newHandler);
  }

  /**
   * Set the value of the {@link #opaque} property, revalidate and repaint
   * this component.
   *
   * @param isOpaque The new value of the property
   *
   * @see ComponentUI#update
   */
  public void setOpaque(boolean isOpaque)
  {
    boolean oldOpaque = opaque;
    opaque = isOpaque;
    firePropertyChange("opaque", oldOpaque, opaque);
    revalidate();
    repaint();
  }

  /**
   * Set the value of the visible property, and revalidate / repaint the
   * component.
   *
   * @param v The new value of the property
   */
  public void setVisible(boolean v)
  {
    super.setVisible(v);
    revalidate();
    repaint();
  }

  /**
   * Call {@link paint}. 
   * 
   * @param g The graphics context to paint into
   */
  public void update(Graphics g)
  {
    paint(g);
  }

  /**
   * Get the value of the UIClassID property. This property should be a key
   * in the {@link UIDefaults} table managed by {@link UIManager}, the
   * value of which is the name of a class to load for the component's
   * {@link ui} property.
   *
   * @return A "symbolic" name which will map to a class to use for the
   * component's UI, such as <code>"ComponentUI"</code>
   *
   * @see #setUI
   * @see #updateUI
   */
  public String getUIClassID()
  {
    return "ComponentUI";
  }

  /**
   * Install a new UI delegate as the component's {@link ui} property. In
   * the process, this will call {@link ComponentUI.uninstallUI} on any
   * existing value for the {@link ui} property, and {@link
   * ComponentUI.installUI} on the new UI delegate.
   *
   * @param newUI The new UI delegate to install
   *
   * @see #updateUI
   * @see #getUIClassID
   */
  protected void setUI(ComponentUI newUI)
  {
    if (ui != null)
      ui.uninstallUI(this);

    ComponentUI oldUI = ui;
    ui = newUI;

    if (ui != null)
      ui.installUI(this);

    firePropertyChange("UI", oldUI, newUI);
    
    revalidate();
    repaint();
  }

  /**
   * This method should be overridden in subclasses. In JComponent, the
   * method does nothing. In subclasses, it should a UI delegate
   * (corresponding to the symbolic name returned from {@link
   * getUIClassID}) from the {@link UIManager}, and calls {@link setUI}
   * with the new delegate.
   */
  public void updateUI()
  {
    System.out.println("update UI not overwritten in class: " + this);
  }

  public static Locale getDefaultLocale()
  {
    return defaultLocale;
  }
  
  public static void setDefaultLocale(Locale l)
  {
    defaultLocale = l;
  }
  
  /**
   * Returns the currently set input verifier for this component.
   *
   * @return the input verifier, or <code>null</code> if none
   */
  public InputVerifier getInputVerifier()
  {
    return inputVerifier;
  }

  /**
   * Sets the input verifier to use by this component.
   *
   * @param verifier the input verifier, or <code>null</code>
   */
  public void setInputVerifier(InputVerifier verifier)
  {
    InputVerifier oldVerifier = inputVerifier;
    inputVerifier = verifier;
    firePropertyChange("inputVerifier", oldVerifier, verifier);
  }

  /**
   * @since 1.3
   */
  public boolean getVerifyInputWhenFocusTarget()
  {
    return verifyInputWhenFocusTarget;
  }

  /**
   * @since 1.3
   */
  public void setVerifyInputWhenFocusTarget(boolean verifyInputWhenFocusTarget)
  {
    if (this.verifyInputWhenFocusTarget == verifyInputWhenFocusTarget)
      return;

    this.verifyInputWhenFocusTarget = verifyInputWhenFocusTarget;
    firePropertyChange("verifyInputWhenFocusTarget",
		       ! verifyInputWhenFocusTarget,
		       verifyInputWhenFocusTarget);
  }
}
