Swing: can't center a vbox inside a JPanel

1k Views Asked by At

I have this code that creates a simply JPanel with text

User profile panel
username: a user
email: [email protected]
Button1 Button2

Each row - is a HorizontalBox and all rows come into a VerticalBox. I try to center the result VerticalBox, but it doesn't work.

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

public class TestProfile extends JPanel  {
    {
        setup();
    }
    public void setup() {
        Box vBoxUserData = Box.createVerticalBox();

        Box hBoxUsername = Box.createHorizontalBox();
        hBoxUsername.add(new JLabel("username: "));
        hBoxUsername.add(new JLabel("a user"));
        vBoxUserData.add(hBoxUsername);

        Box hBoxEmail = Box.createHorizontalBox();
        hBoxEmail.add(new JLabel("email: "));
        hBoxEmail.add(new JLabel("[email protected]"));
        vBoxUserData.add(hBoxEmail);

        Box hBoxButtons = Box.createHorizontalBox();
        hBoxButtons.add(new JButton("Button1"));
        hBoxButtons.add(new JButton("Button2"));

        Box vBoxContent = Box.createVerticalBox();
        vBoxContent.add(new JLabel("User profile panel"));
        vBoxContent.add(hBoxUsername);
        vBoxContent.add(hBoxEmail);
        vBoxContent.add(hBoxButtons);

        vBoxContent.setAlignmentX(CENTER_ALIGNMENT);
        vBoxContent.setAlignmentY(CENTER_ALIGNMENT);
        hBoxUsername.setBackground(Color.RED);

        add(vBoxContent);
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.add(new TestProfile());
        frame.setVisible(true);
        frame.setDefaultCloseOperation(
                WindowConstants.EXIT_ON_CLOSE);
        frame.setSize(600, 400);
    }

}

It looks like this:

enter image description here

while I need it to look like this:

enter image description here

Also I'm confused why

        hBoxUsername.setBackground(Color.RED);

didn't paint it in red?

1

There are 1 best solutions below

0
On

A Box layout just stacks its children in its natural direction. If you want to stretch out the space before those children, add glue to the box before and after the children that you want centered:

Box vBoxContent = Box.createVerticalBox();
vBoxContent.add(new JLabel("User profile panel"));
vBoxContent.add(Box.createVerticalGlue());
vBoxContent.add(hBoxUsername);
vBoxContent.add(hBoxEmail);
vBoxContent.add(hBoxButtons);
vBoxContent.add(Box.createVerticalGlue());

But this alone isn’t enough. Your TestProfile class extends JPanel but never sets the layout. The default layout is a FlowLayout, which won’t attempt to make its child fill its space, so you won’t ever see the effects of adding the glue components.

This can be fixed by using a layout that forces the (sole) child component to fill the entire space of the JPanel, such as BorderLayout:

setLayout(new BorderLayout());
add(vBoxContent);

Finally, JLabels are transparent except for their content. If you want to fill a JLabel with a color, make it opaque:

hBoxUsername.setBackground(Color.RED);
hBoxUsername.setOpaque(true);