Two Laptop Bag*
The moose likes Swing / AWT / SWT and the fly likes Please help me work on my Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Murach's Java Servlets and JSP this week in the Servlets forum!
JavaRanch » Java Forums » Java » Swing / AWT / SWT
Bookmark "Please help me work on my "Swing"" Watch "Please help me work on my "Swing"" New topic
Author

Please help me work on my "Swing"

Denise Advincula
Ranch Hand

Joined: Jan 01, 2007
Posts: 160
Hello, I am currently reviewing for SCJP 6. I started studying Head First to become strongly knowledgeable on the basics first.

Unlike other chapters, I read the GUI and Swing chapters just briefly because I have been using them often so I thought it's quite easy.
However, when I was trying the Swing tutorial from Sun to have a better understanding or
just find answers to my own version of "There are no dumb questions" (part of the Head First Book), turns out that I wasn't really that familiar with the Java's Swing at all. So here are my questions:

1. Since it is better to use LayoutManagers than manually laying out the GUI yourself, we therefore have to abide by the LayoutManager's policies.
But still I find some limitations to the LayoutManagers. For example, how am I gonna display this (I'm sorry, please just imagine that "Big Area 1" and "Bigger Area 2" are boxes representing the parts of the GUI):

~~ Big Area 1 ~~ ~~ Bigger Area 2 ~~
~~ Big Area 1 ~~ ~~ Bigger Area 2 ~~
Button1 Button2 ~~ Bigger Area 2 ~~
Button3 Button4 ~~ Bigger Area 2 ~~

Based from my understanding, FlowLayout is from left to right ("wrapped"). BoxLayout is from top to bottom.

I'm thinking if making 3 panels would make it possible: Panel 1 for Big Area 1; Panel 2 for Bigger Area 2; and Panel 3 for the 4 buttons below Big Area 1. However I still can't figure out how to put these 3 panels together (please refer to question b).

a. Is it possible to add multiple panels in one JFrame?
b. If it is, how can we put it in such a way that it will just be the whole area of the JFrame? I mean, without setting the layout manually and without putting something else in the NORTH, EAST, SOUTH, WEST sides of the JFrame's BorderLayout? Just all the 3 panels in the CENTER Area (and no spaces in the N, E, S, W areas).


2. I think I missed something about the pack() method. What is it all about? The screen looks different if there is a pack method and if there is none. And I assumed that it is always required when displaying a Frame because if I delete that .pack() part, I could not see the whole frame at all.

testFrame.getContentPane().add(this);
testFrame.pack();
testFrame.setVisible(true);

I'm not really sure what is it for. The Java 6 API has this answer:


public void pack()
Causes this Window to be sized to fit the preferred size and layouts of its subcomponents.
If the window and/or its owner are not yet displayable, both are made displayable before calculating the preferred size.
The Window will be validated after the preferredSize is calculated.


But I'm still lost.


3. I get an exception when I use JFrame.add(). And the message says that I should use the getContentPane().add() instead.

JFrame frame = new JFrame();
JPanel panel = new JPanel();
panel.add(label);
panel.add(textField);

//frame.add(panel);
frame.getContentPane().add(panel);

a. Why should I use JFrame.getContentPane.add() instead of JFrame.add()?
b. What Content Pane will be retrieved on the getContentPane? Is there a "default" ContentPane for every JFrame that is retrieved upon invoking the getContentPane()?
c. What is it's difference then with the getRootPane()? Why not just use JFrame.getRootPane.add() instead to get the "default" ContentPane.

Those are my questions so far.

Thank you very much in advance!


SCJP/OCPJP 6 | SCWCD/OCPJWCD 5 | OCMJEA in progress...
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 37897
    
  22
Welcome to JavaRanch.

I shall move you because your post would be more appropriate on the Swing forum.
Ulf Dittmer
Marshal

Joined: Mar 22, 2005
Posts: 41046
    
  43
I'll start by talking about layouts. It's been ages since I last used BorderLayout or FlowLayout; they just don't cut it for any sizeable GUI (meaning one that has many elements). A combination of GridLayout and BoxLayout usually does the trick.

In your situation you'd use a GridLayout with one row and two columns. The left column would contain a JPanel that in turn contains two more JPanels in a BoxLayout. The right column would contain just a JPanel.

So, yes, you can have multiple JPanels - the components being layed out in a Layout can be concrete elements (like buttons and text fields) but also abstract elements like panels. It's not uncommon for this hierarchy to be several layers deep. (There is another layout that's supposed to handle complex GUIs -GridBagLayout- but I'd advise to avoid it like the plague.)


Ping & DNS - my free Android networking tools app
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 37897
    
  22
Layout Managers are awkward. If you can get your hands on a copy of C S Horstmann and G Cornell, Core Java 2 published by Sun Microsystems Press, read it. There is discusion of layouts (I think in the 1st volume; in my copy [7th edition] it starts on page 424) and a class called GBC.
You would do better to use layouts like Grid or GridBag than Flow.

You can use GridLayout to get your Big Areas and Small areas to fill your Component, then put more Components on top of them.
Yes, you can add multiple panels the way you suggest. You can use Grid in which case they will all be the same size.
You can use GridBag; there is a tutorial here. You can find a bit about the GBC class here (no more jokes) but it is a very brief description.

What you do with GBC is something like this:


You will have to go through the GBC class to check whether I have got the method names spelt correctly, and what the different parameters mean. Because of the "chaining" mentioned in the website you can stick as many method calls together as you like, and I don't think they have to go in any particular order.

I can never seem to get pack() to work; I usually call setBounds() on the top-level container (usually a JFrame). I think for pack() to work you have to set a preferred size on all the included Components (setPreferredSize(40, 20)) first. Then call pack() after adding everything.

I think the bit about validate and visible means you can get away without calling validate() and setVisible(true) if you have called pack().

If you get an Exception when using the add() method, please check:
  • Which version of Java you are using. There were additional add() methods added in Java5, so they won't work on Java1.4.2.
  • Whether the arguments you are passing match the add() method; if you go through the API for Component and JComponent you will find add() has been heavily overloaded.
  • As far as I know, the add() method was overloaded in Java5 so if you say add() rather than getContentPane().add() it defaults to adding to the content pane. There are more details about how a Frame works in the Java Tutorials: look for "top level containers" and "how to make frames." But don't add anything to the root pane.

    Those are my questions so far.
    That should keep you busy all day.
    [ May 23, 2008: Message edited by: Campbell Ritchie ]
    Denise Advincula
    Ranch Hand

    Joined: Jan 01, 2007
    Posts: 160
    Thank you!

    Oh I heard GridLayout before. Although I think it's not included in the Head First LayoutManager discussion (or maybe I just skipped that part, I have taken the GUI and Swing chapters for granted. )

    So now my Question #1 is solved... Now I will try using the GridLayout.
    Rob Spoor
    Sheriff

    Joined: Oct 27, 2005
    Posts: 19649
        
      18

    Originally posted by Joane Denise Saulon:
    1. Since it is better to use LayoutManagers than manually laying out the GUI yourself, we therefore have to abide by the LayoutManager's policies.
    But still I find some limitations to the LayoutManagers. For example, how am I gonna display this (I'm sorry, please just imagine that "Big Area 1" and "Bigger Area 2" are boxes representing the parts of the GUI):

    ~~ Big Area 1 ~~ ~~ Bigger Area 2 ~~
    ~~ Big Area 1 ~~ ~~ Bigger Area 2 ~~
    Button1 Button2 ~~ Bigger Area 2 ~~
    Button3 Button4 ~~ Bigger Area 2 ~~

    Based from my understanding, FlowLayout is from left to right ("wrapped"). BoxLayout is from top to bottom.

    I'm thinking if making 3 panels would make it possible: Panel 1 for Big Area 1; Panel 2 for Bigger Area 2; and Panel 3 for the 4 buttons below Big Area 1. However I still can't figure out how to put these 3 panels together (please refer to question b).

    You could check GroupLayout, or if you want to torture yourself GridBagLayout. Alternatively, the 3rd party FormLayout from jgoodies.com could also be an option.

    a. Is it possible to add multiple panels in one JFrame?

    Not directly. You'll have to add components to the ContentPane. Since Java 5.0, calling a JFrame's add method will redirect it to the ContentPane, but it's better to just use the ContentPane directly.

    Now the ContentPane is a Container, so you can give it a different LayoutManager (defaults to BorderLayout) and add components to it without a problem. That includes JPanels.

    b. If it is, how can we put it in such a way that it will just be the whole area of the JFrame? I mean, without setting the layout manually and without putting something else in the NORTH, EAST, SOUTH, WEST sides of the JFrame's BorderLayout? Just all the 3 panels in the CENTER Area (and no spaces in the N, E, S, W areas).

    If you override the LayoutManager for the content pane, you can just make that LayoutManager place your panels. There are no more concepts of NORTH etc.
    The alternative is creating a Container (JPanel) with the contents you need, and add that to the ContentPane with BorderLayout.CENTER (or nothing to default to the center).

    2. I think I missed something about the pack() method. What is it all about? The screen looks different if there is a pack method and if there is none. And I assumed that it is always required when displaying a Frame because if I delete that .pack() part, I could not see the whole frame at all.

    Without a call to pack(), the size of your JFrame will be 0x0 (excluding the title bar). pack() does two very important things:
    1) set the size of the Window (of which JFrame is an indirect subclass) to its preferred size
    2) make sure all components are layed out properly according to the LayoutManager.

    Please note that step 2 is also executed when you resize the JFrame. This is because a resize event will also cause the Container to be (re)validated.

    [/QB]3. I get an exception when I use JFrame.add(). And the message says that I should use the getContentPane().add() instead.

    a. Why should I use JFrame.getContentPane.add() instead of JFrame.add()?
    b. What Content Pane will be retrieved on the getContentPane? Is there a "default" ContentPane for every JFrame that is retrieved upon invoking the getContentPane()?
    c. What is it's difference then with the getRootPane()? Why not just use JFrame.getRootPane.add() instead to get the "default" ContentPane.[/QB]

    a) Check the Using Top-Level Containers link in the JFrame API. This should be fixed in Java 5.0 though, to redirect adding of components to the ContentPane. Are you still using Java 1.4?

    b) The JFrame's ContentPane is actually its JRootPane's ContentPane. This is a JPanel by default, but never assume so. All you can safely assume without instanceof checks is that it is a Container.

    c) Because a RootPane contains more than just the ContentPane. See the link about using Top-Level Containers I showed you.


    SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6
    How To Ask Questions How To Answer Questions
    Denise Advincula
    Ranch Hand

    Joined: Jan 01, 2007
    Posts: 160
    Originally posted by Campbell Ritchie:
    [QB]

    If you get an Exception when using the add() method, please check:
  • Which version of Java you are using. There were additional add() methods added in Java5, so they won't work on Java1.4.2.
  • Whether the arguments you are passing match the add() method; if you go through the API for Component and JComponent you will find add() has been heavily overloaded.
  • As far as I know, the add() method was overloaded in Java5 so if you say add() rather than getContentPane().add() it defaults to adding to the content pane. There are more details about how a Frame works in the Java Tutorials: look for "top level containers" and "how to make frames." But don't add anything to the root pane.
    [QB]

    Maybe that's why. I am currently not at home so the Java Version I'm using (temporarily) is 1.3. I'm coding in 1.3 and my API reference is Java 6. So maybe it got all screwed up. Thank you very much for pointing that out.

    I have a strong feeling I'll be a regular here. :roll:
    [ May 23, 2008: Message edited by: Joane Denise Saulon ]
    Campbell Ritchie
    Sheriff

    Joined: Oct 13, 2005
    Posts: 37897
        
      22
    Grid is easy to use. Go and read its details in the Java Tutorial. You simply set up so many columns and so many rows and it adds in this sort of orderYou don't even have to tell it where to put the components; just add them in the correct order. The only problem is that all the added Components will be the same size.
    Denise Advincula
    Ranch Hand

    Joined: Jan 01, 2007
    Posts: 160
    I think I got the answers now.

    Thank you guys for all these replies!

    Now I can go on with my life.
    Fernando Hood
    Greenhorn

    Joined: May 23, 2008
    Posts: 20
    [ UD: Fernando, please do not post unrelated questions to existing topics. That's called "hijacking", and is frowned upon. You can start a new topic instead. ]
    [ May 24, 2008: Message edited by: Ulf Dittmer ]
     
    It is sorta covered in the JavaRanch Style Guide.
     
    subject: Please help me work on my "Swing"
     
    Similar Threads
    how to resize JPanel size to JFrame size
    help on reading textfield on 1 class from another class and using it to create a file
    TextArea components
    BorderLayout & FlowLayout
    need help with JPanel, liseners, and referencing vectors