3 fixes for JComponent:
1. All PropertyChangeEvent methods have been removed. They are all
handled in Component anyway and only called super. However, there was
one method addPropertyChangeListener(String,PropertyChangeListener)
which did not call super, but instead registered the listener to the
listener list, which is of course completely wrong. It effectivly lead
to PropertyChangeListener not getting notified of property changes
correctly. This fixes a whole lot of the Harmony test suite for us :-)

2. The VetoableChange stuff has been changed to use the
VetoableChangeSupport.

3. revalidate() returns early when the component has no parent. It's not
necessary to (in)validate a component as long as it has no parent, since
it gets validated anyway when it gets connected to a parent. But
revalidate() calls happen quite often during initialization of Swing
components, so this gives a nice little speedup of Swing startup.

2006-06-22  Roman Kennke  <[EMAIL PROTECTED]>

        * javax/swing/JComponent.java
        (vetoableChangeSupport): New field.
        (removeVetoableChangeListener): Rewritten to use
        vetoableChangeSupport.
        (addVetoableChangeListener): Rewritten to use
        vetoableChangeSupport.
        (fireVetoableChange): Rewritten to use
        vetoableChangeSupport.
        (addPropertyChangeListener): Removed. This is handled in
        Component already.
        (firePropertyChange(String,boolean,boolean)): Likewise.
        (firePropertyChange(String,char,char)): Likewise.
        (firePropertyChange(String,int,int)): Likewise.
        (revalidate): Don't do anything when the commponent has no
        parent.

/Roman

-- 
“Improvement makes straight roads, but the crooked roads, without
Improvement, are roads of Genius.” - William Blake
Index: javax/swing/JComponent.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/JComponent.java,v
retrieving revision 1.129
diff -u -2 -0 -r1.129 JComponent.java
--- javax/swing/JComponent.java	21 Jun 2006 12:34:46 -0000	1.129
+++ javax/swing/JComponent.java	22 Jun 2006 20:59:23 -0000
@@ -52,40 +52,41 @@
 import java.awt.Image;
 import java.awt.Insets;
 import java.awt.Point;
 import java.awt.Rectangle;
 import java.awt.Shape;
 import java.awt.Window;
 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.peer.LightweightPeer;
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
 import java.beans.PropertyVetoException;
 import java.beans.VetoableChangeListener;
+import java.beans.VetoableChangeSupport;
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.EventListener;
 import java.util.Hashtable;
 import java.util.Locale;
 import java.util.Set;
 
 import javax.accessibility.Accessible;
 import javax.accessibility.AccessibleContext;
 import javax.accessibility.AccessibleExtendedComponent;
 import javax.accessibility.AccessibleKeyBinding;
 import javax.accessibility.AccessibleRole;
 import javax.accessibility.AccessibleState;
 import javax.accessibility.AccessibleStateSet;
 import javax.swing.border.Border;
 import javax.swing.border.CompoundBorder;
 import javax.swing.border.TitledBorder;
 import javax.swing.event.AncestorEvent;
 import javax.swing.event.AncestorListener;
 import javax.swing.event.EventListenerList;
@@ -666,40 +667,45 @@
 
   /**
    * Indicates whether the current paint call is already double buffered or
    * not. 
    */
   static boolean isPaintingDoubleBuffered = false;
 
   /**
    * Indicates whether we are calling paintDoubleBuffered() from
    * paintImmadiately (RepaintManager) or from paint() (AWT refresh).
    */
   static private boolean isRepainting = false;
 
   /**
    * Listeners for events other than [EMAIL PROTECTED] PropertyChangeEvent} are
    * handled by this listener list. PropertyChangeEvents are handled in
    * [EMAIL PROTECTED] #changeSupport}.
    */
   protected EventListenerList listenerList = new EventListenerList();
 
+  /**
+   * Handles VetoableChangeEvents.
+   */
+  private VetoableChangeSupport vetoableChangeSupport;
+
   /** 
    * 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 ComponentInputMap inputMap_whenInFocusedWindow;
   private ActionMap actionMap;
   /** @since 1.3 */
   private boolean verifyInputWhenFocusTarget;
   private InputVerifier inputVerifier;
 
   private TransferHandler transferHandler;
 
   /**
    * Indicates if this component is currently painting a tile or not.
@@ -857,83 +863,70 @@
    * 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>VetoableChangeChangeListener</code>.
    *
    * @param listener The listener to unregister
    *
    * @see #addVetoableChangeListener
    */
   public void removeVetoableChangeListener(VetoableChangeListener listener)
   {
-    listenerList.remove(VetoableChangeListener.class, listener);
+    if (vetoableChangeSupport != null)
+      vetoableChangeSupport.removeVetoableChangeListener(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> for a specific, named
-   * property. To listen to all property changes, regardless of name, use
-   * [EMAIL PROTECTED] #addPropertyChangeListener(PropertyChangeListener)} instead.
-   *
-   * @param propertyName The property name to listen to
-   * @param listener The listener to register
-   *
-   * @see #removePropertyChangeListener(String, PropertyChangeListener)
-   * @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);
+    // Lazily instantiate this, it's rarely needed.
+    if (vetoableChangeSupport == null)
+      vetoableChangeSupport = new VetoableChangeSupport(this);
+    vetoableChangeSupport.addVetoableChangeListener(listener);
   }
 
   /**
    * Returns all registered [EMAIL PROTECTED] EventListener}s of the given 
    * <code>listenerType</code>.
    *
    * @param listenerType the class of listeners to filter (<code>null</code> 
    *                     not permitted).
    *                     
    * @return An array of registered listeners.
    * 
    * @throws ClassCastException if <code>listenerType</code> does not implement
    *                            the [EMAIL PROTECTED] EventListener} interface.
    * @throws NullPointerException if <code>listenerType</code> is 
    *                              <code>null</code>.
    *                            
    * @see #getAncestorListeners()
    * @see #listenerList
    * 
    * @since 1.3
@@ -952,109 +945,59 @@
    * @return The set of <code>AncestorListener</code> objects in [EMAIL PROTECTED]
    * #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 [EMAIL PROTECTED]
    * #listenerList}
    */
   public VetoableChangeListener[] getVetoableChangeListeners()
   {
     return (VetoableChangeListener[]) getListeners(VetoableChangeListener.class);
   }
 
   /**
-   * A variant of [EMAIL PROTECTED] #firePropertyChange(String,Object,Object)} 
-   * for properties with <code>boolean</code> values.
-   *
-   * @specnote It seems that in JDK1.5 all property related methods have been 
-   *           moved to java.awt.Component, except this and 2 others. We call
-   *           super here. I guess this will also be removed in one of the next
-   *           releases.
-   */
-  public void firePropertyChange(String propertyName, boolean oldValue,
-                                 boolean newValue)
-  {
-    super.firePropertyChange(propertyName, oldValue, newValue);
-  }
-
-  /**
-   * A variant of [EMAIL PROTECTED] #firePropertyChange(String,Object,Object)} 
-   * for properties with <code>char</code> values.
-   *
-   * @specnote It seems that in JDK1.5 all property related methods have been 
-   *           moved to java.awt.Component, except this and 2 others. We call
-   *           super here. I guess this will also be removed in one of the next
-   *           releases.
-   */
-  public void firePropertyChange(String propertyName, char oldValue,
-                                 char newValue)
-  {
-    super.firePropertyChange(propertyName, oldValue, newValue);
-  }
-
-  /**
-   * A variant of [EMAIL PROTECTED] #firePropertyChange(String,Object,Object)} 
-   * for properties with <code>int</code> values.
-   *
-   * @specnote It seems that in JDK1.5 all property related methods have been 
-   *           moved to java.awt.Component, except this and 2 others. We call
-   *           super here. I guess this will also be removed in one of the next
-   *           releases.
-   */
-  public void firePropertyChange(String propertyName, int oldValue,
-                                 int newValue)
-  {
-    super.firePropertyChange(propertyName, oldValue, newValue);
-  }
-
-  /**
    * Call [EMAIL PROTECTED] 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);
+    if (vetoableChangeSupport != null)
+      vetoableChangeSupport.fireVetoableChange(propertyName, oldValue, newValue);
   }
 
   /**
    * 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 [EMAIL PROTECTED] #alignmentX} property.
    *
    * @return The current value of the property.
    *
    * @see #setAlignmentX
    * @see #alignmentY
    */
@@ -2683,40 +2626,45 @@
   /**
    * Request focus on the default component of this component's [EMAIL PROTECTED]
    * FocusTraversalPolicy}.
    *
    * @return The result of [EMAIL PROTECTED] #requestFocus()}
    *
    * @deprecated Use [EMAIL PROTECTED] #requestFocus()} on the default component provided
    *     from the [EMAIL PROTECTED] FocusTraversalPolicy} instead.
    */
   public boolean requestDefaultFocus()
   {
     return false;
   }
 
   /**
    * Queue a an invalidation and revalidation of this component, using 
    * [EMAIL PROTECTED] RepaintManager#addInvalidComponent}.
    */
   public void revalidate()
   {
+    // As long as we don't have a parent we don't need to do any layout, since
+    // this is done anyway as soon as we get connected to a parent.
+    if (getParent() == null)
+      return;
+
     if (! EventQueue.isDispatchThread())
       SwingUtilities.invokeLater(new Runnable()
         {
           public void run()
           {
             revalidate();
           }
         });
     else
       {
         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

Attachment: signature.asc
Description: Dies ist ein digital signierter Nachrichtenteil

Reply via email to