Search code examples
javaswinglayout-managergridbaglayout

Anchor constraint in GridBagLayout not working


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

public class GBLClumpingExample extends JFrame{

    GBLClumpingExample(){
        GridBagLayout g = new GridBagLayout();
        GridBagConstraints gv = new GridBagConstraints();

        GridBagLayout b = new GridBagLayout();
        GridBagConstraints gc = new GridBagConstraints();

        setVisible(true);
        setSize(720,720);
        setLayout(g);

        JPanel p = new JPanel();
        p.setLayout(b);
        gv.fill = GridBagConstraints.BOTH;
        add(p,gv);
        
        Label l1 = new Label("Label 1");
        Label l2 = new Label("Label 2");
        Label l3 = new Label("Label 3");
        Label l4 = new Label("Label 4");
        Label l5 = new Label("Label 5");
        
        gc.weightx =1.0;
        gc.weighty = 1.0;
        gc.gridx= 1;
        gc.gridy= 1;
        gc.anchor = GridBagConstraints.PAGE_START;
        gc.gridx= -1;
        gc.gridy= 0;
        p.add(l1,gc);
        gc.anchor = GridBagConstraints.SOUTH;
        p.add(l2,gc);
        gc.anchor = GridBagConstraints.EAST;
        p.add(l3,gc);
        gc.anchor = GridBagConstraints.WEST;
        p.add(l4,gc);
        gc.anchor = GridBagConstraints.CENTER;
        p.add(l5,gc);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    public static void main(String[] args){
        GBLClumpingExample e = new GBLClumpingExample();
    }
}

I was trying to use GridBagLayout but maybe it is not working correctly.

This is my code I don't know what is wrong but anchor constraints of GridBagConstraints are not working, they are all just clump together.


Solution

  • You are adding you components to a panel p which you are then adding to the frame (to its content pane) using add(p,gv);. The constraints in gv have been initialized with gv.fill = GridBagConstraints.BOTH;, but its weightx and weighty are left at their initial zero. As a result, this panel will stay at its preferred size and not receive additional space, so it has no additional space to distribute to its own content.

    Since all labels have the same size, their anchors have no effect when there is no additional space.

    When you change the line

    gv.fill = GridBagConstraints.BOTH;
    

    to

    gv.fill = GridBagConstraints.BOTH;
    gv.weightx = 1;
    gv.weighty = 1;
    

    you will see the effect of the anchors. Alternatively, you can get rid of the additional panel. There are other redundant operations too. You can simplify your code to:

    import java.awt.*;
    import javax.swing.*;
    
    public class GBAnchorExample extends JFrame{
        GBAnchorExample() {
            Container c = super.getContentPane();
            c.setLayout(new GridBagLayout());
            GridBagConstraints gc = new GridBagConstraints();
            gc.weightx = gc.weighty = 1.0;
    
            JLabel l1 = new JLabel("Label 1");
            JLabel l2 = new JLabel("Label 2");
            JLabel l3 = new JLabel("Label 3");
            JLabel l4 = new JLabel("Label 4");
            JLabel l5 = new JLabel("Label 5");
    
            gc.anchor = GridBagConstraints.PAGE_START;
            c.add(l1,gc);
            gc.anchor = GridBagConstraints.SOUTH;
            c.add(l2,gc);
            gc.anchor = GridBagConstraints.EAST;
            c.add(l3,gc);
            gc.anchor = GridBagConstraints.WEST;
            c.add(l4,gc);
            gc.anchor = GridBagConstraints.CENTER;
            c.add(l5,gc);
            super.setDefaultCloseOperation(EXIT_ON_CLOSE);
        }
    
        public static void main(String[] args) {
            GBAnchorExample e = new GBAnchorExample();
            e.setSize(720,720);
            e.setVisible(true);
        }
    }
    

    To visualize the actual effect of the anchor you may change the main method to

    public static void main(String[] args){
        GBAnchorExample e = new GBAnchorExample();
        Component grid = new JComponent() {
            @Override
            protected void paintComponent(Graphics g) {
                g.setColor(Color.GREEN);
                int w = getWidth(), h = getHeight();
                for(int i = 1; i < 5; i++) {
                    int x = (int)(w/5.0*i);
                    g.drawLine(x, 0, x, h);
                }
            }
        };
        e.setGlassPane(grid);
        grid.setVisible(true);
        e.setSize(720,720);
        e.setVisible(true);
    }
    

    This will paint a green grid to show the logical cells containing the labels, so it becomes apparent how the anchors affect the labels’ positions within their cells.