开发者

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 |          |
+---------------+--------------+----------+----------+
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜