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

Java 如何使用GridBagLayout和GridBagLayout进行最佳对齐?,java,swing,layout-manager,grid-layout,gridbaglayout,Java,Swing,Layout Manager,Grid Layout,Gridbaglayout,我想在我的程序中尝试GridBagLayout,但遗憾的是我不太清楚,我也尝试过实现GridBagLayout,但两者都给我带来了不同的问题。让我向您展示代码和输出图片以进一步澄清: package iKleen; import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.net.*; public class ikleenRegister { JFrame frame; JP

我想在我的程序中尝试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中,数字字段与其余字段不对齐,我希望它们在起点对齐,就像JLabel一样。 在gridlayout中,jfields和jLabel之间的差距太大,我尝试了许多解决方案,可惜没有成功。

您的两次尝试(使用
GridBagLayout
GridBagLayout
作为外部面板)都非常接近解决方案。 问题是
phonePanel
FlowLayout
。 在这两种变体中,您都可以通过将其替换为
边界布局
(零间隙)来解决问题:

对于您的
GridLayout
变体,请执行上述修复:

对于您的
GridBagLayout
变体,执行上述修复。
为了获得更好的外观,您可以通过以下方式在组件周围引入一些填充:

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

对于GridBagLayout,更新以下代码行。您正在使用FlowLayout.CENTER,它将移动号码字段移动到面板的中间

phonePanel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
对于网格布局:

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

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

  • 尝试限制jtextfields,为构造函数提供不同的列数(当前最大值为20)
  • 将JLabel向右对齐。这将导致标签左侧出现空白
当然,这些不是解决方案,它们是一种妥协,因为您的面板将改变外观

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

phonePanel.setLayout (new FlowLayout(FlowLayout.LEFT, 0, 0));
您将得到以下结果:

如果您希望具有相同的宽度,可以在电话面板上设置BorderLayout,在BorderLayout.WEST上添加国家代码(使其具有固定大小),并在中间添加mobileField(使其占用所有额外空间)

结果是:


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

谢谢,它实际上使它看起来更好,但我刚才说的是JLabel和JTextfield之间的间隙,它们之间的距离都太远,我希望它们更靠近一点,而且,如果您能让它看起来更专业,plz do help:)@Hanzyusuf我已经添加了一些提示,让您的
GridBagLayout
变体看起来更好。
phonePanel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
phonePanel.setLayout (new FlowLayout(FlowLayout.LEFT, 0, 0));
phonePanel.setLayout(new BorderLayout());
phonePanel.add(countryCode, BorderLayout.WEST);
phonePanel.add(mobileField, BorderLayout.CENTER);