GridBagLayout question: Position 3 and 2 equal sized buttons problem ?

U

Ulf Meinhardt

Assume a GridBayLayout with two button rows:
The first button row contains 3 equal sized buttons
and the second row conatins 2 equal sized buttons.

"Equal sized" menas the button in the same row have the same dimensions
(but not necessarily in comparison to the buttons in the other row).

The problem now is to code this within a GridBagLayout.

The result seems to be always either

Button1 ! Button2 ! Button3 !
Button4 ! Button5 !

or

Button1 ! Button2 ! Button3 !
Button4 ! Button5 !

But never (as desired):

Button1 ! Button2 ! Button3 !
Button4 ! Button5 !

Does someone have an idea (maybe with weightx constraint) ?

Ulf
 
H

hiwa

GridBagLayout, as the name suggests, use an
implicit 'grid' for layout scheme.

A better and easier layout often can be done by
using multiple sub-containers.

If it's me, I would use two Boxes with X_AXIS for
sub-containers. And the main container could be
a Y_AXIS one.
 
K

Knute Johnson

Ulf said:
Assume a GridBayLayout with two button rows:
The first button row contains 3 equal sized buttons
and the second row conatins 2 equal sized buttons.

"Equal sized" menas the button in the same row have the same dimensions
(but not necessarily in comparison to the buttons in the other row).

The problem now is to code this within a GridBagLayout.

The result seems to be always either

Button1 ! Button2 ! Button3 !
Button4 ! Button5 !

or

Button1 ! Button2 ! Button3 !
Button4 ! Button5 !

But never (as desired):

Button1 ! Button2 ! Button3 !
Button4 ! Button5 !

Does someone have an idea (maybe with weightx constraint) ?

Ulf

Ulf:

You can't easily (or at least I can't easily). So what I would do in a
case like this is to use a Panel for the second row with a FlowLayout or
GridBagLayout. Remember that you only need one GridBagConstraints
object no matter how many containers you are laying out. It will get
confusing though :).

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class test {
public static void main(String[] args) {
Runnable r = new Runnable() {
public void run() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.gridx = c.gridy = 0;
JButton b = new JButton("one");
f.add(b,c);
++c.gridx;
b = new JButton("two");
f.add(b,c);
++c.gridx;
b = new JButton("three");
f.add(b,c);

JPanel p = new JPanel();
p.setLayout(new GridBagLayout());
c.gridx = c.gridy = 0;
b = new JButton("four");
p.add(b,c);
++c.gridx;
b = new JButton("five");
p.add(b,c);

c.gridx = 0; c.gridy = 1; c.gridwidth = 3;
f.add(p,c);

f.pack();
f.setVisible(true);
}
};
EventQueue.invokeLater(r);
}
}
 
T

Thomas Hawtin

Ulf said:
Assume a GridBayLayout with two button rows:
The first button row contains 3 equal sized buttons
and the second row conatins 2 equal sized buttons.
But never (as desired):

Button1 ! Button2 ! Button3 !
Button4 ! Button5 !

Use columns
! ! ! ! !

Does someone have an idea (maybe with weightx constraint) ?

gridwidth. Give buttons 2, 4 and 5 a gridwidth of 2. You could make it
more obvious by giving buttons 1, 2 and 3 a gridwidth of 2, and buttons
4 and 5 a gridwidth of 3.

As hiwa says in another post, javax.swing.Box/BoxLayout can do it more
simply. GroupLayout (from Java SE 1.6) is also capable of doing it. I
suspect FormLayout (non-JRE) may get a bit confused.

Tom Hawtin
 
P

Paul Hamaker

I don't think you can do that with GBL, because its basis is a grid.
Here's an idea : put B1-3 in a panel, B4-5 in a second panel. This way
you can set layout managers for the panels (GridLayout?) and put the
panels in a container with a GridLayout of 2 lines.
 
P

Patricia Shanahan

Knute said:
Ulf:

You can't easily (or at least I can't easily). So what I would do in a
case like this is to use a Panel for the second row with a FlowLayout or
GridBagLayout. Remember that you only need one GridBagConstraints
object no matter how many containers you are laying out. It will get
confusing though :).
....

I have made it work using only GridBagLayout, but I had to write to the
public variable columnWeights to do it.

However, to me the problem description cries out for nested GridLayout
panels. It took me several tries to get my GridBagLayout version right.
In contrast, my nested GridLayout version ran correctly first time I
tested it.

Here are both versions, based on code shamelessly stolen from the quoted
message:

import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.JButton;
import javax.swing.JFrame;

public class TestGridBag {
public static void main(String[] args) {
Runnable r = new Runnable() {
public void run() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GridBagLayout g = new GridBagLayout();
f.setLayout(g);
g.columnWeights= new double[]{1.0,1.0,1.0,1.0,1.0,1.0};
GridBagConstraints c = new GridBagConstraints();

c.fill = GridBagConstraints.BOTH;
c.weightx = 1.0;
c.weighty = 1.0;

c.gridx = c.gridy = 0;

c.gridwidth = 2;
JButton b = new JButton("one");
f.add(b, c);
c.gridx+=2;
b = new JButton("two");
f.add(b, c);
c.gridx+=2;
b = new JButton("three");
f.add(b, c);

c.gridy = 1;
c.gridx = 0;
c.gridwidth = 3;

b = new JButton("four");
f.add(b, c);
c.gridx += 3;
b = new JButton("five");
f.add(b, c);

f.pack();
f.setVisible(true);
}
};
EventQueue.invokeLater(r);
}
}


import java.awt.EventQueue;
import java.awt.GridLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class TestGrid {
public static void main(String[] args) {
Runnable r = new Runnable() {
public void run() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLayout(new GridLayout(2, 1));

JPanel p = new JPanel();
p.setLayout(new GridLayout(1, 3));

p.add(new JButton("one"));
p.add(new JButton("two"));
p.add(new JButton("three"));
f.add(p);

p = new JPanel();
p.setLayout(new GridLayout(1, 2));

p.add(new JButton("four"));
p.add(new JButton("five"));
f.add(p);

f.pack();
f.setVisible(true);
}
};
EventQueue.invokeLater(r);
}
}
 
T

Thomas Hawtin

Patricia said:
I have made it work using only GridBagLayout, but I had to write to the
public variable columnWeights to do it.

If you add a row of spacer components, it works out fine. However, there
is more code.

I was forgetting how daft GridBagLayout can get with allocation by weight.
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GridBagLayout g = new GridBagLayout();
f.setLayout(g);
g.columnWeights= new double[]{1.0,1.0,1.0,1.0,1.0,1.0};

Ditch this last line.
GridBagConstraints c = new GridBagConstraints();

c.fill = GridBagConstraints.BOTH;
c.weightx = 1.0;
c.weighty = 1.0;

Discard this last line, for now.
c.gridx = c.gridy = 0;

Insert a row of spacers:

f.add(Box.createHorizontalGlue(), c);
c.gridx++;
f.add(Box.createHorizontalGlue(), c);
c.gridx++;
f.add(Box.createHorizontalGlue(), c);
c.gridx++;
f.add(Box.createHorizontalGlue(), c);
c.gridx++;
f.add(Box.createHorizontalGlue(), c);
c.gridx++;
f.add(Box.createHorizontalGlue(), c);

Move onto next line:

c.weightx = 0.0;
c.weighty = 1.0;
c.gridy++;
c.gridx = 0;
c.gridwidth = 2;
JButton b = new JButton("one");
f.add(b, c);
c.gridx+=2;
b = new JButton("two");
f.add(b, c);
c.gridx+=2;
b = new JButton("three");
f.add(b, c);
c.gridy = 1;

Correct this last line to:

c.gridy++;
c.gridx = 0;
c.gridwidth = 3;

b = new JButton("four");
f.add(b, c);
c.gridx += 3;
b = new JButton("five");
f.add(b, c);

f.pack();
f.setVisible(true);

Tom Hawtin
 
P

Patricia Shanahan

Thomas said:
If you add a row of spacer components, it works out fine. However, there
is more code. ....
Insert a row of spacers:

f.add(Box.createHorizontalGlue(), c);
c.gridx++;
....

Thanks! I understood my problem was caring about the width of a column
without having inserted any components in it, but couldn't think what to
use for spacing.

I still think forgetting GridBagLayout, and using e.g. nested
GridLayouts, is a much better solution to the problem.

Patricia
 
T

Thomas Hawtin

Nigel said:
That is to be expected - GridBaglayout creates a grid made up of columns. The
columns in each row line up, so you cannot have a column in row 2 which is in
the middle of the column in row 1.

You can have a component span multiple columns or rows using gridwidth
and gridheight. However, there is a problem distributing weight over
multiple columns. So either use single column/row spacer components for
allocating weights or override with GridBagLayout.columnWidths. See
other posts in this thread.

Tom Hawtin
 
N

Nigel Wade

Ulf said:
Assume a GridBayLayout with two button rows:
The first button row contains 3 equal sized buttons
and the second row conatins 2 equal sized buttons.

"Equal sized" menas the button in the same row have the same dimensions
(but not necessarily in comparison to the buttons in the other row).

The problem now is to code this within a GridBagLayout.

The result seems to be always either

Button1 ! Button2 ! Button3 !
Button4 ! Button5 !

or

Button1 ! Button2 ! Button3 !
Button4 ! Button5 !

But never (as desired):

Button1 ! Button2 ! Button3 !
Button4 ! Button5 !

Does someone have an idea (maybe with weightx constraint) ?

That is to be expected - GridBaglayout creates a grid made up of columns. The
columns in each row line up, so you cannot have a column in row 2 which is in
the middle of the column in row 1.

You have 2 choices.
1 - Create inner containers for each row. Give the top container a grid of 3
columns and the lower container a grid of 2 columns. The problem here is that
the rows might end up being different heights.
2 - Create a grid which has a number of columns which is divisible by both 2 and
3, e.g. 6. On the top row you make each button span
(GridBagConstraints.gridwidth) 2 columns, and on the bottom row you make each
button span 3 columns.
 
D

Dave Mandelin

Nested BoxLayouts will probably be a lot easier than GridBag (yuck).

If you must use GridBag, try making 6 columns and sizing the buttons in
the first row to take up 2 columns and the buttons in the second row 3
columns.
 
T

Thomas Hawtin

Nigel said:
I think that GridBagLayout was meant to be quite simple and clean in its
concept, but actually got implemented by committee.

I think the opposite. I suspect it was written by someone who threw all
his cool ideas into the bag. With such a rush to get JDK 1.00 out, there
would have been little time to sort the wheat from the chaff or to make
sure that the algorithms were sensible. I mean ipad[xy], even the
documentation is misleading (perhaps it made sense on NeWS).

Tom Hawtin
 
N

Nigel Wade

Thomas said:
You can have a component span multiple columns or rows using gridwidth
and gridheight. However, there is a problem distributing weight over
multiple columns. So either use single column/row spacer components for
allocating weights or override with GridBagLayout.columnWidths. See
other posts in this thread.

Yes, I see what you mean. I've just tried the simple layout of 3+2 in 6 columns
and the weights are somewhat problematic...

I think that GridBagLayout was meant to be quite simple and clean in its
concept, but actually got implemented by committee.
 
S

steve

Assume a GridBayLayout with two button rows:
The first button row contains 3 equal sized buttons
and the second row conatins 2 equal sized buttons.

"Equal sized" menas the button in the same row have the same dimensions
(but not necessarily in comparison to the buttons in the other row).

The problem now is to code this within a GridBagLayout.

The result seems to be always either

Button1 ! Button2 ! Button3 !
Button4 ! Button5 !

or

Button1 ! Button2 ! Button3 !
Button4 ! Button5 !

But never (as desired):

Button1 ! Button2 ! Button3 !
Button4 ! Button5 !

Does someone have an idea (maybe with weightx constraint) ?

Ulf

it also depends on the text in the buttons and if your fonts are left/right
justified & if your buttons are tied to the compass directions or
centralised.

the way i work with GBL is:

1. remove any fill, remove any weight, remove padding ,remove weight, remove
anchors
2. setup the items, (usually in their own panel, to keep control of the
beast)
3. get the layout correct
6. add the items i remove in 1 back.

your above problem looks like its caused by , fill or weight., are you using
an IDE design tool?

steve
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top