Search code examples
javaswinglayout-managergridbaglayout

GridBagLayout not getting expected result


Trying to understand how the GridBagLayout for Java works. Never used it before so its probably a stupid error that I've made.

My objective is to place a JLabel at the top center of the page. I've been using the java tutorials on Oracle but have had no luck. It seems the label remains in the center of the page. (center as in dead center of the x and y graph).

From what I understood, if I set the gridx and gridy constraint to 0, the compiler will look at the top, first row of the program and place the text their. I then used the PAGE START anchor to place the text in the center of the page. I'm not entirely sure what the weightx and weighty function does in my defence.

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

class test
{
    public static void main (String Args [])
    {
    //frame and jpanel stuff
    JFrame processDetail = new JFrame("Enter information for processes");
    JPanel panelDetail = new JPanel(new GridBagLayout());
    GridBagConstraints c = new GridBagConstraints();

    //label to add on top centre
    JLabel label = new JLabel("LOOK AT ME");

    //set size of frame and operation
    processDetail.setSize(500,500);
    processDetail.setDefaultCloseOperation(processDetail.EXIT_ON_CLOSE);

    //add the label to panel
    c.fill = GridBagConstraints.HORIZONTAL;
    c.anchor = GridBagConstraints.PAGE_START;
    c.weightx = 0; //not sure what this does entirely
    c.gridx = 0; //first column
    c.gridy = 0; //first row
    panelDetail.add(label, c);

    processDetail.add(panelDetail);
    processDetail.setVisible(true);
    }
}

Solution

  • You're only adding one thing to the GBL using container, and so it will be centered. If you add a 2nd component below your JLabel, the JLabel will show up at the top. For example,

    import java.awt.Dimension;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    
    import javax.swing.*;
    
    public class Test2 {
       private static void createAndShowGui() {
          JPanel mainPanel = new JPanel(new GridBagLayout());
          GridBagConstraints gbc = new GridBagConstraints();
          gbc.gridx = 0;
          gbc.gridy = 0;
          gbc.gridheight = 1;
          gbc.gridwidth = 1;
          gbc.weightx = 1.0;
          gbc.weighty = 1.0;
          gbc.fill = GridBagConstraints.BOTH;
          gbc.anchor = GridBagConstraints.PAGE_START;
    
          mainPanel.add(new JLabel("Look at me!", SwingConstants.CENTER), gbc);   
    
    
          gbc.gridy = 1;
          gbc.gridheight = 10;
          gbc.gridwidth = 10;
    
          mainPanel.add(Box.createRigidArea(new Dimension(400, 400)), gbc);
    
          JFrame frame = new JFrame("Test2");
          frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
          frame.getContentPane().add(mainPanel);
          frame.pack();
          frame.setLocationByPlatform(true);
          frame.setVisible(true);
       }
    
       public static void main(String[] args) {
          SwingUtilities.invokeLater(new Runnable() {
             public void run() {
                createAndShowGui();
             }
          });
       }
    }
    

    Myself, I'd use BorderLayout if I wanted my JLabel to be at the top.