How do I position labels of varying heights in two rows using GridBagLayout?
I'm trying to use GridBagLayout
to position labels in two rows, but I want some of the labels to span both rows and others to be placed 开发者_JS百科on top of each other. I need to use GridBagLayout
because of the proportional sizing functionality in the weightx
and weighty
properties of GridBagConstraints
. This is the layout I'm looking for:
+----------+----------+----------+----------+ | | | labelC | | | labelA | labelB |----------| labelD | | | | labelE | | +----------+----------+----------+----------+
The problem is that labelE
is being placed beneath LabelA
. Here is the layout portion of my code:
GridBagLayout gridbag = new GridBagLayout(); GridBagConstraints c = new GridBagConstraints(); this.setLayout(gridBag); c.fill = GridBagConstraints.BOTH; c.gridwidth = 1; c.gridheight = 2; c.weighty = PANEL_HEIGHT; gridbag.setConstraints(labelA, c); this.add(labelA); gridbag.setConstraints(labelB, c); this.add(labelB); c.gridheight = 1; c.weighty = TOPROW_HEIGHT; gridbag.setConstraints(labelC, c); this.add(labelC); c.gridheight = 2; c.gridwidth = GridBagConstraints.REMAINDER; c.weighty = PANEL_HEIGHT; gridbag.setConstraints(labelD, c); this.add(labelD); c.gridheight = 1; c.gridwidth = 1; c.weighty = BOTROW_HEIGHT; gridbag.setConstraints(labelE, c); this.add(labelE); this.validate();
Any ideas about what I'm missing?
You can use gridx
and gridy
to select your position on the grid :
GridBagLayout gridbag = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
this.setLayout(gridbag);
c.fill = GridBagConstraints.BOTH;
c.gridwidth = 1;
c.gridheight = 2;
c.gridx = 0;
c.gridy = 0;
c.weighty = PANEL_HEIGHT;
gridbag.setConstraints(labelA, c);
this.add(labelA);
c.gridx = 1;
c.gridy = 0;
gridbag.setConstraints(labelB, c);
this.add(labelB);
c.gridx = 2;
c.gridy = 0;
c.gridheight = 1;
c.weighty = TOPROW_HEIGHT;
gridbag.setConstraints(labelC, c);
this.add(labelC);
c.gridx = 3;
c.gridy = 0;
c.gridheight = 2;
c.gridwidth = GridBagConstraints.REMAINDER;
c.weighty = PANEL_HEIGHT;
gridbag.setConstraints(labelD, c);
this.add(labelD);
c.gridx = 2;
c.gridy = 1;
c.fill = GridBagConstraints.VERTICAL;
c.gridheight = 1;
c.gridwidth = 1;
c.weighty = BOTROW_HEIGHT;
gridbag.setConstraints(labelE, c);
this.add(labelE);
this.validate();
You need to set the gridX and gridY:
GridBagLayout gridbag = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
this.setLayout(gridBag);
c.fill = GridBagConstraints.BOTH;
c.gridwidth = 1;
c.gridheight = 2;
c.gridx = 0;
c.gridy = 0;
c.weighty = PANEL_HEIGHT;
gridbag.setConstraints(labelA, c);
this.add(labelA);
c.gridx = 1;
c.gridy = 0;
gridbag.setConstraints(labelB, c);
this.add(labelB);
c.gridx = 2;
c.gridy = 0;
c.gridheight = 1;
c.weighty = TOPROW_HEIGHT;
gridbag.setConstraints(labelC, c);
this.add(labelC);
c.gridx = 3;
c.gridy = 0;
c.gridheight = 2;
c.gridwidth = GridBagConstraints.REMAINDER;
c.weighty = PANEL_HEIGHT;
gridbag.setConstraints(labelD, c);
this.add(labelD);
c.gridx = 2;
c.gridy = 1;
c.gridheight = 1;
c.gridwidth = 1;
c.weighty = BOTROW_HEIGHT;
gridbag.setConstraints(labelE, c);
this.add(labelE);
this.validate();
Hope that helps.
My suggestion is you can do the above without using a GridBaglayout. It will save you a lot of time and reduced number of lines. For your particular problem, you can achieve what you're trying to using a simple Grid Layout.
Create one GridLayout of size 1x4. For the third column, you can use another GridLayout of size 2x1. Put them all in place and you should achieve what you want.
http://img823.imageshack.us/img823/5643/screenshot20101002at225.png
import java.awt.Component;
import java.awt.GridLayout;
import javax.swing.*;
public class LayoutTest extends JFrame {
public LayoutTest(){
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
this.setSize(300,75);
this.add(getCustomPanel());
this.setVisible(true);
}
private Component getCustomPanel() {
JPanel pnl = new JPanel();
GridLayout gridLayout = new GridLayout(1,4);
pnl.setLayout(gridLayout);
JPanel subPanel = new JPanel();
GridLayout subLayout = new GridLayout(2,1);
subPanel.setLayout(subLayout);
subPanel.add(new JLabel("labelC"));
subPanel.add(new JLabel("labelE"));
pnl.add(new JLabel("labelA"));
pnl.add(new JLabel("labelB"));
pnl.add(subPanel);
pnl.add(new JLabel("labelD"));
return pnl;
}
public static void main(String[] args) {
new LayoutTest();
}
}
The easiest way to solve this problem (using GridBag) is to have labelC and labelE inside a JPanel.
The more difficult way to solve it, is to use the gridx, gridy and gridheight constraints. So, you would have
+---------------+--------------+----------+----------+
| gridy=0 | gridy=0 | gridy=0 | gridy=0 |
| | | gridx=2 | gridx=3 |
| gridx=0 | gridx=1 |----------| |
| gridheight=2 | gridheight=2 | gridy=1 | |
| | | gridx=2 | |
+---------------+--------------+----------+----------+
精彩评论