0
votes

I have the following situation. I've created a JPanel with GridBagLayout with the following proportions. I want to get this straight, and after that I will add more components. For now I have something like

------------------------------------
|LABEL 45%  | LABEL 10% | LABEL 45%|
------------------------------------

Each label takes 1 cell horizontally and vertically (gridwidth/height = 1)

Weights (x) are 0.45, 0.1 and 0.45 (from left to right)

Weights (y) are 0.0

All labels have fill GBC.HORIZONTAL and the anchors are WEST, WEST, EAST.

JPanel topPanel = new JPanel(new GridBagLayout());

    topPanel.add(new JLabel("1"), new GridBagConstraints(
        0, 0, 1, 1, 0.45, 0.0, GridBagConstraints.WEST,
        GridBagConstraints.HORIZONTAL, INSETS_0PX, 0, 0));
    topPanel.add(new JLabel("2"), new GridBagConstraints(
        1, 0, 1, 1, 0.1, 0.0, GridBagConstraints.WEST,
        GridBagConstraints.BOTH, INSETS_0PX, 0, 0));
    topPanel.add(new JLabel("3"), new GridBagConstraints(
        2, 0, 1, 1, 0.45, 0.0, GridBagConstraints.EAST,
        GridBagConstraints.HORIZONTAL, INSETS_0PX, 0, 0));

At this point everything is OK, the first label gets the exact same space as the right label (which is 45% of the width available, and the other one gets 10%). Perfect.

But when I try to add, instead of a label (either left/right), another JPanel with a GridBagLayout, the proportions are not kept as defined.

In the left I want to add a JPanel which is defined as follows

----------------------
|JLabel..............|
|--------------------|
|JTextArea...........|
|....................|
----------------------

JLabel has weights 0.0 (for both x/y), WEST anchor, and fill NONE

JTextArea - weights 1.0(x), 1.0, WEST anchor, fill BOTH (in order to stretch)

myPanel = new JPanel(new GridBagLayout());
myPanel.add(new JLabel("TITLE", new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,
        GridBagConstraints.WEST, GridBagConstraints.NONE, INSETS_0PX, 0, 0));
myPanel.add(new JTextArea(5,25), new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0,
        GridBagConstraints.WEST, GridBagConstraints.BOTH, INSETS_0PX, 0, 0));

In the right, I want to add a JPanel with a GridBagLayout which holds two other JPanels with GridBagLaouts (there's no point in describing now how is defined).

--> therefore, at the moment when I add the left panel instead of the label, it gets somewhere around 60% of the screen (which is not right, it should get 45%).

Can you spot what is wrong? I'm out of ideas

LE: here's the simple example

public class Example extends JFrame {

public Example() {
    init();
}

private JPanel createPanel(Component comp) {
    JPanel topPanel = new JPanel(new GridBagLayout());

    topPanel.add(comp, new GridBagConstraints(
        0, 0, 1, 1, 0.45, 0.0, GridBagConstraints.WEST,
        GridBagConstraints.HORIZONTAL, new Insets(0,0,0,0), 0, 0));
    topPanel.add(new JLabel("2"), new GridBagConstraints(
        1, 0, 1, 1, 0.1, 0.0, GridBagConstraints.WEST,
        GridBagConstraints.BOTH, new Insets(0,0,0,0), 0, 0));
    topPanel.add(new JLabel("3"), new GridBagConstraints(
        2, 0, 1, 1, 0.45, 0.0, GridBagConstraints.EAST,
        GridBagConstraints.HORIZONTAL, new Insets(0,0,0,0), 0, 0));

    return topPanel;
}

private JPanel getPanelWithLabel() {
    return createPanel(new JLabel("1"));
}

private JPanel getPanelWithPanel() {
    JPanel myPanel = new JPanel(new GridBagLayout());
    myPanel.add(new JLabel("TITLE"), new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,
            GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0,0,0,0), 0, 0));
    myPanel.add(new JTextArea(5,25), new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0,
            GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(0,0,0,0), 0, 0));
    return createPanel(myPanel);
}

private void init() {
    setTitle("Simple example");
    setSize(800, 200);
    setLocationRelativeTo(null);
    setDefaultCloseOperation(EXIT_ON_CLOSE);

    JPanel panel = new JPanel(new BorderLayout());
    panel.add(getPanelWithLabel(), BorderLayout.CENTER);
//panel.add(getPanelWithPanel(), BorderLayout.CENTER);

    add(panel);
    setVisible(true);
}

public static void main(String[] args) {

    EventQueue.invokeLater(new Runnable() {

        @Override
        public void run() {
            Example ex = new Example();
        }
    });

}
}
3
If you add the JPanel alone with the JLabel without the JTextArea? To know if the problem is the JPanel or the JTextArea...Yassin Hajaj
@YassinHajaj I've removed the myPanel.add(new JTA()..), but still the same result. The left part gets 445px, right one 400pxMarius Manastireanu

3 Answers

1
votes

The problem lays with the rows of your JTextArea.

As 25 rows is wider than the 45%, it expends itself.

Instead of using 25, I'd use the WIDTH of the container (myPanel)


Solution

myPanel.add(new JTextArea(5,myPanel.WIDTH), new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0,
                GridBagConstraints.WEST, GridBagConstraints.BOTH, INSETS_0PX, 0, 0));

Output

enter image description here


EDIT

Since the sizes are still different with this method. I tried to create first a JPanel and to add the JLabel to it.


Solution

JPanel threeCont = new JPanel(new GridBagLayout());
threeCont.add(new JLabel("3"), new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,
        GridBagConstraints.WEST, GridBagConstraints.NONE, INSETS_0PX, 0, 0));
// We add myPanel and two(JLabel) to topPanel first and than the below.
topPanel.add(threeCont, new GridBagConstraints(
    2, 0, 1, 1, 0.45, 0.0, GridBagConstraints.EAST,
    GridBagConstraints.HORIZONTAL, INSETS_0PX, 0, 0));

Output

System.out.println("First Panel's Size : " + myPanel.getSize());
System.out.println("Second Panel's Size : " +two.getSize());
System.out.println("Third Panel's Size : " +threeCont.getSize());

Console

First Panel's Size : java.awt.Dimension[width=441,height=96]
Second Panel's Size : java.awt.Dimension[width=98,height=96]
Third Panel's Size : java.awt.Dimension[width=441,height=16]

Full code

public static void main(String[]a) {
    JFrame fr = new JFrame();
    fr.setSize(new Dimension(1000,1000));
    fr.setLocationRelativeTo(null);
    JPanel topPanel = new JPanel(new GridBagLayout());
    Insets INSETS_0PX = new Insets(0,0,0,0);
    JLabel one = new JLabel("1");
    JLabel two = new JLabel("2");
    one.setBackground(Color.yellow);
    two.setBackground(Color.blue);

    JPanel myPanel = new JPanel(new GridBagLayout());
    myPanel.add(new JLabel("TITLE"), new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,
            GridBagConstraints.WEST, GridBagConstraints.NONE, INSETS_0PX, 0, 0));
    myPanel.add(new JTextArea(5,myPanel.WIDTH), new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0,
            GridBagConstraints.WEST, GridBagConstraints.BOTH, INSETS_0PX, 0, 0));

    JPanel threeCont = new JPanel(new GridBagLayout());
    threeCont.add(new JLabel("TITLE"), new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,
            GridBagConstraints.WEST, GridBagConstraints.NONE, INSETS_0PX, 0, 0));

    topPanel.add(myPanel, new GridBagConstraints(
        0, 0, 1, 1, 0.45, 0.0, GridBagConstraints.WEST,
        GridBagConstraints.HORIZONTAL, INSETS_0PX, 0, 0));

    topPanel.add(two, new GridBagConstraints(
        1, 0, 1, 1, 0.1, 0.0, GridBagConstraints.WEST,
        GridBagConstraints.BOTH, INSETS_0PX, 0, 0));

    topPanel.add(threeCont, new GridBagConstraints(
        2, 0, 1, 1, 0.45, 0.0, GridBagConstraints.EAST,
        GridBagConstraints.HORIZONTAL, INSETS_0PX, 0, 0));


    fr.add(topPanel);

    fr.setVisible(true);

    System.out.println("First Panel's Size : " + myPanel.getSize());
    System.out.println("Second Panel's Size : " +two.getSize());
    System.out.println("Third Panel's Size : " +threeCont.getSize());
}
0
votes

I think you should add text area into scroll pane like - new JScrollPane(new JTextArea(5,25)) instead new JTextArea(5,25)... If you are add text area without scroll pane, grid bag layout will try to stretch cell to width set by rows given into text area constructor no mater what Weights is set to given cell into grid bag structure.

0
votes

The weightX constraint applies to the extra space available.

So each component is assigned its preffered size. Then if that is extra space in the window the space is allocated on the percentages specified.

So if you have compnents with a preferred size of:

45, 10, 45

and you increase the width of the panel by 100 you will get:

90, 20, 90.

But if you start with preferred sizes of:

150, 20, 100

and increase the width of the panel by 100 you will get:

195, 30, 145

So if you always want the ratio to apply the preferred size of each component must also be in the ration you desire.

An option might be to use the Relative Layout. It will ignore the preferred size and just assign the size based on the relative constraint of each component.