Java Forum / GUI / September 2006
GridBagLayout problems
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 MagazinesGet 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 ...
|
|
|