Hi there,

I removed the caching of the preferredSize in JRootPane.RootLayout. I
have an app here that has a problem with it. The exact problem is this:
while building the GUI and layouting, the RootLayout is asked for its
preferredSize while beeing in an invalid state. This (wrong)
preferredSize is then cached. After this, the contentPane is modified so
that the preferredSize is affected. However, when the container calls
preferredLayoutSize() the next time the cached value is returned, which
is wrong. I wrote some mauve tests that confirm that the RootLayout
should not cache its preferredSize (and one that confirms that Container
should not invalidate the layout before asking the preferredSize of an
invalid container).

Maybe we should add some comments to the API docs for LayoutManager,
this seems like a potential programming mistake that can also happen to
application developers? Caching layout info is ok and actually makes
sense, but caching preferredSize can easily lead to incorrect layout,
except when the caching is done in a way that the valid state of the
container is also considered.

2006-01-30  Roman Kennke  <[EMAIL PROTECTED]>

        * javax/swing/JRootPane.java
        (RootLayout.prefSize): Removed caching for preferredSize.
        (RootLayout.invalidateLayout): Likewise.
        (RootLayout.preferredLayoutSize): Likewise.

/Roman
Index: javax/swing/JRootPane.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/JRootPane.java,v
retrieving revision 1.32
diff -u -r1.32 JRootPane.java
--- javax/swing/JRootPane.java	8 Nov 2005 14:12:45 -0000	1.32
+++ javax/swing/JRootPane.java	30 Jan 2006 21:13:13 -0000
@@ -120,11 +120,6 @@
     private Rectangle menuBarBounds;
 
     /**
-     * The cached preferred size.
-     */
-    private Dimension prefSize;
-
-    /**
      * Creates a new <code>RootLayout</code> object.
      */
     protected RootLayout()
@@ -191,7 +186,6 @@
           layeredPaneBounds = null;
           contentPaneBounds = null;
           menuBarBounds = null;
-          prefSize = null;
         }
     }
 
@@ -287,29 +281,20 @@
      */
     public Dimension preferredLayoutSize(Container c)
     {
-      // We must synchronize here, otherwise we cannot guarantee that the
-      // prefSize is still non-null when returning.
-      synchronized (this)
+      Dimension prefSize = new Dimension();
+      Insets i = getInsets();
+      prefSize = new Dimension(i.left + i.right, i.top + i.bottom);
+      Dimension contentPrefSize = contentPane.getPreferredSize();
+      prefSize.width += contentPrefSize.width;
+      prefSize.height += contentPrefSize.height;
+      if (menuBar != null)
         {
-          if (prefSize == null)
-            {
-              Insets i = getInsets();
-              prefSize = new Dimension(i.left + i.right, i.top + i.bottom);
-              Dimension contentPrefSize = contentPane.getPreferredSize();
-              prefSize.width += contentPrefSize.width;
-              prefSize.height += contentPrefSize.height;
-              if (menuBar != null)
-                {
-                  Dimension menuBarSize = menuBar.getPreferredSize();
-                  if (menuBarSize.width > contentPrefSize.width)
-                    prefSize.width += menuBarSize.width - contentPrefSize.width;
-                  prefSize.height += menuBarSize.height;
-                }
-            }
-          // Return a copy here so the cached value won't get trashed by some
-          // other component.
-          return new Dimension(prefSize);
-      }
+          Dimension menuBarSize = menuBar.getPreferredSize();
+          if (menuBarSize.width > contentPrefSize.width)
+            prefSize.width += menuBarSize.width - contentPrefSize.width;
+          prefSize.height += menuBarSize.height;
+        }
+      return prefSize;
     }
 
     /**

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

Reply via email to