Java Swing 工具的布局问题

Layout problems with Java Swing Tools

我正在尝试制作一个简单的 GUI 注册码 window,它有一个用于输入代码的文本,以及一个用于验证输入的代码是否正确的按钮。完全像这张图片:

所以我尝试用 java 使用 Java Swing 库来完成这个 GUI,这就是我的代码:

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

public class MainClass {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        final JFrame appFrame = new JFrame();
        final JPanel gridPanel = new JPanel(new GridLayout(2,1));
        
        
        Font f = new Font(Font.SERIF, Font.PLAIN, 20);
        JButton registerButton = new JButton("Register!");
        registerButton.setFont(f);
        JTextField verificationCodeText = new JTextField("--Enter your registration key here--");
        
        registerButton.setSize(30,20);
        verificationCodeText.setSize(50,20);
        verificationCodeText.setHorizontalAlignment(SwingConstants.CENTER);
        Border border = BorderFactory.createLineBorder(Color.BLACK, 5);
        verificationCodeText.setFont(f);
        verificationCodeText.setBorder(border);
        
        gridPanel.add(verificationCodeText);
        gridPanel.add(registerButton);
    
        appFrame.add(gridPanel);
        appFrame.setSize(400,400);
        appFrame.setVisible(true);
        
        System.out.println("End");
    }
}

但那是我得到的:

我可以用布局做什么来纠正这个问题?

(注意:忽略第一张图片中的外黑框,仅用于说明目的)

最好嵌套 JPanel,根据需要混合布局,并使用空白边框等填充,这比绝对设置大小要好。例如,使用类似于此的代码,下面的示例使用 BorderLayout 作为整体布局,然后将使用 JPanel(默认 JPanel 布局)的 FlowLayout 添加到顶部,并将使用 JPanel 的 GridBagLayout 添加到主 JPanel 的中心。如果以默认(无约束)方式添加,GridBag 将使单个组件居中:

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

@SuppressWarnings("serial")
public class RegistrationGUI extends JPanel {
    private JButton registerButton = new JButton("Register!");
    private JTextField verificationCodeText = new JTextField("--Enter your registration key here--", 20);
    
    public RegistrationGUI() {
        JPanel topPanel = new JPanel();
        int gap = 35;
        topPanel.setBorder(BorderFactory.createEmptyBorder(gap, gap, gap, gap));
        verificationCodeText.setHorizontalAlignment(SwingConstants.CENTER);
        topPanel.add(verificationCodeText);
        
        JPanel bottomPanel = new JPanel(new GridBagLayout());
        gap = 60;
        bottomPanel.setBorder(BorderFactory.createEmptyBorder(gap, gap, gap, gap));
        bottomPanel.add(registerButton);

        
        setLayout(new BorderLayout());
        add(topPanel, BorderLayout.PAGE_START);
        add(bottomPanel, BorderLayout.CENTER);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }

    private static void createAndShowGui() {
        RegistrationGUI mainPanel = new RegistrationGUI();
        JFrame frame = new JFrame("Registration");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.add(mainPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }
}