代码之家  ›  专栏  ›  技术社区  ›  Hanzyusuf

如何使用GridBagLayout和GridBagLayout进行最佳对齐?

  •  3
  • Hanzyusuf  · 技术社区  · 8 年前

    我想在我的程序中尝试GridBagLayout,但遗憾的是我不太清楚,我也尝试过实现GridBagLayout,但两者都给我带来了不同的问题。让我向您展示代码和输出图片,以进一步澄清:

    package iKleen;
    
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;
    import java.net.*;
    
    public class ikleenRegister {
    
        JFrame frame;
        JPanel phonePanel, fieldPanel, mainPanel;
        JLabel name, email, password, address, mobile, l_register;
        JTextField nameField, emailField, passwordField, addressField, mobileField, countryCode;
        JButton b_register;
        GridBagConstraints c;
    
        public void launchGUI()
        {
            frame = new JFrame("iKleen - Register / Create Free Account");
    
            //phonePanel and its components
            phonePanel = new JPanel();
            phonePanel.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
            mobileField = new JTextField(8);
            countryCode = new JTextField(2);
            countryCode.setText("+91");
            countryCode.setEnabled(false);
            phonePanel.add(countryCode);
            phonePanel.add(mobileField);
    
            //fieldPanel and its components
            fieldPanel = new JPanel();
            fieldPanel.setLayout(new GridBagLayout());
            fieldPanel.setBorder(BorderFactory.createEmptyBorder(25,25,25,25));
            c = new GridBagConstraints();
            c.fill = GridBagConstraints.HORIZONTAL;
            name = new JLabel("Name: ");
            email = new JLabel("Email ID: ");
            password = new JLabel("Password: ");
            address = new JLabel("Address: ");
            mobile = new JLabel("Mobile Number: ");
            nameField = new JTextField(15);
            emailField = new JTextField(15);
            passwordField = new JTextField(15);
            addressField = new JTextField(20);
            c.gridx=0;
            c.gridy=0;
            fieldPanel.add(name, c);
            c.gridx=1;
            c.gridy=0;
            fieldPanel.add(nameField, c); 
            c.gridx=0;
            c.gridy=1;
            fieldPanel.add(email, c);
            c.gridx=1;
            c.gridy=1;
            fieldPanel.add(emailField, c);
            c.gridx=0;
            c.gridy=2;
            fieldPanel.add(password, c);
            c.gridx=1;
            c.gridy=2;
            fieldPanel.add(passwordField, c);
            c.gridx=0;
            c.gridy=3;
            fieldPanel.add(address, c);
            c.gridx=1;
            c.gridy=3;
            fieldPanel.add(addressField, c);
            c.gridx=0;
            c.gridy=4;
            fieldPanel.add(mobile, c);
            c.gridx=1;
            c.gridy=4;
            fieldPanel.add(phonePanel, c);
    
            //mainPanel and its components
            mainPanel = new JPanel();
            mainPanel.setBorder(BorderFactory.createEmptyBorder(25,25,25,25));
            mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
            Font font = new Font("MS Sans Serif", Font.BOLD, 18);
            l_register = new JLabel("Create a free account");
            l_register.setFont(font);
            l_register.setAlignmentX(Component.CENTER_ALIGNMENT);
            b_register = new JButton("Create Account");
            b_register.setAlignmentX(Component.CENTER_ALIGNMENT);
            mainPanel.add(l_register);
            mainPanel.add(fieldPanel);
            mainPanel.add(b_register);
    
            //final frame settings
            frame.setContentPane(mainPanel);
            frame.pack();
            centerFrame();
            frame.setVisible(true);
            frame.setResizable(false);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        }
    
        public void centerFrame() {
            Dimension currentScreen = Toolkit.getDefaultToolkit().getScreenSize();
            int x = (int) ((currentScreen.getWidth() - frame.getWidth()) / 2);
            int y = (int) ((currentScreen.getHeight() - frame.getHeight()) / 2);
            frame.setLocation(x, y);
        }
    }
    

    gridbaglayout

    package iKleen;
    
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;
    import java.net.*;
    
    public class ikleenRegister {
    
        JFrame frame;
        JPanel phonePanel, fieldPanel, mainPanel;
        JLabel name, email, password, address, mobile, l_register;
        JTextField nameField, emailField, passwordField, addressField, mobileField, countryCode;
        JButton b_register;
    
        public void launchGUI()
        {
            frame = new JFrame("iKleen - Register / Create Free Account");
    
            //phonePanel and its components
            phonePanel = new JPanel();
            phonePanel.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
            mobileField = new JTextField(15);
            countryCode = new JTextField(2);
            countryCode.setText("+91");
            countryCode.setEnabled(false);
            phonePanel.add(countryCode);
            phonePanel.add(mobileField);
    
            //fieldPanel and its components
            fieldPanel = new JPanel();
            fieldPanel.setLayout(new GridLayout(5,2,3,3));
            fieldPanel.setBorder(BorderFactory.createEmptyBorder(25,25,25,25));
            name = new JLabel("Name: ");
            email = new JLabel("Email ID: ");
            password = new JLabel("Password: ");
            address = new JLabel("Address: ");
            mobile = new JLabel("Mobile Number: ");
            nameField = new JTextField(15);
            emailField = new JTextField(15);
            passwordField = new JTextField(15);
            addressField = new JTextField(15);
            fieldPanel.add(name);
            fieldPanel.add(nameField);
            fieldPanel.add(email);
            fieldPanel.add(emailField);
            fieldPanel.add(password);
            fieldPanel.add(passwordField);
            fieldPanel.add(address);
            fieldPanel.add(addressField);
            fieldPanel.add(mobile);
            fieldPanel.add(phonePanel);
    
            //mainPanel and its components
            mainPanel = new JPanel();
            mainPanel.setBorder(BorderFactory.createEmptyBorder(25,25,25,25));
            mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
            Font font = new Font("MS Sans Serif", Font.BOLD, 18);
            l_register = new JLabel("Create a free account");
            l_register.setFont(font);
            l_register.setAlignmentX(Component.CENTER_ALIGNMENT);
            b_register = new JButton("Create Account");
            b_register.setAlignmentX(Component.CENTER_ALIGNMENT);
            mainPanel.add(l_register);
            mainPanel.add(fieldPanel);
            mainPanel.add(b_register);
    
            //final frame settings
            frame.setContentPane(mainPanel);
            frame.pack();
            centerFrame();
            frame.setVisible(true);
            frame.setResizable(false);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        }
    
        public void centerFrame() {
            Dimension currentScreen = Toolkit.getDefaultToolkit().getScreenSize();
            int x = (int) ((currentScreen.getWidth() - frame.getWidth()) / 2);
            int y = (int) ((currentScreen.getHeight() - frame.getHeight()) / 2);
            frame.setLocation(x, y);
        }
    }
    

    gridlayout

    在gridbaglayout中,数字字段与其余字段不对齐,我希望它们像JLabel一样在起点对齐。

    3 回复  |  直到 8 年前
        1
  •  3
  •   Ansharja    8 年前

    对于GridLayout:

    jlabels和jtextfield之间的“差距”是由于在GridLayout中,每个单元格的宽度和高度完全相同。 因此,由于jtextfields比标签宽,因此它们将变得更宽以适合其单元格。

    因此,如果您仍然希望使用没有间隙的GridLayout,您可以:

    • 将标签向右对齐。这将导致标签左侧出现空白。

    当然,这些不是解决方案,它们是一种折衷,因为您的面板将改变外观。

    我建议您使用GridBagLayout,更改“phonePanel”布局。 如果您不希望您的phonePanel与其他文本字段具有相同的宽度,则可以使用具有左对齐的flowlayout:

    phonePanel.setLayout (new FlowLayout(FlowLayout.LEFT, 0, 0));
    

    enter image description here

    如果您喜欢相同的宽度,可以在电话面板上设置BorderLayout,在BorderLayout上添加国家代码。WEST(给它一个固定的大小),并在中心添加mobileField(让它占据所有额外的空间)。

    phonePanel.setLayout(new BorderLayout());
    phonePanel.add(countryCode, BorderLayout.WEST);
    phonePanel.add(mobileField, BorderLayout.CENTER); 
    

    结果如下:

    enter image description here

    最后,您可以使用 insets 在标签和文本字段之间插入一点间隙。

        2
  •  3
  •   Thomas Fritsch    8 年前

    你的两次尝试(与 GridBagLayout GridLayout 对于外部面板),非常接近解决方案。 问题是 FlowLayout 你的 phonePanel . 在这两种变体中,您可以通过将其替换为 BorderLayout

        //phonePanel and its components
        phonePanel = new JPanel();
        phonePanel.setLayout(new BorderLayout(0, 0));
        mobileField = new JTextField(15);
        countryCode = new JTextField(2);
        countryCode.setText("+91");
        countryCode.setEnabled(false);
        phonePanel.add(countryCode, BorderLayout.WEST);
        phonePanel.add(mobileField, BorderLayout.CENTER);
    

    为了您的 网格布局

    enter image description here

    为了您的 网格包布局
    为了获得更好的外观,您可以通过以下方式在组件周围引入一些填充:

    c.insets = new Insets(5, 10, 5, 10);  // top, left, bottom, right padding
    

    enter image description here

        3
  •  1
  •   Fahad Shakeel    8 年前

    phonePanel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));