File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

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

 
Janet Wilson
Ranch Hand
Posts: 98
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 15302
6
Chrome IntelliJ IDE Mac OS X
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.
 
Janet Wilson
Ranch Hand
Posts: 98
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 15302
6
Chrome IntelliJ IDE Mac OS X
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 98
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Gregg,
Helps a great deal!
Thanks! Janet
 
Josh Rehman
Ranch Hand
Posts: 63
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 98
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 63
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 15302
6
Chrome IntelliJ IDE Mac OS X
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 63
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You are wrong.
 
Gregg Bolinger
GenRocket Founder
Ranch Hand
Posts: 15302
6
Chrome IntelliJ IDE Mac OS X
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 63
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
frame.getContentPane().getClass() != Container.class
 
Janet Wilson
Ranch Hand
Posts: 98
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 4121
IntelliJ IDE Java Spring
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.
 
Josh Rehman
Ranch Hand
Posts: 63
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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().
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic