Search code examples
javaswinguser-interfacelayout-managergridbaglayout

GridBagLayout - adding margin to constraints to move the component to top from center


I am working on my first application to practice layout managers, I started learning the GridBagLayout and I want to create a login window, with a logo and a login box.

Currently my app looks like this:

img
(source: gyazo.com)

I feel that the logo is way too close to the login box, and far away from the top - therefore I need to find a way to give the logo a margin from the bottom, so it goes a bit to the top, so there will be a space between the two components, and the logo will be near the top bar.

Is it possible to do with GridBagLayout?

I've tried setting Insets, to 0, 0, 0, 110 and it moves the logo to the left a bit, not sure why.

@Override
public void init() throws Exception {
    GridBagLayout layout = new GridBagLayout();
    super.setLayout(layout);
    this.loginPane = new JPanel();
    this.loginPane.setSize(400, 400);
    this.loginPane.setBackground(Color.RED);
    JTextField username = new JTextField();
    username.setSize(200, 45);

    BufferedImage logo = ImageIO.read(new File("assets/logo.png"));
    JLabel logoLabel = new JLabel(new ImageIcon(logo));

    GridBagConstraints t = new GridBagConstraints();
    t.ipadx = logo.getWidth();
    t.ipady = logo.getHeight();
    t.gridx = 0;
    t.gridy = 0;

    super.add(logoLabel, t);
    t.ipadx = 500;
    t.ipady = 300;
    t.gridwidth = 1;
    t.gridheight = 1;
    t.gridy++;
    super.add(loginPane, t);
}

How can I do this?


Solution

  • There are other properties that you can use for better control on the width and height of the component in percentage.

    • weightx Specifies how to distribute extra horizontal space.

    • weighty Specifies how to distribute extra vertical space.

    It's better expanded under Swing Tutorial on How to Use GridBagLayout

    Try t.weighty=0.5; that will divide both in 50%-50% and place the component in the center as well. and let me know whether it looks as per your need or not?


    • Use frame.pack() instead of frame.setSize() that fits the components as per component's preferred size.

    • Override getPreferredSize() to set the preferred size of the JPanel instead of using setSize() method.

    sample code:

    JPanel panel = new JPanel() {
    
        @Override
        public Dimension getPreferredSize() {
            return new Dimension(..., ...);
        }
    };