This week's book giveaways are in the Java EE and JavaScript forums.
We're giving away four copies each of The Java EE 7 Tutorial Volume 1 or Volume 2(winners choice) and jQuery UI in Action and have the authors on-line!
See this thread and this one for details.
The moose likes Swing / AWT / SWT and the fly likes Swing - Content Pane vs. Panel - have I got this right? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of The Java EE 7 Tutorial Volume 1 or Volume 2 this week in the Java EE forum
or jQuery UI in Action in the JavaScript forum!
JavaRanch » Java Forums » Java » Swing / AWT / SWT
Bookmark "Swing - Content Pane vs. Panel - have I got this right?" Watch "Swing - Content Pane vs. Panel - have I got this right?" New topic
Author

Swing - Content Pane vs. Panel - have I got this right?

Janet Wilson
Ranch Hand

Joined: Jul 16, 2002
Posts: 98
Hi folks,
After much struggling with the Java Tutorial found on Sun's site and some searching around I think I finally have the concept of JFrame--Content Pane--Panel figured out at the beginner's level but would like to bounce this off the group for confirmation (assumes I am working with JFrame vs. the other top-level containers).
1. When I instantiate my JFrame I get the JRootPane.
2. If I want a menu bar, I would add that to the JFrame.
3. There is a 1:1 relationship between the JFrame and Content Pane. In other words, I issue this statement:
Container contentPane = getContentPane();
in my JFrame definition.
4. I could place components directly on the contentPane container, but it's best to place them on a JPanel.
5. I can stack 1 or more JPanels on the contentPane.
I wrote a bunch of little programs to help me arrive at this but I haven't found anything which confirms that this is the "PROPER" way to think of things. Could someone either confirm this or "show me the way"?
Thanks a bunch! Janet
Gregg Bolinger
GenRocket Founder
Ranch Hand

Joined: Jul 11, 2001
Posts: 15299
    
    6

Sounds good to me. Couple of things.
I would never use Container contentPane = getContentPane(). Either create a JPanel and do setContentPane(panel) or if adding directly to the contentPane do getContentPane().add(component).
But everything else seems correct to me.


GenRocket - Experts at Building Test Data
Janet Wilson
Ranch Hand

Joined: Jul 16, 2002
Posts: 98
Gregg,
Thanks for reviewing this so quickly. Of course, I have the natural question....why did you say:
I would never use Container contentPane = getContentPane().

If I have:
Container contentPane = getContentPane();
-or-
JPanel contentPane = new JPanel();
Followed by (later in the code):
setContentPane(contentPane);
It generates the same results (or at least it does in my lame examples). Is it slower using the Container -or- is it just a commonly accepted way to use the JPanel?
Thanks! Janet
Gregg Bolinger
GenRocket Founder
Ranch Hand

Joined: Jul 11, 2001
Posts: 15299
    
    6

The main reason you don't want to use Container is because it is an AWT component. And as your example implies, you are using SWING components. Mixing Swing and AWT components is not a good idea.
Hope that helps.
Janet Wilson
Ranch Hand

Joined: Jul 16, 2002
Posts: 98
Gregg,
Helps a great deal!
Thanks! Janet
Josh Rehman
Ranch Hand

Joined: Jul 24, 2001
Posts: 63
Gregg is wrong. getContentPane() does not return an AWT component. It returns an instance of JPanel. You can always do this:

JPanel is a subclass of java.awt.Container. Perhaps that's where the confusion comes from.
But JFrame doesn't have any special class for it's contentPane member. It's just a JPanel.
Janet Wilson
Ranch Hand

Joined: Jul 16, 2002
Posts: 98
Hi guys,
Ok, here's my "play code" which I am using to try to learn from. Is this ok or am I grossly violating some rule(s)?

It does what I have asked it to do. Thanks for looking at this.
Janet
[ October 22, 2002: Message edited by: Janet Wilson ]
Josh Rehman
Ranch Hand

Joined: Jul 24, 2001
Posts: 63
Looks good!
There are 3 ways to add content to a frame:
1 - Create a panel, add it as the content pane (this is what you did).
2 - Create a panel, and add it TO the content pane. (This is probably the most common. However, it's a tad wasteful.)
3 - Get a panel with getContentPane, and use it.
In code, here are the three snippets:
1-
JPanel panel = new JPanel();
myFrame.setContentPane(panel);
2-
JPanel panel = new JPanel();
myFrame.getContentPane().add(panel);
3-
JPanel panel = (JPanel) myFrame.getContentPane();
Which method you choose is largely a matter of style. #1 Wastes cycles on the creation of an object. #2 Wastes cycles on the creation of an object, and space on maintaining 2 objects. #3 Doesn't waste anything. So my preference is 3, 1, 2, but it really doesn't matter too much either way.
Gregg Bolinger
GenRocket Founder
Ranch Hand

Joined: Jul 11, 2001
Posts: 15299
    
    6

Originally posted by Josh Rehman:
Gregg is wrong. getContentPane() does not return an AWT component. It returns an instance of JPanel. You can always do this:

JPanel is a subclass of java.awt.Container. Perhaps that's where the confusion comes from.
But JFrame doesn't have any special class for it's contentPane member. It's just a JPanel.


I didn't say getContentPane returned an AWT component, but now that you bring it up, it does. I said Container is an AWT component.
And getContentPane() does not return an instance of JPanel. If it did, you would not have to cast as you did in your sample code. getContentPane() returns Container which is a top level AWT component.
So who is wrong?
Josh Rehman
Ranch Hand

Joined: Jul 24, 2001
Posts: 63
You are wrong.
Gregg Bolinger
GenRocket Founder
Ranch Hand

Joined: Jul 11, 2001
Posts: 15299
    
    6

Would you care to tell me what I am wrong about?

getContentPane
public Container getContentPane()Returns the contentPane object for this frame.
Specified by:
getContentPane in interface RootPaneContainer
Returns:
the contentPane property

taken from here
So you see, it does return an AWT component (Container)
[ October 22, 2002: Message edited by: Gregg Bolinger ]
Josh Rehman
Ranch Hand

Joined: Jul 24, 2001
Posts: 63
frame.getContentPane().getClass() != Container.class
Janet Wilson
Ranch Hand

Joined: Jul 16, 2002
Posts: 98
Josh/Gregg - Thanks for the additional information. Since I didn't hear any debate re: the efficiency of option #3, I have changed my code accordingly. After I complete my beginner's review of Swing, I was going to move on to understanding threads.
Thanks! Janet
Nathan Pruett
Bartender

Joined: Oct 18, 2000
Posts: 4121

Greg,

Actually, the bad thing to do is mix AWT (Heavy Weight) components (widgets), and Swing (Light Weight) components (widgets). Container is not a widget in AWT... it's simply a class in the awt package. Swing was built off of AWT, so there is a lot of re-use of AWT classes. For example, JPanel is a Swing light weight component, but it is also a Container... so is JDesktopPane, JScrollPane, and all other components that can hold other components... since Container is one of their common ancestor super classes. It is fine to mix Swing and AWT classes, just not Swing and AWT components.


-Nate
Write once, run anywhere, because there's nowhere to hide! - /. A.C.
Josh Rehman
Ranch Hand

Joined: Jul 24, 2001
Posts: 63
There seems to be this common misconception about inheritence. Part of the problem is the language, the whole 'is a' relationship. Here we see this lack of words rear it's ugly head. Yes, a JPanel is a Container, in the sense that Container is a superclass of JPanel. However, if I create a new JPanel, the class of that object is JPanel, not Container. Sure, I can cast the object into Container, but all this does is limit the API of that object -- I'd have to cast again to regain the full API. The object's class IS NOT Container. It is JPanel. So now if someone asks you, if x is an a, is x's class a, you can firmly tell them "not always".
One of the very important ways this distinction is important is in the implemnentation of a valid equals() method. You should never test with instanceof if you maintain symmetry (which you always should, per the documentation in Object). Instead you should use getClass and check for strict equality.
Consider a hypothetical Container equals method:
public boolean equals(Object o){
if (o instanceof Container){
// do some processing
return true;
} else {
return false;
}
}
Now you have Container.equals(JPanel) but !JPanel.equals(Container) (assuming that the equals method was overriden in JPanel in a similiar way).
The correct implementnation is to use getClass().
 
 
subject: Swing - Content Pane vs. Panel - have I got this right?