This fixes a mauve test for JLayeredPane. In order to fix this, I implemented the set/getComponentZOrder() methods in Container and made JLayeredPane use these methods. This is not only much more efficient than adding/removing components when changing the order, it also fixes a nasty problem when there is a layout manager installed on the JLayeredPane (which is discouraged but not forbidden).
2006-02-04 Roman Kennke <[EMAIL PROTECTED]> * java/awt/Container.java (getComponentZOrder): New method. (setComponentZOrder): New method. * javax/swing/JLayeredPane.java (setPosition): Reimplemented to use setComponentZOrder(). (getIndexOf): Reimplemented to use getComponentZOrder(). (addImpl): Pass layerContraint to super call. Important for possibly installed layout managers. (swapComponents): Remove unneeded method. /Roman
Index: java/awt/Container.java =================================================================== RCS file: /cvsroot/classpath/classpath/java/awt/Container.java,v retrieving revision 1.77 diff -u -r1.77 Container.java --- java/awt/Container.java 27 Jan 2006 15:51:21 -0000 1.77 +++ java/awt/Container.java 4 Feb 2006 11:04:18 -0000 @@ -1565,6 +1565,93 @@ changeSupport.addPropertyChangeListener (name, listener); } + + /** + * Sets the Z ordering for the component <code>comp</code> to + * <code>index</code>. Components with lower Z order paint above components + * with higher Z order. + * + * @param comp the component for which to change the Z ordering + * @param index the index to set + * + * @throws NullPointerException if <code>comp == null</code> + * @throws IllegalArgumentException if comp is an ancestor of this container + * @throws IllegalArgumentException if <code>index</code> is not in + * <code>[0, getComponentCount()]</code> for moving between + * containers or <code>[0, getComponentCount() - 1]</code> for moving + * inside this container + * @throws IllegalArgumentException if <code>comp == this</code> + * @throws IllegalArgumentException if <code>comp</code> is a + * <code>Window</code> + * + * @see #getComponentZOrder(Component) + * + * @since 1.5 + */ + public final void setComponentZOrder(Component comp, int index) + { + if (comp == null) + throw new NullPointerException("comp must not be null"); + if (comp instanceof Container && ((Container) comp).isAncestorOf(this)) + throw new IllegalArgumentException("comp must not be an ancestor of " + + "this"); + if (comp instanceof Window) + throw new IllegalArgumentException("comp must not be a Window"); + + if (comp == this) + throw new IllegalArgumentException("cannot add component to itself"); + + // FIXME: Implement reparenting. + if ( comp.getParent() != this) + throw new AssertionError("Reparenting is not implemented yet"); + else + { + // Find current component index. + int currentIndex = getComponentZOrder(comp); + if (currentIndex < index) + { + System.arraycopy(component, currentIndex + 1, component, + currentIndex, index - currentIndex); + } + else + { + System.arraycopy(component, index, component, index + 1, + currentIndex - index); + } + component[index] = comp; + } + } + + /** + * Returns the Z ordering index of <code>comp</code>. If <code>comp</code> + * is not a child component of this Container, this returns <code>-1</code>. + * + * @param comp the component for which to query the Z ordering + * + * @return the Z ordering index of <code>comp</code> or <code>-1</code> if + * <code>comp</code> is not a child of this Container + * + * @see #setComponentZOrder(Component, int) + * + * @since 1.5 + */ + public final int getComponentZOrder(Component comp) + { + int index = -1; + if (component != null) + { + for (int i = 0; i < component.length; i++) + { + if (component[i] == comp) + { + index = i; + break; + } + } + } + return index; + } + // Hidden helper methods. /** Index: javax/swing/JLayeredPane.java =================================================================== RCS file: /cvsroot/classpath/classpath/javax/swing/JLayeredPane.java,v retrieving revision 1.42 diff -u -r1.42 JLayeredPane.java --- javax/swing/JLayeredPane.java 1 Feb 2006 12:17:13 -0000 1.42 +++ javax/swing/JLayeredPane.java 4 Feb 2006 11:04:18 -0000 @@ -353,16 +353,9 @@ */ public void setPosition(Component c, int position) { - int currentPos = getPosition(c); - if (currentPos == position) - return; - int layer = getLayer(c); - int i1 = position; - int i2 = getPosition(c); - int incr = (i1 - i2) / Math.abs(i1 - i2); - for (int p = i2; p != i1; p += incr) - swapComponents(p, p + incr, layer); + int index = insertIndexForLayer(layer, position); + setComponentZOrder(c, index); } /** @@ -432,17 +425,7 @@ */ public int getIndexOf(Component c) { - int index = -1; - Component[] components = getComponents(); - for (int i = 0; i < components.length; ++i) - { - if (components[i] == c) - { - index = i; - break; - } - } - return index; + return getComponentZOrder(c); } /** @@ -604,7 +587,7 @@ int newIdx = insertIndexForLayer(layer, index); setLayer(comp, layer); - super.addImpl(comp, null, newIdx); + super.addImpl(comp, layerConstraint, newIdx); } /** @@ -689,28 +672,4 @@ } return result; } - - /** - * Swaps the components at position i and j, in the specified layer. - * - * @param i the position of the 1st component in its layer - * @param j the position of the 2nd component in its layer - * @param layer the layer in which the components reside - */ - private void swapComponents (int i, int j, int layer) - { - int p1 = Math.min(i, j); - int p2 = Math.max(i, j); - Component[] layerComps = getComponentsInLayer(layer); - int layerOffs = getIndexOf(layerComps[0]); - Component c1 = layerComps[p1]; - Component c2 = layerComps[p2]; - // remove() wants the real index. - remove(p2 + layerOffs); - remove(p1 + layerOffs); - // add() wants the position within the layer. - Integer l = getObjectForLayer(layer); - add(c2, l, p1); - add(c1, l, p2); - } }