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

Java Swing多JFrame切换问题:登录按钮触发空指针异常求助

解决JFrame切换时的NullPointerException问题

首先看你的报错,NullPointerException出现在openLearnerDataBase方法的第21行,这说明你调用setVisible(true)的对象是null,咱们一步步来修复:

1. 先修复openLearnerDataBase方法的语法错误

你现在的方法代码是:

public void openLearnerDataBase() {
    Login new LearnerDatabase().setVisible(true);
}

这行语法完全不对,根本不是正确的对象创建方式。如果是要打开LearnerDatabase窗口,直接改成这样就行:

public void openLearnerDataBase() {
    new LearnerDatabase().setVisible(true);
}

2. 解决NullPointerException的核心:确保窗口实例被初始化

你在Login类里声明了learnerDatabaseFrame、teacherDatabase这些变量,但从来没有给它们赋值(也没调用对应的set方法),所以当你调用learnerDatabaseFrame.setVisible(true)时,这个变量还是null,自然会抛出空指针异常。

方案一:直接在登录验证通过后创建新窗口(最简单,适合初学者)

这种方式不需要那些set方法和成员变量,直接在验证通过后创建对应窗口,同时隐藏当前Login窗口:
修改btnLoginActionPerformed方法里的逻辑:

private void btnLoginActionPerformed(java.awt.event.ActionEvent evt) {
    boolean parentLogin = false;
    boolean teacherLogin = false;
    boolean adminLogin = false;
    boolean learnerLogin = false;
    String username = edtUsername.getText();
    // 注意:JPasswordField的getText已过时,用这种方式获取密码更规范
    String password = new String(edtPassword.getPassword());

    //Leaner Login Details
    if (username.equals("Enzo") && password.equals("EnzoPassword")) {
        learnerLogin = true;
    }
    //Parent Login Details
    if (username.equals("Sharon") && password.equals("SharonPassword")) {
        parentLogin = true;
    }
    //Teacher Login Details
    if (username.equals("Karl") && password.equals("KarlPassword")) {
        teacherLogin = true;
    }
    //Admin Login Details
    if (username.equals("Michael") && password.equals("MichaelPassword")) {
        adminLogin = true;
    }

    if (learnerLogin) {
        new LearnerDatabase().setVisible(true);
        // 隐藏当前Login窗口
        this.setVisible(false);
    } else if (parentLogin) {
        new ParentDatabase().setVisible(true);
        this.setVisible(false);
    } else if (teacherLogin) {
        new TeacherDatabase().setVisible(true);
        this.setVisible(false);
    } else if (adminLogin) {
        // 补充Admin对应的窗口逻辑,比如new AdminDatabase().setVisible(true);
        this.setVisible(false);
    } else {
        // 可以加个错误提示,让用户知道用户名密码不对
        JOptionPane.showMessageDialog(this, "Invalid username or password!");
    }
}

方案二:提前注入窗口实例(适合需要复用窗口的场景)

如果你的项目需要保留窗口之前的操作状态(比如表格里的筛选条件),那可以在Login窗口初始化时给成员变量赋值:
修改main方法:

public static void main(String args[]) {
    // ... 之前的look and feel代码保持不变 ...
    
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            Login loginFrame = new Login();
            // 创建各个窗口实例并注入到Login窗口
            loginFrame.setLearnerDatabase(new LearnerDatabase());
            loginFrame.setTeacherDatabase(new TeacherDatabase());
            loginFrame.setParentDatabase(new ParentDatabase());
            loginFrame.setVisible(true);
        }
    });
}

然后修改你的open方法,加上隐藏当前窗口的逻辑:

public void openLearnerDataBase() {
    learnerDatabaseFrame.setVisible(true);
    this.setVisible(false);
}

public void openTeacherDatabase() {
    teacherDatabase.setVisible(true);
    this.setVisible(false);
}

public void openParentDatabase() {
    parentDatabase.setVisible(true);
    this.setVisible(false);
}

这样就不会有空指针问题了。

3. 额外的小建议

  • 尽量不要用多个独立的JFrame,后续学习可以尝试用CardLayout(在同一个窗口里切换面板)或者JDialog(模态窗口),体验会更好。
  • 如果希望关闭子窗口后回到Login窗口,可以在子窗口的构造方法里加这段代码(需要持有Login的引用):
// 比如在LearnerDatabase里
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
addWindowListener(new java.awt.event.WindowAdapter() {
    public void windowClosed(java.awt.event.WindowEvent evt) {
        loginFrame.setVisible(true);
    }
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 12:27:43