java - 如何使用 GridBagLayout 和 GridLayout 实现最佳对齐?

标签 java swing layout-manager grid-layout gridbaglayout

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

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 一样在起点对齐。 在网格布局中,jfield 和 jlabel 之间的间隙太大,我尝试了很多解决方案,遗憾的是没有效果。

最佳答案

对于网格布局:

您在 jlabel 和 jtextfield 之间看到的“间隙”是由于以下事实引起的:在 GridLayout 中,每个单元格都具有完全相同的宽度和高度。 因此,由于您的 jtextfields 比标签宽,它们将变得更宽以适合其单元格。

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

  • 尝试限制您的 jtextfields,为构造函数指定不同的列数(当前最大值为 20)。
  • 将 jlabel 向右对齐。这将导致空白间隙被放置在标签的左侧。

当然,这些不是解决方案,它们是一种妥协,因为您的面板会改变方面。

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

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

您将得到以下结果:

enter image description here

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

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

这是结果:

enter image description here

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

关于java - 如何使用 GridBagLayout 和 GridLayout 实现最佳对齐?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45055938/

相关文章:

java - JTextPane 中未呈现 CSS 填充

java - Lombok @Builder 不创建不可变对象(immutable对象)?

java - 用括号解析负数

java AWT native 操作系统库?

java - 类如何将其父类(super class)的方法视为接口(interface)方法的实现?

java - 无法用java写入文件

java - JTextArea setText 不工作

java - 如何在 JPanel 中设置 JButton 的大小

java - 使用 GridLayout 进行修饰

java - Swing 布局 - 在保持组件尺寸的同时使用网格