JDK-6235079 : JFrame.setLayout(BoxLayout) causes an exception
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 5.0
  • Priority: P4
  • Status: Closed
  • Resolution: Won't Fix
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2005-03-02
  • Updated: 2010-04-02
  • Resolved: 2005-03-02
Description
FULL PRODUCT VERSION :
java version "1.5.0_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_01-b08)
Java HotSpot(TM) Client VM (build 1.5.0_01-b08, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]
Likely all other OSs, this is not OS specific

A DESCRIPTION OF THE PROBLEM :
This problem occurs with javax.swing.BoxLayout and with javax.swing.OverlayLayout that I know of. Both of these LayoutManagers take a Container as an argument to their constructors. Various methods of these classes accept a Container as an argument and check it against the constructor-provided container to ensure they are the same. I don't know why they need to be the same. The methods in BoxLayout that do this are as follows:
invalidateLayout
preferredLayoutSize
minimumLayoutSize
maximumLayoutSize
getLayoutAlignmentX
getLayoutAlignmentY
layoutContainer

This is the method that they call:
    void checkContainer(Container target) {
        if (this.target != target) {
            throw new AWTError("BoxLayout can't be shared");
        }
    }

The problem occurs when using the new convenience method, JFrame.setLayout, provided in Java 1.5. This method sets the layout of the contentPane, not of the JFrame as it first appears. Therefore:
myJFrame.setLayout(new BoxLayout(myJFrame));

causes an exception. It can be very difficult for someone unfamiliar with JFrames to figure this out.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
No exceptions.
ACTUAL -
An exception is thrown.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "main" java.awt.AWTError: BoxLayout can't be shared
				at javax.swing.BoxLayout.checkContainer(BoxLayout.java:415)
				at javax.swing.BoxLayout.invalidateLayout(BoxLayout.java:202)
				at java.awt.Container.invalidate(Container.java:1417)
				at java.awt.Component.addNotify(Component.java:5879)
				at java.awt.Container.addNotify(Container.java:2493)
				at javax.swing.JComponent.addNotify(JComponent.java:4436)
				at java.awt.Container.addNotify(Container.java:2500)
				at javax.swing.JComponent.addNotify(JComponent.java:4436)
				at java.awt.Container.addNotify(Container.java:2500)
				at javax.swing.JComponent.addNotify(JComponent.java:4436)
				at javax.swing.JRootPane.addNotify(JRootPane.java:680)
				at java.awt.Container.addNotify(Container.java:2500)
				at java.awt.Window.addNotify(Window.java:458)
				at java.awt.Frame.addNotify(Frame.java:501)
				at java.awt.Window.pack(Window.java:476)
				at BoxLayoutBug.main(BoxLayoutBug.java:9)


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import javax.swing.JFrame;
import javax.swing.BoxLayout;

public class BoxLayoutBug {

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setLayout(new BoxLayout(frame, BoxLayout.PAGE_AXIS));
        frame.pack();
    }
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Pass the JFrame's contentPane to the BoxLayout's constructor.
###@###.### 2005-03-02 19:11:05 GMT

Comments
EVALUATION Affects GroupLayout too.
05-04-2006

EVALUATION The JFrame.seyLayout() method has been provided for convenience and it is clearly documented to forward the call to the content pane. I agree that there is now the possibility of confusion, but there is little we can do to allay that. Changes to BoxLayout to deal with this would be hacks at best. We'll have to hope that developers read and understand the documentation. If this continues to come up, or receives more votes, it may be worthwhile to make a special mention of this case in the documentation for JFrame.setLayout(). For now, closing as will not fix. ###@###.### 2005-03-02 19:43:47 GMT
02-03-2005