Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / GUI / September 2006

Tip: Looking for answers? Try searching our database.

GridBagLayout problems

Thread view: 
Ian Wilson - 21 Sep 2006 16:02 GMT
Can anyone suggest fixes for two problems, in the example app below,
when I resize the window vertically smaller:

1) The textfields suddenly resize to minimal width.

2) The table doesn't get scrollbars in its scrollpane

I guess I need a decent book on Swing! Anyone know if Robinson &
Vorobiev's "Swing" is being rewritten for 1.5 (or 1.6)? I'm reluctant to
buy a 1.4 book.

---------------------8<----------------------
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.border.TitledBorder;

public class GridBagProblem extends JPanel {

    GridBagProblem() {
        setLayout(new GridBagLayout());
        add(createVeryTallPanel("foo"), new GridBagConstraints(
                0,0,                            // x, y
                1,3,                            // width, height
                0.0,0.0,                        // weightx weighty
                GridBagConstraints.FIRST_LINE_START, // anchor
                GridBagConstraints.NONE,        // fill
                new Insets(0,0,0,0),            // insets: t l b r
                0,0                             // ipadx, ipady
                ));
        add(createSmallPanel("bar"), new GridBagConstraints(
                1,0,                            // x, y
                1,1,                            // width, height
                0.0,0.0,                        // weightx weighty
                GridBagConstraints.FIRST_LINE_START,  // anchor
                GridBagConstraints.NONE,        // fill
                new Insets(0,0,0,0),            // insets: t l b r
                0,0                             // ipadx, ipady
                ));
        add(createSmallPanel("baz"), new GridBagConstraints(
                1,1,                            // x, y
                1,1,                            // width, height
                0.0,0.0,                        // weightx weighty
                GridBagConstraints.FIRST_LINE_START,  // anchor
                GridBagConstraints.NONE,        // fill
                new Insets(0,0,0,0),            // insets: t l b r
                0,0                             // ipadx, ipady
                ));
        add(createTallPanel("qux"), new GridBagConstraints(
                2,0,                            // x, y
                1,2,                            // width, height
                0.0,0.0,                        // weightx weighty
                GridBagConstraints.FIRST_LINE_START, // anchor
                GridBagConstraints.NONE,        // fill
                new Insets(0,0,0,0),            // insets: t l b r
                0,0                             // ipadx, ipady
                ));
        add(createWidePanel("quxqux"), new GridBagConstraints(
                1,2,                            // x, y
                2,1,                            // width, height
                0.0,0.0,                        // weightx weighty
                GridBagConstraints.FIRST_LINE_START, // anchor
                GridBagConstraints.NONE,        // fill
                new Insets(0,0,0,0),            // insets: t l b r
                0,0                             // ipadx, ipady
                ));
        add(createTable("quxquxqux"), new GridBagConstraints(
                0,3,                            // x, y
                3,1,                            // width, height
                0.9,0.9,                        // weightx weighty
                GridBagConstraints.FIRST_LINE_START, // anchor
                GridBagConstraints.BOTH,        // fill
                new Insets(0,0,0,0),            // insets: t l b r
                0,0                             // ipadx, ipady
                ));
    }

    private static JPanel createSmallPanel(String title) {
        JPanel panel = new JPanel();
        panel.setBorder(new TitledBorder(title));
        panel.setLayout(new GridBagLayout());
        addPair(panel, 0,0, "name", 10);
        addPair(panel, 0,1, "street", 20);
        addPair(panel, 0,2, "city", 20);
        return panel;
    }

    private static JPanel createTallPanel(String title) {
        JPanel panel = new JPanel();
        panel.setBorder(new TitledBorder(title));
        panel.setLayout(new GridBagLayout());
        addPair(panel, 0,0, "name", 10);
        addPair(panel, 0,1, "street", 20);
        addPair(panel, 0,2, "city", 20);
        addPair(panel, 0,3, "postal code", 10);
        addPair(panel, 0,4, "country", 8);
        return panel;
    }

    private static JPanel createVeryTallPanel(String title) {
        JPanel panel = new JPanel();
        panel.setBorder(new TitledBorder(title));
        panel.setLayout(new GridBagLayout());
        addPair(panel, 0,0, "name", 10);
        addPair(panel, 0,1, "street", 20);
        addPair(panel, 0,2, "city", 20);
        addPair(panel, 0,3, "postal code", 10);
        addPair(panel, 0,4, "country", 8);
        addPair(panel, 0,5, "this", 8);
        addPair(panel, 0,6, "that", 8);
        addPair(panel, 0,7, "theother", 8);
        return panel;
    }

    private static JPanel createWidePanel(String title) {
        JPanel panel = new JPanel();
        panel.setBorder(new TitledBorder(title));
        panel.setLayout(new GridBagLayout());
        addPair(panel, 0,0, "up", 10);
        addPair(panel, 0,1, "down", 20);
        addPair(panel, 2,0, "in", 20);
        addPair(panel, 2,1, "out", 10);
        return panel;
    }

    private static JPanel createTable(String title) {
        JPanel panel = new JPanel();
        panel.setBorder(new TitledBorder(title));
        String[] headings = { "eggs", "spam" };
        String[][] data = {
                {"12", "12"}, {"56", "56" }, {"56", "56" },
                {"12", "12"}, {"56", "56" }, {"56", "56" },
                {"12", "12"}, {"56", "56" }, {"56", "56" },
                {"12", "12"}, {"56", "56" }, {"56", "56" },
                {"12", "12"}, {"56", "56" }, {"56", "56" },
                {"12", "12"}, {"56", "56" }, {"56", "56" },
                {"12", "12"}, {"56", "56" }, {"56", "56" },
                {"12", "12"}, {"56", "56" }, {"56", "56" },
                {"12", "12"}, {"56", "56" }, {"56", "56" },
                {"12", "12"}, {"56", "56" }, {"56", "56" },
                {"12", "12"}, {"56", "56" }, {"56", "56" },
                {"12", "12"}, {"56", "56" }, {"56", "56" },
                {"12", "12"}, {"56", "56" }, {"56", "56" },
                {"12", "12"}, {"56", "56" }, {"56", "56" }
                };
        JTable table = new JTable(data, headings);
        JScrollPane scrollPane = new JScrollPane(table);
        panel.add(scrollPane);
        return panel;
    }

    private static void addPair(JPanel panel, int x, int y,
            String labelText, int size) {
        panel.add (new JLabel(labelText), new GridBagConstraints(x,y,
                1,1,                            // width, height
                0.1,0.1,                        // weightx weighty
                GridBagConstraints.LINE_START,  // anchor
                GridBagConstraints.NONE,        // fill
                new Insets(2,0,3,10),           // insets t l b r
                0,0                             // ipadx, ipady
                ));
        panel.add (new JTextField(size), new GridBagConstraints(x+1,y,
                1,1,                            // width, height
                0.9,0.9,                        // weightx weighty
                GridBagConstraints.LINE_START,  // anchor
                GridBagConstraints.NONE,        // fill
                new Insets(2,10,3,10),          // insets t l b r
                0,0                             // ipadx, ipady
                ));
    }

    private static void createAndShowGUI() {
        try {
            UIManager.setLookAndFeel(
                    UIManager.getSystemLookAndFeelClassName());
        } catch (Exception e) {
            System.out.println("Unable to set L&F");
        }
        JFrame.setDefaultLookAndFeelDecorated(true);
        JFrame frame = new JFrame("GridBagProblem");
        frame.setContentPane(new GridBagProblem());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }

}
---------------------8<----------------------
A. Bolmarcich - 21 Sep 2006 17:07 GMT
> Can anyone suggest fixes for two problems, in the example app below,
> when I resize the window vertically smaller:
>
> 1) The textfields suddenly resize to minimal width.

That is how GridBayLayout works.  If the container is not large enough
to set the components to at least their preferred sizes, GridBagLayout
uses the minimum size of each component.

Because the textfields and the containers that they are in use
GridBagLayout, change the GridBagLayout constraints to allow the
textfields to use the extra space in the container.  That is, use
non-zero weightx value and a fill value that gives at least the extra
horizontal space to the textfields.

> 2) The table doesn't get scrollbars in its scrollpane

The table is in a panel that uses the default layout manager of
FlowLayout.  That layout manager always sets each component in it to
the component's preferred size.  If the enclosing container is not
large enough to show each component at that size, the component is
clipped.

Use a different layout manager for the panel that the table is in.
Try BorderLayout and leave the rest of the code as-is.  You may not
like the fact that the table will fill the available horizontal
space, but that can be changed by using a different layout manager
and changing the some of the code to use appropriate layout constaints
with the table.
[snip]
Ian Wilson - 21 Sep 2006 17:55 GMT
>> Can anyone suggest fixes for two problems, in the example app
>> below, when I resize the window vertically smaller:
[quoted text clipped - 10 lines]
> non-zero weightx value and a fill value that gives at least the extra
>  horizontal space to the textfields.

I set min size to preferred size and that works reasonably well.

>> 2) The table doesn't get scrollbars in its scrollpane
>
> The table is in a panel that uses the default layout manager of
> FlowLayout.  

Ah yes, I'd overlooked that.

> That layout manager always sets each component in it to
> the component's preferred size.  If the enclosing container is not
> large enough to show each component at that size, the component is
> clipped.

That is useful information. In Sun's documentation I can only find this
statement " A flow layout lets each component assume its natural
(preferred) size." Is there somewhere else I can get more information
about the behaviour of various layout managers when containers are resized?

> Use a different layout manager for the panel that the table is in.
> Try BorderLayout and leave the rest of the code as-is.  You may not
> like the fact that the table will fill the available horizontal
> space,

I tried BorderLayout and that looks OK to me.

> but that can be changed by using a different layout manager
> and changing the some of the code to use appropriate layout
> constaints with the table. [snip]

Which ones? I've tried this example with nested BoxLayouts. Further
hints or suggestions for further reading would be appreciated.

Many thanks.
Knute Johnson - 21 Sep 2006 18:38 GMT
> That is useful information. In Sun's documentation I can only find this
> statement " A flow layout lets each component assume its natural
> (preferred) size." Is there somewhere else I can get more information
> about the behaviour of various layout managers when containers are resized?

I don't know of any.  If you find anything let us all know.

One other note on your code.  You don't need new GridBagConstraints for
every component.  One is sufficient, just change the elements for each
component as necessary.

Signature

Knute Johnson
email s/nospam/knute/

Ian Wilson - 22 Sep 2006 11:14 GMT
> One other note on your code.  You don't need new GridBagConstraints for
> every component.  One is sufficient, just change the elements for each
> component as necessary.

This came up in this newsgroup some months ago. There seemed to be two
schools of thought:
a) You can lose track of incrementally amended GridBagConstraints.
b) Using the full constructor leads to code bloat. Etc.

I've tried both ways, I've found that a) is true when I insert new
components or re-order them.

What I'm doing at the moment is using an extension of GridBagConstraints
with terse constructors.

e.g.
  add(fooLabel, new GBC(0,0,GBC.LABEL));
  add(fooField, new GBC(1,0,GBC.FIELD));
  add(barLabel, new GBC(0,1,GBC.LABEL));
  add(barField, new GBC(1,1,GBC.FIELD));

Where I use the third parameter (GBC.LABEL or GBC.FIELD) in the
constructor to decide suitable values for weights, anchor, fill and insets.

Obviously there is a trade off in ease of future maintenance for people
unfamiliar with this new GBC class.

In my earlier posting I "unwrapped" GBC to conventional use of
GridBagConstraints in order to avoid confusing the core issue.

It seems that whenever I think I've got my head round GridBagLayout,
something strange happens and I realise I don't understand it enough.
At these times I wonder whether I really should make a serious effort at
looking at JGoodies FormLayout or inventing my own Layout Manager (seems
very daunting though I've seen articles saying it is not hard).

Thanks for the help and the comments, it doesn't hurt me to review my
choices every now and then.
Knute Johnson - 22 Sep 2006 17:06 GMT
> It seems that whenever I think I've got my head round GridBagLayout,
> something strange happens and I realise I don't understand it enough.
[quoted text clipped - 4 lines]
> Thanks for the help and the comments, it doesn't hurt me to review my
> choices every now and then.

Ian:

GridBagLayout is the most powerful and the most difficult to master.  I
discover new things about it every time I try to do a complicated layout.

Signature

Knute Johnson
email s/nospam/knute/

Karsten Lentzsch - 22 Sep 2006 19:16 GMT
> GridBagLayout is the most powerful and the most difficult to master.  I
> discover new things about it every time I try to do a complicated layout.

GridBagLayout is one of the weaker layout managers;
it lacks even essential features for everyday design.
See the "Layout Essentials" at www.jgoodies.com/articles/

You can find more details in "Layout and Panel Building"
or in the "JGoodies Forms" whitepaper. At the end of
the whitepaper I compare a bunch of popular layout managers.
This comparison lacks the explicit table builder and MIGLayout.
However, the whole text explains why GBL is a weak layout manager
besides being difficult to master.

-Karsten
Aki Laukkanen - 25 Sep 2006 16:36 GMT
>> GridBagLayout is the most powerful and the most difficult to master.  
>> I discover new things about it every time I try to do a complicated
[quoted text clipped - 3 lines]
> it lacks even essential features for everyday design.
> See the "Layout Essentials" at www.jgoodies.com/articles/

Or, in other words, GridBagLayout should really be named
YouDoNotWantThisLayout.

Signature

-Aki Laukkanen

Thomas Weidenfeller - 26 Sep 2006 08:05 GMT
> Or, in other words, GridBagLayout should really be named
> YouDoNotWantThisLayout.

I am much more a fan of a realistic view. It depends on where you come
from. If you have firsthand experience with anomalies like the CDE/Motif
 geometry management, or then absence of any kind of geometry
management, then GBL is a step forward. You can build GUIs with GBL, and
if you know what you are doing, you can build well-behaving GUIs with
it. Which less frustration than one had with previous, legacy technology
on some platforms.

It also has the bonus of being part of the Java standard edition. So one
doesn't need to add yet another product dependency to an application.

/Thomas
Signature

The comp.lang.java.gui FAQ:
http://gd.tuwien.ac.at/faqs/faqs-hierarchy/comp/comp.lang.java.gui/
ftp://ftp.cs.uu.nl/pub/NEWS.ANSWERS/computer-lang/java/gui/faq

alyawn - 28 Sep 2006 06:50 GMT
I hear complaints about GridBagLayout all the time. I personally think
it saves a lot of time once you learn the rules. I always fall back on
the GBL if I find I'm nesting to many panels and things are getting
bloated. Here are the layouts I use:

 BorderLayout - good for full frame layout.
 GridBagLayout - good for almost everything else.
 <Custom>Layout - When the above don't work.

Generally speaking, if I can't get my panel laid out with combinations
of border & GBL, then I usually write my own. It really is pretty easy
to write your own LayoutManager. I have a stack layout that works well
and is less than 40 lines of code. My 2 cents.

- Alan
- http://everydaycoder.com
Karsten Lentzsch - 28 Sep 2006 09:31 GMT
> I hear complaints about GridBagLayout all the time. [...]

GBL can't ensure that two columns have the same width,
or a bunch of rows have the same height. It's difficult
to ensure symmetry, you can hardly build stable layouts,
it has no means for minimum widths, and in general
it doesn't scale with the font and resolution. See:
http://www.jgoodies.com/articles/layout-essentials.pdf

> Generally speaking, if I can't get my panel laid out with combinations
> of border & GBL, then I usually write my own. It really is pretty easy
> to write your own LayoutManager. I have a stack layout that works well
> and is less than 40 lines of code. My 2 cents.

I agree that it's easy to build a custom layout manager,
much easier than most developers I met expect. But it's
difficult to build a custom layout manager quickly that
offers the features the GBL lacks, for example resolution
independence.

Therefore I typically favor to use a powerful general purpose
layout manager over writing a weaker custom layout manager.
Good general purpose layout managers are ExplicitLayout plus
Explicit Table Builder, JGoodies FormLayout, MIGLayout.

-Karsten
alyawn - 28 Sep 2006 20:56 GMT
Well, whatever works for you. I looked at some of those layouts a while
back. I also had to repair a few broken FormLayouts in the past. Maybe
that left a bit of a sour taste in my mouth. Cheers.

-Alan
-http://everydaycoder.com
Karsten Lentzsch - 29 Sep 2006 08:34 GMT
Alan wrote:

> Well, whatever works for you. I looked at some of those layouts a while
> back. I also had to repair a few broken FormLayouts in the past. Maybe
> that left a bit of a sour taste in my mouth. Cheers.

I've fixed broken GridBagLayouts, TableLayout, HIGLayouts,
FormLayout - but it isn't related to the capabilities of
these layout managers, and it is not related to the costs
of doing a layout.

HIGLayout, ExplicitLayout, FormLayout, MIGLayout
can build true supersets of layouts compared to GBL,
so the question is whether the difference is significant,
and how much it costs to build a better layout.

I've seen that most developers ignore resolution independence
with the GBL, with custom layout managers and with custom
preferred and minimum sizes. This leads to potentially poor layout.
And I've found that many developers don't expect that a layout
breaks and does *not* retain proportions and pseudo 3D effects,
if the screen resolution changes. This becomes more and more
important with todays popular LCDs with 80dpi up to 144dpi.

How do you handle resolution independence in GBL or
your custom layouts?
How do you handle font size differences between English
letters and Chinese glyphs?

-Karsten
Thomas Hawtin - 23 Sep 2006 17:44 GMT
>   add(fooLabel, new GBC(0,0,GBC.LABEL));
>   add(fooField, new GBC(1,0,GBC.FIELD));
>   add(barLabel, new GBC(0,1,GBC.LABEL));
>   add(barField, new GBC(1,1,GBC.FIELD));

Why not write a class that can be used something like:

    return new GBC(panel)
        .addLabel(fooLabel, 0, 0)
        .addField(fooField, 1, 0)
        .addLabel(barLabel, 0, 1)
        .addField(barField, 1, 1)
        .getTarget();

Tom Hawtin
Signature

Unemployed English Java programmer
http://jroller.com/page/tackline/

A. Bolmarcich - 21 Sep 2006 19:07 GMT
[snip]
> That is useful information. In Sun's documentation I can only find this
> statement " A flow layout lets each component assume its natural
> (preferred) size." Is there somewhere else I can get more information
> about the behaviour of various layout managers when containers are resized?

I don't know of any written material that adequately explains the
behaviour of various layout managers when containers are resized.
Read Sun's documentation and when programs do not behave as expected
reread Sun's documentation and read the LayoutManager source.

Component sizes can change dramatically when a layout manager shifts
from using the preferred size of the components in it to using the
minimum size.
[snip]

>> Use a different layout manager for the panel that the table is in.
>> Try BorderLayout and leave the rest of the code as-is.  You may not
[quoted text clipped - 9 lines]
> Which ones? I've tried this example with nested BoxLayouts. Further
> hints or suggestions for further reading would be appreciated.

I can't think of a way to do it with only standard LayoutManagers.  The
tricky part is to have the scrollPane with the table set to its
preferred width even when GridBagLayout uses the minimum sizes of the
components.  You could

- write a scroll pane class with an overridden getMinimumSize method
 that returns the preferred width and minimum height  

- add that scroll pane to a container that uses GridBagLayout with
 a non-zero weighty constraint and a VERTICAL fill constraint
danharrisandrews@gmail.com - 22 Sep 2006 17:49 GMT
> I guess I need a decent book on Swing! Anyone know if Robinson &
> Vorobiev's "Swing" is being rewritten for 1.5 (or 1.6)? I'm reluctant to
> buy a 1.4 book.

Hi Ian,

In 1999 I bought a book by Simon Roberts, Philip Heller, and Michael
Ernest
(http://www.amazon.com/Complete-Java-Certification-Study-Guide/dp/0782124631).
Over the years I've thrown out a lot of books, but this one is still on
the shelf. I frequently lend it out to colleagues with a bookmark in
Chapter 9 (Layout Managers). It is by far the best 30 pages on layout
managers that I have seen and although written for 1.2 it is still
relevant today.

Cheers,

Dan Andrews
- - - - - - - - - - - - - - - - - - - - - - - - -
Ansir Development Limited http://www.ansir.ca
- - - - - - - - - - - - - - - - - - - - - - - - -


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.