Search code examples
javaswinggridbaglayout

GridBagLayout showing these components apart from each other


i want it to be like thisI am practicing [GridBagLayout] and I have search it on net but I don't find the answer of my problem then I come here so to find some help , why they are going apart from each other

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

public class StudentProfile extends JFrame {

    public StudentProfile() {
        super("Student Profile");
        setSize(400, 400);
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        Container c = getContentPane();

        c.setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.weightx = 1.0;
        gbc.weighty = 1.0;
        gbc.gridheight = 1;
        gbc.gridwidth = 5;
        gbc.anchor =  GridBagConstraints.FIRST_LINE_START;
        JLabel stProfile = new JLabel("Student Profile");
        c.add(stProfile, gbc);

        JPanel j1 = new JPanel();
        j1.setLayout(new GridBagLayout());
        GridBagConstraints gbc1 = new GridBagConstraints();
        gbc1.gridx = 0;
        gbc1.gridy = 0;
        JLabel stName = new JLabel("Student Name", SwingConstants.LEFT);
        j1.add(stName, gbc1);

        gbc1.gridy = 1;
        JLabel fName = new JLabel("Father Name", SwingConstants.LEFT);
        j1.add(fName, gbc1);

        gbc.gridy = 1;
        c.add(j1, gbc);
    }

    public static void main (String[] agrs) {
        StudentProfile sp = new StudentProfile();
        sp.setVisible(true);
    }
}

enter image description here


Solution

  • The thing is in weights. Make weighty=1 right before you place your last element. And use Insets to create gaps between components. See comments in code below. Remember to use gbc.fill, which makes components stretch in direction you specify (HORIZONTAL, VERTICAL, BOTH, NONE). Also, you are messing a lot with your gbc and gbc1 objects. Try refactoring your code into smaller classes/methods - read Single Responsibility Principle. Generally, using numbers in variable's names is not a good idea.

    SSCCE

    public class StudentProfile extends JFrame {
    
        public StudentProfile() {
        super("Student Profile");
        setSize(400, 400);
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        Container c = getContentPane();
    
        c.setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
    
        gbc.insets = new Insets(0, 0, 10, 0); //<---1 this to make a bottom gap after first label
        gbc.weightx = 1.0;
        //gbc.weighty = 1.0; <---2 take this from here
        gbc.gridheight = 1;
        gbc.gridwidth = 5;
        gbc.anchor = GridBagConstraints.FIRST_LINE_START;
        JLabel stProfile = new JLabel("Student Profile");
        c.add(stProfile, gbc);
    
        gbc.insets = new Insets(0, 0, 0, 0); //<---1 reset insets
    
        JPanel j1 = new JPanel();
        j1.setLayout(new GridBagLayout());
        GridBagConstraints gbc1 = new GridBagConstraints();
        gbc1.gridx = 0;
        gbc1.gridy = 0;
        JLabel stName = new JLabel("Student Name", SwingConstants.LEFT);
        j1.add(stName, gbc1);
    
        gbc1.gridy = 1;
        JLabel fName = new JLabel("Father Name", SwingConstants.LEFT);
        j1.add(fName, gbc1);
        gbc.weighty = 1.0; //<---2 here
        gbc.gridy = 1;
    
        c.add(j1, gbc);
    }
    
    public static void main (String[] agrs) {
        StudentProfile sp = new StudentProfile();
        sp.setVisible(true);
    }
    

    Result:

    Result layout

    Also, take a look at this code, which is a modified version of yours.

    public class StudentProfile extends JFrame {
    
        private Container container;
        private JPanel studentProfileInfoPanel;
    
        public StudentProfile(String title) {
            super(title);
        }
    
        public void createStudentProfile() {
            this.setSize(400, 400);
            this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    
            this.container = this.getContentPane();
    
            this.container.setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
    
            gbc.insets = new Insets(0, 0, 10, 0);
            gbc.weightx = 1.0;
            gbc.gridx=0;
            gbc.gridy=0;
            gbc.fill = GridBagConstraints.BOTH;
            gbc.anchor = GridBagConstraints.NORTHWEST;
    
            JLabel studentProfileLabel = new JLabel("Student Profile");
            this.container.add(studentProfileLabel, gbc);
    
            this.createStudentProfileInfoPanel();
    
            gbc.insets = new Insets(0, 0, 0, 0);
            gbc.weighty = 1.0;
            gbc.gridy++;
            //gbc.fill=GridBagConstraints.NONE; //<--- try using this, see what happens
            this.container.add(studentProfileInfoPanel, gbc);
        }
    
        private void createStudentProfileInfoPanel() {
            this.studentProfileInfoPanel = new JPanel(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
    
            gbc.fill = GridBagConstraints.HORIZONTAL;
            gbc.insets = new Insets(10,0,0,10);
            gbc.weightx = 1;
    
            gbc.gridx = 0;
            gbc.gridy = 0;
            JLabel studentNameLabel = new JLabel("Student Name");
            this.studentProfileInfoPanel.add(studentNameLabel, gbc);
    
            gbc.gridx++;
            this.studentProfileInfoPanel.add(new JLabel ("Adam Smith Jr"), gbc);
    
            gbc.gridx=0;
            gbc.gridy++;
            JLabel studentFatherNameLabel = new JLabel("Father Name");
            this.studentProfileInfoPanel.add(studentFatherNameLabel, gbc);
    
            gbc.weighty = 1;
            gbc.gridx++;
            this.studentProfileInfoPanel.add(new JLabel("Adam Smith"), gbc);
        }
    
        public static void main(String[] agrs) {
            StudentProfile studentProfile = new StudentProfile("Student Profile");
            studentProfile.createStudentProfile();
    
            SwingUtilities.invokeLater(() -> {
                studentProfile.setVisible(true);
            });
        }
    }
    

    If this helps, accept this answer. :)