You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java Swing解决登录页在主JFrame前最小化显示异常问题

核心问题点
  • 变量遮蔽:类中已定义frame(主窗体)、lframe(登录窗体)成员变量,但构造方法内重复声明了同名局部变量,所有窗体配置仅作用于局部变量,类成员变量始终未初始化,后续登录页方法操作的都是空对象
  • 组件挂载错误:初始化的container是TestFrame类(自身继承JFrame)的内容面板,所有登录页组件都被添加到了这个隐式窗体上,没有挂载到登录窗体中
  • 显示顺序错误:构造方法中直接将主窗体设置为可见,未等登录验证就提前加载主界面
  • 登录窗体配置缺失:局部声明的登录窗体未设置尺寸、居中规则、关闭逻辑,启动后默认以最小化状态显示
  • 监听器方法未生效:类实现了ActionListener接口,但没有重写actionPerformed方法,自定义的loginActionPerformed方法不会被事件触发
修改步骤
  1. 删除构造方法中重复声明的局部lframe、frame变量,直接初始化类层面的成员变量
  2. 初始状态下主窗体不设置可见,仅在登录验证通过后再触发显示
  3. 将登录页的容器指向登录窗体的内容面板,确保所有登录组件正确挂载到登录窗上
  4. 为登录窗体补全尺寸、居中显示、关闭规则等基础配置
  5. 重写actionPerformed方法绑定按钮事件,登录成功后销毁登录窗体,再加载主窗体
修正后的可运行核心代码
public class TestFrame extends JFrame implements ActionListener{

    private JFrame frame; //主窗体
    private JFrame lframe; //登录窗体
    private Container container;
    private JLabel userLabel;
    private JLabel passwordLabel;
    private JTextField userTextField;
    private JPasswordField passwordField;
    private JButton loginButton;
    private JButton resetButton;
    private JCheckBox showPassword;

    public TestFrame() {
        // 初始化主窗体,初始状态不可见
        frame = new JFrame();
        frame.setTitle("Test System");
        frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(new JLabel(new ImageIcon("test.png")));
        frame.setResizable(false);
        JMenuBar menuBar = new JMenuBar();
        frame.setJMenuBar(menuBar);
        // 此处保留主窗体其他业务组件初始化逻辑

        // 初始化登录窗体
        lframe = new JFrame();
        lframe.setTitle("Login BHMS");
        lframe.setSize(500,500);
        lframe.setLocationRelativeTo(null); // 登录窗居中显示
        lframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        lframe.setResizable(false);
        container = lframe.getContentPane(); // 容器指向登录窗体的内容面板

        // 初始化登录组件
        userLabel = new JLabel("USERNAME");
        passwordLabel = new JLabel("PASSWORD");
        userTextField = new JTextField();
        passwordField = new JPasswordField();
        loginButton = new JButton("LOGIN");
        resetButton = new JButton("RESET");
        showPassword = new JCheckBox("Show Password");

        // 加载登录页
        login();
    }

    public void login() {
        setLayoutManager();
        setLocationAndSize();
        addComponentsToContainer();
        addActionEvent();
        lframe.setVisible(true);
    }

    public void setLayoutManager() {
        container.setLayout(null);
    }
 
    public void setLocationAndSize() {
        userLabel.setBounds(50, 150, 100, 30);
        passwordLabel.setBounds(50, 220, 100, 30);
        userTextField.setBounds(150, 150, 150, 30);
        passwordField.setBounds(150, 220, 150, 30);
        showPassword.setBounds(150, 250, 150, 30);
        loginButton.setBounds(50, 300, 100, 30);
        resetButton.setBounds(200, 300, 100, 30);
    }

    public void addComponentsToContainer() {
        container.add(userLabel);
        container.add(passwordLabel);
        container.add(userTextField);
        container.add(passwordField);
        container.add(showPassword);
        container.add(loginButton);
        container.add(resetButton);

        JLabel lblNewLabel = new JLabel("");
        lblNewLabel.setIcon(new ImageIcon(getClass().getResource("/development/test1.png")));
        lblNewLabel.setBounds(106, 10, 204, 113);
        container.add(lblNewLabel);
    }

    public void addActionEvent() {
        loginButton.addActionListener(this);
        resetButton.addActionListener(this);
        showPassword.addActionListener(this);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        // 登录按钮逻辑
        if (e.getSource() == loginButton) {
            String userText = userTextField.getText();
            String pwdText = String.valueOf(passwordField.getPassword());
            if (userText.equalsIgnoreCase("Admin") && pwdText.equalsIgnoreCase("Admin")) {
                JOptionPane.showMessageDialog(lframe, "Login Successful. Hello "+userText);
                // 登录成功:销毁登录窗,显示主窗体
                lframe.dispose();
                frame.setVisible(true);
            } 
            else {
                JOptionPane.showMessageDialog(lframe, "Invalid Username or Password");
            }
        }
        // 重置按钮逻辑
        if (e.getSource() == resetButton) {
            userTextField.setText("");
            passwordField.setText("");
        }
        // 显示密码逻辑
        if (e.getSource() == showPassword) {
            passwordField.setEchoChar(showPassword.isSelected() ? (char)0 : '*');
        }
    }

    public static void main(String[] args) {
        // Swing组件需在事件调度线程启动,避免线程安全问题
        SwingUtilities.invokeLater(TestFrame::new);
    }
}
额外优化建议
  • JPasswordField的getText()方法已废弃,统一使用String.valueOf(passwordField.getPassword())获取密码,规避安全风险
  • 生产环境不建议使用null绝对布局,不同分辨率下会出现组件错位,优先使用官方提供的BorderLayout、FlowLayout或第三方布局管理器
  • 所有Swing窗体启动逻辑需放在SwingUtilities.invokeLater()中执行,保证界面渲染线程安全

内容的提问来源于stack exchange,提问作者Brainmated

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 22:21:31