Question

I am dinamically generating a layout which requires to use relative sizes, the only way I found to do it without using an external Java layout library is GridBagLayout's weightx and weighty.

At this point it has been working exactly as I need with one small exception. When I have one column containing two JPanels with a space distribution of 66.6% and 33.3% respectively and then another column with 3 JPanels using 33.3% of the space each one of them, the 33.3% of the first column is not the same as the 33.3% of the second. I need them to be perfectly aligned.

Unfortunately this is my first post and I am not able to post any pictures, I hope I won't get in trouble for doing the following:

i.stack.imgur.com/avsuA.png

I think I know what the problem is, inside of each JPanel I have one JLabel and since weightx and weighty's definition is "Weights are used to determine how to distribute space among columns (weightx) and among rows (weighty)" I guess the difference between the two 33.3%s is the fact that the second column contains one extra JLabel.

In this thread StanislavL says that the "container asks children for their preferred size", so, I am wondering if the solution is to override JLabel's getPreferredSize method. I am not sure how "dirty" would be to do that, I would appreciate a lot your suggestions to solve this problem.

Thanks in advance!

Diego

Was it helpful?

Solution

I am wondering if the solution is to override JLabel's getPreferredSize method.

try it, except I would override the panels getPreferredSize() method, since it the the panels size that will adjust as the frame grows/shrinks.

I am not sure how "dirty" would be to do that

overriding is preferred to using the setPreferredSize() method.

the only way I found to do it without using an external Java layout library

Why not use an external library if it make the code easier to use and understand? Relative Layout was specifically designed for this purpose so you don't have to play around with sizes.

OTHER TIPS

The accepted answer to this question states:

If the space within a Panel is greater than the preferredDimension of the components contained within, the weightx and weighty is used to distribute the extra space to the individual components.

weighty won't "lock" each box to exactly 33% of the height; it doesn't distribute all of the space, but only the extra space.

So, if you need them to line up perfectly, use setPreferredSize (rather than of overriding getPreferredSize as you suggested).

Use a single GridBagLayout for both columns rather than splitting apart. GridBagLayout allows you to do more than just an HTML table would, without having to hack your size and preferred size methods. You can do something as follows in your frame initializer:

getContentPane().setLayout(new GridBagLayout());
GridBagConstraints constraints = null;
Insets insets = new Insets(0, 0, 0, 0);
...
// upper left hand corner, 1 column wide, 2 rows high, make the column take up half of the total width, the row(s) take up 0.66 of the total height
constraints = new GridBagConstraints(0, 0, 1, 2, 0.5, 0.66, GridBagConstraints.CENTER, GridBagConstraints.BOTH, insets, 0, 0);
getContentPane().add(upperLeftPanel, constraints);

// lower left hand corner, 1 column wide, 1 row high, make the column take up half of the total width, the row take up 0.33 of the total height
constraints = new GridBagConstraints(0, 1, 1, 1, 0.5, 0.33, GridBagConstraints.CENTER, GridBagConstraints.BOTH, insets, 0, 0);
getContentPane().add(lowerLeftPanel, constraints);

// upper right hand corner, 1 column wide, 1 row high, make the column take up half of the total width, the row take up 0.33 of the total height
constraints = new GridBagConstraints(1, 0, 1, 1, 0.5, 0.33, GridBagConstraints.CENTER, GridBagConstraints.BOTH, insets, 0, 0);
getContentPane().add(upperRightPanel, constraints);

// center right hand side, 1 column wide, 1 row high, make the column take up half of the total width, the row take up 0.33 of the total height
constraints = new GridBagConstraints(1, 1, 1, 1, 0.5, 0.33, GridBagConstraints.CENTER, GridBagConstraints.BOTH, insets, 0, 0);
getContentPane().add(centerRightPanel, constraints);

// lower right hand corner, 1 column wide, 1 row high, make the column take up half of the total width, the row take up 0.33 of the total height
constraints = new GridBagConstraints(1, 2, 1, 1, 0.5, 0.33, GridBagConstraints.CENTER, GridBagConstraints.BOTH, insets, 0, 0);
getContentPane().add(bottomRightPanel, constraints);

The various properties of the constraints, as well as the container where you will really add the panels is entirely up to you. You can change the same constraints object or create a new one every time. I have see both used, but tend to favor the latter myself. As you can see, there is no problem adding multiple columns to a single GridBagLayout.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top