GridBagLayout: how to keep invisible components from collapsing
Asked Answered
L

4

7

When making individual components of a layout managed by GridBagLayout invisible, the arrangement of the remaining components in the layout keeps changing. The GridBagLayout appears to "collapse" cells with invisible components, causing other components to change positions. This is a highly annoying behaviour, and I've been looking for a way to keep it from doing that.

One method I've tried is by adding a spacer to the same cell, with a fixed size equal to the preferred size of the component that may be hidden, but if that preferred size ever were to change, it would be a lot of trouble to keep the spacer in sync. Is there a better way?

Actually, it wouldn't be so bad if the GridBagLayout would really completely disregard cells with invisible components, but it still takes the cell's insets into account, so if you have a layout of input fields and used the insets to neatly arrange them with regular gaps in between, then hiding one component in the middle removes it from the layout but leaves the gap, which usually means the surrounding components flow together, but with an ugly double-wide gap between them...

Lipcombe answered 21/1, 2010 at 10:41 Comment(2)
Ah good old Gridbaglayout with it's constraints, how i don't miss you (but i will follow this thread anyway ;)Unseal
I know the GridBagLayout for years, and still sometimes I can spend great amounts of time looking for what causes the collapse behavior. Try to add a big component, for example a label with much text. Then resize your GridBagLayout'ed container to a width smaller than the label's preferred size... This is so weirdSavaii
F
8

What about using JPanel (or Box) as placeholder?
Put a JPanel into each cell and add the components to the panels. If you turn the component invisible, the panel should still be there...

Fanfani answered 21/1, 2010 at 13:33 Comment(2)
Not sure why this had no upvotes, it was exactly what I needed. Just one thing though: you'll want to do containerPanel.setLayout(new GridLayout(1, 1)); or something similar, otherwise the default BorderLayout will add in some spacing and put all your components out by a few pixels.Awn
Tested this and this is a great workaround for the horrible collapse behavior.Savaii
S
1

One possibility would be to use nested panels with a CardLayout to hide components, instead of setting them to invisible. A CardLayout causes the panel to always have the size of the biggest "card".

Alternatively, you could try using the new (as of Java 6) GroupLayout instead of the GridBagLayout - it's IMO much easier to use and almost as powerful.

Selfexecuting answered 21/1, 2010 at 10:47 Comment(1)
I haven't had the chance to try GroupLayout - it looks interesting, but unfortunatley, Java 1.5 compatibility is enforced in the project (I mean, how can you expect the users to have to update their environments to a state of technology that's LESS THAN 4 YEARS old?! </sarcasm>)Lipcombe
S
1

Use MigLayout

to bring back the joy into layouting ^^.

I also used GridBagLayout in the past, and it's awful. Lots of boilerplate code, and if you add one little component, the layout is most probably screwed.

Another alternative is using Boxlayout

Soleure answered 21/1, 2010 at 11:30 Comment(1)
Third-party code is not an option, unfortunately, for various reasons, and BoxLayout does not seem to be able to create the (rather complex) required arrangements of UI elements...Lipcombe
G
0

IIRC, what I have done in the past is place the component in a container (or used a separate component) that mimics the sizes of the original component, but not whether it the hidden state. PUt this in a method or a facade to grid bag, and your layout code can remain nice and clean.

Gerhan answered 21/1, 2010 at 13:52 Comment(1)
That's the method I've been using (creating struts via the methods offered by "Box") but it's clumsy and error-prone.Lipcombe

© 2022 - 2024 — McMap. All rights reserved.