Search code examples
javaswingawtlayout-managergridbaglayout

JPanel GridBagLayout start from top instead of center


I´ve been trying to make a dashboard where the main menu buttons are listed from top of the dashboard to bottom, but setting

    gridBagConstraints.gridx = 10;
    gridBagConstraints.gridy = 0;

starts in center of the panel instead at the top. I tried setting gridBagConstraints.anchor = GridBagConstraints.FIRST_LINE_START and GridBagConstraints.NORT as well as NORTHWEST, but that did nothing.

Since there is a large panel on the side of the menu, I can't have the buttons auto fit into the (the weighty=1 option), otherwise the buttons become elongated.

Is there a way to force the buttons to make a list, or a way of doing this with another layout?


Solution

  • This is a common pattern. Generally, when you want to force the alignment of the components to a particular edge, you place a filler component on the opposite side and set it to fill the remaining empty space

    Filled

    import java.awt.Color;
    import java.awt.EventQueue;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    
    public class Test {
    
        public static void main(String[] args) {
            new Test();
        }
    
        public Test() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    JFrame frame = new JFrame();
                    frame.setLayout(new GridBagLayout());
                    GridBagConstraints gbc = new GridBagConstraints();
                    gbc.gridx = 0;
                    gbc.gridwidth = GridBagConstraints.REMAINDER;
    
                    frame.add(new JLabel("This is a line"), gbc);
                    frame.add(new JLabel("This is another line"), gbc);
                    frame.add(new JLabel("This is show off line"), gbc);
    
                    gbc.weighty = 1;
                    JPanel filler = new JPanel();
                    filler.setBackground(Color.RED);
    
                    frame.add(filler, gbc);
    
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    }
    

    ps I'd normally make the filler component transparent, but this is for demonstration purposes