Ellen Spertus
Ellen Spertus

Reputation: 6815

Why did JFrame originally require getContentPane() for adding components

I know that, as of Java 1.5, one can add a component to a JFrame like this:

myFrame.add(myButton);

instead of:

myFrame.getContentPane().add(myButton);

Why wasn't this always the case?

Upvotes: 8

Views: 1553

Answers (2)

mre
mre

Reputation: 44250

4753342: Swing's top level component should redirect add/remove methods to ContentPane

Description:

Contrary to AWT programming, JFrame/JDialg/JWindow/JApplet/JInternalFrame do not allow you to add Components to it, instead you must learn about JRootPane and add children Components to it. This adds needless confusion to new developers.

Prior to 5.0, attempting to add or remove a Component from one of these top level Components would result in an exception be thrown. In 5.0, no exception will be thrown, instead the Component will be added or removed from the content pane. This resulted in several revisions to the javadoc of JFrame, JDialog, JWindow, JApplet and JInternalFrame. This has been summarized in RootPaneContainer's javadoc:

 * For conveniance
 * <code>JFrame</code>, <code>JDialog</code>, <code>JWindow</code>,
 * <code>JApplet</code> and <code>JInternalFrame</code>, by default,
 * forward all calls to <code>add</code> and its variants,
 * <code>remove</code> and <code>setLayout</code> to the
 * <code>contentPane</code>. This means rather than writing:
 * <pre>
 * rootPaneContainer.getContentPane().add(component);
 * </pre>
 * you can do:
 * <pre>
 * rootPaneContainer.add(component);
 * </pre>
 * <p>
 * The behavior of <code>add</code> and its variants and
 * <code>setLayout</code> for
 * <code>JFrame</code>, <code>JDialog</code>, <code>JWindow</code>,
 * <code>JApplet</code> and <code>JInternalFrame</code> is controlled by
 * the <code>rootPaneCheckingEnabled</code> property. If this property is
 * true, the default, then <code>add</code> and its variants and
 * <code>setLayout</code> are
 * forwarded to the <code>contentPane</code>, if it is false, then these
 * methods operate directly on the <code>RootPaneContainer</code>. This
 * property is only intended for subclasses, and is therefor protected.

Also, here's a related bug:

Upvotes: 7

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285405

As is spelled out in the JFrame API, both do the same thing: add a component to the contentPane. It's just recently (Java 1.5 perhaps?) Swing added the syntactic sugar/convenience method to allow you to make this call directly on the JFrame (or any other Swing top-level container), but you're still adding to the contentPane. Same for remove(...) and setLayout(...) This becomes all too clear if you try to set the background color of the JFrame via myJFrame.setBackground(Color.green); and nothing happens. It is for this reason, I'm not too happy with this change. That and also because I must be an old curmudgeon.

Upvotes: 9

Related Questions