A couple of fixes for the JLayeredPane. This fixes the behaviour of
toFront(), toBack(), setPosition() and setLayer() which was slightly
broken before.

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

        * javax/swing/JLayeredPane.java
        (getPosition): Moved code around to avoid unnecessary method
calls.
        (setPosition): Delegate to setLayer().
        (insertIndexForLayer(int,int)): Delegate to new private helper
method.
        (insertIndexForLayer(Component,int,int)): New helper method
        to support the use of setComponentZOrder() which doesn't remove
        the component and thus the insertIndexForLayer must ignore
        the component to be moved to get the index right.
        (setLayer): Added check to prevent unnecessary execution of
        method body. Changed to update the component order here.
        Added repaint() to make sure that the update becomes visible.
        (addImpl): Call setLayer() only when a constraint has been
specified.
        Validate and repaint the JLayeredPane.

/Roman

-- 
“Improvement makes straight roads, but the crooked roads, without
Improvement, are roads of Genius.” - William Blake
Index: javax/swing/JLayeredPane.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/JLayeredPane.java,v
retrieving revision 1.46
diff -u -2 -0 -r1.46 JLayeredPane.java
--- javax/swing/JLayeredPane.java	1 Jun 2006 04:38:49 -0000	1.46
+++ javax/swing/JLayeredPane.java	23 Jun 2006 11:07:55 -0000
@@ -26,40 +26,41 @@
 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.Color;
 import java.awt.Component;
 import java.awt.Container;
 import java.awt.Graphics;
 import java.awt.Rectangle;
+import java.util.ArrayList;
 import java.util.Hashtable;
 
 import javax.accessibility.Accessible;
 import javax.accessibility.AccessibleContext;
 import javax.accessibility.AccessibleRole;
 
 /**
  * A container that adds depth to the usual <code>Container</code> semantics.
  * Each child component of a <code>Layered Pane</code> is placed within one
  * of several layers. <code>JLayeredPane</code> defines a set of standard
  * layers. The pre-defined sets are (in the order from button to top):
  *
  *  <dl>
  *    <dt>[EMAIL PROTECTED] #DEFAULT_LAYER}</dt>
  *    <dd>The layer where most of the normal components are placed. This
  *      is the bottommost layer.</dd>
  *
  *    <dt>[EMAIL PROTECTED] #PALETTE_LAYER}</dt>
  *    <dd>Palette windows are placed in this layer.</dd>
  *
@@ -309,70 +310,68 @@
   {
     setPosition (c, -1);
   }
 
   /**
    * Return the position of a component within its layer. Positions are assigned
    * from the "front" (position 0) to the "back" (position N-1), and drawn from 
    * the back towards the front.
    *
    * @param c the component to get the position of
    *
    * @return the position of <code>c</code> within its layer or -1 if
    *         <code>c</code> is not a child of this layered pane
    *
    * @see #setPosition
    */
   public int getPosition(Component c)
   {
     int pos = -1;
     int index = getIndexOf(c);
-    Component[] components = getComponents();
-    int layer = getLayer(c);
     if (index >= 0)
       {
-        for (int i = index; i >= 0; --i)
+        pos = 0;
+        int layer = getLayer(c);
+        for (int i = index - 1; i >= 0; --i)
           {
-            if (layer == getLayer(components[i]))
+            if (layer == getLayer(getComponent(i)))
               pos++;
             else
               break;
           }
       }
     return pos;
   }
 
   /**
    * Change the position of a component within its layer. Positions are assigned
    * from the "front" (position 0) to the "back" (position N-1), and drawn from 
    * the back towards the front.
    *
    * @param c the component to change the position of
    * @param position the position to assign the component to
    *
    * @see #getPosition
    */
   public void setPosition(Component c, int position)
   {
-    int layer = getLayer(c);
-    int index = insertIndexForLayer(layer, position);
-    setComponentZOrder(c, index);
+    setLayer(c, getLayer(c), position);
   }
     
   /**
    * Return an array of all components within a layer of this
    * container. Components are ordered front-to-back, with the "front"
    * element (which draws last) at position 0 of the returned array.
    *
    * @param layer the layer to return components from
    *
    * @return the components in the layer
    */
   public Component[] getComponentsInLayer(int layer)
   {
     Component[] inLayer = new Component[getComponentCountInLayer(layer)];
     Component[] components = getComponents();
     int j = 0;
     for (int i = 0; i < components.length; ++i)
       {
         if (layer == getLayer(components[i]))
           {
@@ -461,68 +460,119 @@
 
 	    default:
         break;
 	    }
 
     return new Integer(layer);
   }
 
   /**
    * Computes an index at which to request the superclass [EMAIL PROTECTED]
    * java.awt.Container} inserts a component, given an abstract layer and
    * position number.
    *
    * @param layer the layer in which to insert a component.
    * @param position the position in the layer at which to insert a component.
    *
    * @return the index at which to insert the component.
    */
   protected int insertIndexForLayer(int layer, int position)
   {
-    // position < 0 means insert at greatest position within layer.
-    if (position < 0)
-      position = Integer.MAX_VALUE;
+    return insertIndexForLayer(null, layer, position);
+  }
 
-    Component[] components = getComponents();
-    int index = 0;
+  /**
+   * Similar to [EMAIL PROTECTED] #insertIndexForLayer(int, int)}, only that it takes a
+   * component parameter, which should be ignored in the search. This is
+   * necessary to support [EMAIL PROTECTED] #setLayer(Component, int, int)} which uses
+   * Container.setComponentZOrder(), which doesn't remove the component.
+   *
+   * @param comp the component to ignore
+   * @param layer the layer
+   * @param position the position
+   *
+   * @return the insertion index
+   */
+  private int insertIndexForLayer(Component comp, int layer, int position)
+  {
+    // Create the component list to search through.
+    ArrayList l = new ArrayList();
+    int count = getComponentCount();
+    for (int i = 0; i < count; i++)
+      {
+        Component c = getComponent(i);
+        if (c != comp)
+          l.add(c);
+      }
 
-    // Try to find the start index of the specified layer.
-    int p = -1;
-    for (int i = 0; i < components.length; i++)
-      {
-        int l = getLayer(components[i]);
-        if (l > layer)
-          index++;
-        // If we are in the layer we look for, try to find the position.
-        else if (l == layer)
+    count = l.size();
+    int layerStart = -1;
+    int layerEnd = -1;
+    for (int i = 0; i < count; i++)
+      {
+        int layerOfComponent = getLayer((Component) l.get(i));
+        if (layerStart == -1 && layerOfComponent == layer)
+          layerStart = i;
+        if (layerOfComponent < layer)
           {
-            p++;
-            if (p < position)
-              index++;
+            // We are beyond the layer that we are looking for. Update the
+            // layerStart and layerEnd and exit the loop.
+            if (i == 0)
+              {
+                layerStart = 0;
+                layerEnd = 0;
+              }
             else
-              break;
+              layerEnd = i;
+            break;
           }
-        // No need to look further if the layer at i is smaller than layer.
+      }
+
+    // No layer found. The requested layer is lower than any existing layer,
+    // put the component at the end.
+    int insertIndex;
+    if (layerStart == -1 && layerEnd == -1)
+      {
+        insertIndex = count;
+      }
+    else
+      {
+        // Corner cases.
+        if (layerStart != -1 && layerEnd == -1)
+          layerEnd = count;
+        if (layerStart == -1 && layerEnd != -1)
+          layerStart = layerEnd;
+
+        // Adding to the bottom of a layer returns the end index
+        // in the layer.
+        if (position == -1)
+          insertIndex = layerEnd;
         else
-          break;
+          {
+            // Insert into a layer.
+            if (position > -1 && layerStart + position <= layerEnd)
+              insertIndex = layerStart + position;
+            else
+              insertIndex = layerEnd;
+          }
       }
-    return index;
+    return insertIndex;
   }
 
   /**
    * Removes a child from this container. The child is specified by
    * index. After removal, the child no longer occupies a layer.
    *
    * @param index the index of the child component to remove.
    */
   public void remove(int index)
   {
     Component c = getComponent(index);
     if (! (c instanceof JComponent))
       componentToLayer.remove(c);
     super.remove(index);
   }
 
   /**
    * Removes all components from this container.
    *
    * @since 1.5
@@ -542,81 +592,96 @@
    * component is added to the container.</p>
    *
    * @param c the component to set the layer property for.
    * @param layer the layer number to assign to the component.
    */
   public void setLayer(Component c, int layer)
   {
     setLayer(c, layer, -1);
   }
 
   /**
    * Set the layer and position of a component, within this container.
    *
    * @param c the child component to set the layer property for.
    * @param layer the layer number to assign to the component.
    * @param position the position number to assign to the component.
    */
   public void setLayer(Component c, int layer, int position)
   {
     Integer layerObj = getObjectForLayer(layer);
-    if (c instanceof JComponent)
+
+    // Nothing to do if neither the layer nor the position is
+    // changed.
+    if (layer != getLayer(c) || position != getPosition(c))
       {
-        JComponent jc = (JComponent) c;
-        jc.putClientProperty(LAYER_PROPERTY, layerObj);
-      }
-    else
-      componentToLayer.put (c, layerObj);
+        // Store the layer either in the JComponent or in the hashtable
+        if (c instanceof JComponent)
+          {
+            JComponent jc = (JComponent) c;
+            jc.putClientProperty(LAYER_PROPERTY, layerObj);
+          }
+        else
+          componentToLayer.put (c, layerObj);
 
-    // Set position only of component is already added to this layered pane.
-    if (getIndexOf(c) != -1)
-      setPosition(c, position);
+        // Update the component in the Z order of the Container.
+        Container parent = c.getParent();
+        if (parent == this)
+          {
+            int index = insertIndexForLayer(c, layer, position);
+            setComponentZOrder(c, index);
+          }
+      }
+    repaint(c.getX(), c.getY(), c.getWidth(), c.getHeight());
   }
 
   /**
    * Overrides the default implementation from [EMAIL PROTECTED] java.awt.Container}
    * such that <code>layerConstraint</code> is interpreted as an [EMAIL PROTECTED]
    * Integer}, specifying the layer to which the component will be added
    * (at the bottom position).
    *
    * The argument <code>index</code> specifies the position within the layer
    * at which the component should be added, where <code>0</code> is the top
    * position greater values specify positions below that and <code>-1</code>
    * specifies the bottom position.
    *
    * @param comp the component to add
    * @param layerConstraint an integer specifying the layer to add the
    *        component to
    * @param index the position within the layer
    */
   protected void addImpl(Component comp, Object layerConstraint, int index) 
   {
     int layer;
     if (layerConstraint != null && layerConstraint instanceof Integer)
-      layer = ((Integer) layerConstraint).intValue();
+      {
+        layer = ((Integer) layerConstraint).intValue();
+        setLayer(comp, layer);
+      }
     else
-	  layer = getLayer(comp);
+      layer = getLayer(comp);
 
     int newIdx = insertIndexForLayer(layer, index);
-    setLayer(comp, layer);
     super.addImpl(comp, layerConstraint, newIdx);
-    repaint(comp.getX(), comp.getY(), comp.getWidth(), comp.getHeight());
+    comp.validate();
+    comp.repaint();
   }
 
   /**
    * Sets the layer property for a JComponent.
    *
    * @param component the component for which to set the layer
    * @param layer the layer property to set
    */
   public static void putLayer(JComponent component, int layer)
   {
     component.putClientProperty(LAYER_PROPERTY, new Integer(layer));
   }
 
   /**
    * Returns the accessible context for this <code>JLayeredPane</code>.
    *
    * @return the accessible context for this <code>JLayeredPane</code>
    */
   public AccessibleContext getAccessibleContext()
   {

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

Reply via email to