5

I am learning Java Swing and I appended a menuBar to the frame. By default this should call jframe.getContentPane().add(child). When I ran the script the menuBar didn't show up. But the button was at the very top "y=0" if that makes sense.

Then I realized my mistake I actually had to put in a menu in the menubar. Then the menuBar showed up. So that got me thinking...is the "menubar" "contentpane" actually 2 panels? It is confusing the hell out of me. Because that acted a lot like a panel. But getContentPane() returns a Container, not a JPanel object so I'm confused.

If so, does that mean that the only thing that is dumped directly into a frame are just Jpanel objects? Hence JButtons, JLabels are not directly in a frame... Does that mean, jpanels are "nested"? One more thing that is confusing me. If a jpanel can control how things are positioned, what is a LayoutManager for? :S Thanks, and please answer as if to a 2yr old asking why the sky is blue,ha ;)

mKorbel
  • 109,525
  • 20
  • 134
  • 319
Lews Therin
  • 10,907
  • 4
  • 48
  • 72
  • Looks like JPanel extends Container. http://download.oracle.com/javase/6/docs/api/javax/swing/JPanel.html – Bhesh Gurung Oct 13 '11 at 18:54
  • "If a jpanel can control how things are positioned, what is a LayoutManager for?" A `JPanel` can't control how things are positioned, that's exactly what the `LayoutManager`s do. – Nate W. Oct 13 '11 at 19:05
  • Right I guess is more about how things are displayed or organized and not about the locations of components on the screen – Lews Therin Oct 13 '11 at 22:20
  • 1
    See also [`JRootPane`](http://download.oracle.com/javase/7/docs/api/javax/swing/JRootPane.html), the lightweight container used `JFrame`, _et al_. – trashgod Oct 13 '11 at 22:56
  • @trashgod that answers *some* of my question. Ah, it seems that the JRootPane acts as the JComponent that JFrame isn't... I still don't know why it implements setJMenuBar separately, I'm sure there is a reason..damn. – Lews Therin Oct 13 '11 at 23:11
  • 1
    Click though to [How to Use Root Panes](http://download.oracle.com/javase/tutorial/uiswing/components/rootpane.html). – trashgod Oct 13 '11 at 23:15

4 Answers4

10

Some random thoughts:

  • Yes, JPanels and other components are often "nested". This is where a firm understanding of the Swing/AWT layout managers is essential.
  • While the type returned by a JFrame's getContentPane() is technically a Container, it's also a JPanel (which inherits eventually from Container).
  • I believe that you can make anything that derives from Container the contentPane, but you need to take care that it is opaque.
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • So is there actually one JPanel by default when there is no JMenuBar used? Forgetting other explicit jpanels of course. And if you added a JMenuBar, it creates 2 JPanels by default? One for the MenuBar and one for the Content. Why is a layout manager different? – Lews Therin Oct 13 '11 at 18:59
  • 2
    There's one JPanel when you start. If you add a JMenuBar, there is that same JPanel and now a JMenuBar, not two JPanels. I don't understand your last question -- why is what layout manager different. – Hovercraft Full Of Eels Oct 13 '11 at 19:01
  • You are right. When I tried a `jframe.add(menuBar)` it doesn't actually show anything. With `setJMenuBar(menuBar)` it does show something..which means It sets the menuBar to (0,0) by default if it doesn't create another JPanel... I mean how is it that a JPanel is different from a Layout as a JPanel can also position items or other components position themselves – Lews Therin Oct 13 '11 at 19:03
  • @Hovercraft Full Of Eels (not sure) maybe CardLayout?? – mKorbel Oct 13 '11 at 19:04
  • 1
    A JPanel and a layout manager are two completely different beasts. JPanels and anything that derives from Component ***use*** layout managers. The JPanel is the component that is displayed in the GUI, and the layout is the way that that containers (which includes JPanels) arrange the components that they hold. So if your JPanel holds other components, you'd better be familiar with which layout manager it is using and how that layout manager works. – Hovercraft Full Of Eels Oct 13 '11 at 19:05
  • @Lews Therin can you please to split your question to the separated areas, because you jumping ...., – mKorbel Oct 13 '11 at 19:07
  • @mKorbel Sure, I will.. I still don't understand LayoutManagers, so might as well. – Lews Therin Oct 13 '11 at 19:09
3

for that there is method

frame.setJMenuBar(menuBar);

for todays Java Swing GUI, is not neccesary declare ContentPane, from Java5, and with BorderLayout as default LayoutManager

then frame.add(myPanel); //is same as frame.add(myPanel, BorderLayout.CENTER) and occupated whole Container

basic stuff about how to use LayourManagers

mKorbel
  • 109,525
  • 20
  • 134
  • 319
1

getContentPane() always returns a Container instance. However, you should note that JPanel objects are Container instances, as well as other classes in the Swing framework. The actual class of the instance returned is irrelevant, as you do not have control over which implementation of Container is used as a contentPane (unless you have forced a specific contentPane), and most of the time this should not be a problem.

You can add many GUI widgets in a JFrame, such as JButton, JLabel, etc. However, they will be automatically added to the associated contentPane.

JPanel does not handle the objects positioning, the LayoutManager associated with your panel does; either automatically based on its own set of rules (e.g. FlowLayout), or by using the constraints you have specified when adding the object to the container (the GridBagLayout layout manager is a good example). The JavaDoc on the LayoutManagers usually contain enough information to get you started on using them.

You can have nested panels, yes. A Container can contain other Container instances. While it seems to be a complicated solution, it does enable you to control exactly how your GUI is displayed. Depending on which LayoutManager you are using, on the needs you have to fulfill with your user interface, and on your own preferences/habits as a developper, you might need less or more nested panels.

Laf
  • 7,965
  • 4
  • 37
  • 52
  • Confused...when should we use setcontentpane and getContentPane()? Do they refer to a field in JFrame or something? – Lews Therin Oct 13 '11 at 20:27
  • `setContentPane()` should rarely be used, at least I have never had to use it. `getContentPane()` should be used everytime you want to add a GUI widget to a `JFrame`. To what exactly they refer is an implementation detail that should not impact your work. The important thing to remember is that calling `getContentPane()` will get you the `Container` that is used to display your UI. – Laf Oct 13 '11 at 20:46
  • I was looking at the API. Apparently setContentPane returns a reference to the same object that getContentPane refers to, I think so anyways. I don't understand something else though...I don't really like creating threads in such a short while, so can I ask here? Why do I have to call setJMenuBar to display a frame? No website seems to answer that. And what does it mean that a JFrame has many layers. That's confusing of all. – Lews Therin Oct 13 '11 at 22:15
  • 1
    @LewsTherin javadoc for `setContentPane()` mentions that the return type is `void`, so no reference to the content pane is returned ([link](http://download.oracle.com/javase/6/docs/api/javax/swing/JFrame.html#setContentPane(java.awt.Container))). And you have to call the `setMenuBar()` method because `JFrame` handles the menu bar display so that you do not have to worry about it. The Java Tutorials contain a good article on top level containers, such as `JFrame` ([link](http://download.oracle.com/javase/tutorial/uiswing/components/toplevel.html)). – Laf Oct 14 '11 at 14:03
  • I meant getContentPane() and setContentPane() I wrote it in the reverse :( Good catch :P Thanks for the links. – Lews Therin Oct 15 '11 at 15:16
0

You need to see this API doc for JComponent.

If you look at the inheritance hierarchy, you will see that the JComponent extends Component so a JComponent is a Component.

Also under Direct Known Subclasses, you can see the list of all the classes that extend the JComponent including JMenuBar and JPanel.

So, JMenuBar and JPanel are two more specialized versions of JComponent (or Container).

Bhesh Gurung
  • 50,430
  • 22
  • 93
  • 142