The attached patch fixes two issues with JLayeredPane. It avoids a
potential memory leak that comes from not overriding removeAll in
JLayeredPane. Calling removeAll() would cause components to be removed
but their layer information to be kept forever in JLayeredPane's
Hashtable.

Also, I improved the isOptimizedDrawingEnabled method so that it
accurately calculates if child components overlap or not. Before, I had
a heuristic there that returns false for #components>2. Now I go through
all the components and compare their rectangles. This is surprisingly
efficient, I had a JLayeredPane here with 9 children and this method
still took 1ms or less. As a reward the painting is done more efficient,
which is well worth the effort.

2006-02-13  Roman Kennke  <[EMAIL PROTECTED]>

        * javax/swing/JLayeredPane.java
        (removeAll): New method. Avoid potential memory leak.
        (isOptimizedDrawingEnabled): Replaced heuristic with accurate
        calculation.

/Roman
Index: javax/swing/JLayeredPane.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/JLayeredPane.java,v
retrieving revision 1.43
diff -u -r1.43 JLayeredPane.java
--- javax/swing/JLayeredPane.java	4 Feb 2006 11:08:43 -0000	1.43
+++ javax/swing/JLayeredPane.java	14 Feb 2006 11:12:57 -0000
@@ -523,6 +523,17 @@
   }
 
   /**
+   * Removes all components from this container.
+   *
+   * @since 1.5
+   */
+  public void removeAll()
+  {
+	componentToLayer.clear();
+	super.removeAll();
+  }
+
+  /**
    * <p>Set the layer property for a component, within this container. The
    * component will be implicitly mapped to the bottom-most position in the
    * layer, but only if added <em>after</em> calling this method.</p>
@@ -646,30 +657,33 @@
   public boolean isOptimizedDrawingEnabled()
   {
     int numChildren = getComponentCount();
-    boolean result = false;
-    // We implement a heuristic here in order to return a quick result:
-    // - For 0 or 1 children it is clear that they do not overlap, return true.
-    // - For 2 children we check their bounding rectangles and if they don't
-    //   interect, return true.
-    // - For more than 2 children we return false. Comparing all the bounding
-    //   rectangles costs too much time and in most cases this will return
-    //   false anyway, since JLayeredPane are mostly used in JRootPane and then
-    //   have at least one child (the contentPane) that takes up the whole
-    //   area of the JLayeredPane.
-    switch (numChildren)
-    {
-      case 0:
-      case 1:
-        result = true;
-        break;
-      case 2:
-        Rectangle r1 = getComponent(0).getBounds();
-        Rectangle r2 = getComponent(1).getBounds();
-        result = !r1.intersects(r2);
-        break;
-      default:
-        result = false;
-    }
+    boolean result = true;
+    for (int i = 0; i < numChildren; ++i)
+      {
+    	Component c1 = getComponent(i);
+    	if (! c1.isVisible())
+          continue;
+    	Rectangle r1 = c1.getBounds();
+    	if (r1.isEmpty())
+          continue;
+
+    	for (int j = i + 1; j < numChildren; ++j)
+          {
+            Component c2 = getComponent(j);
+            if (! c2.isVisible())
+              continue;
+            Rectangle r2 = c2.getBounds();
+            if (r2.isEmpty())
+              continue;
+            if (r1.intersects(r2))
+              {
+                result = false;
+                break;
+              }
+            if (result == false)
+              break;
+          }
+      }
     return result;
   }
 }

Reply via email to