actionListener/actionhandler java NullPointerException问题

actionListener/actionhandler java NullPointerException问题,java,swing,nullpointerexception,actionlistener,Java,Swing,Nullpointerexception,Actionlistener,我的问题是,当试图执行代码时,我的actionListener上不断出现NullPointerException。这是我的登录视图。在一些测试之后,LoginView类中发生异常 public class LoginView extends JDialog { private static final long serialVersionUID = 1L; private JTextField tfUsername; private JPasswordField pfPassword; pri

我的问题是,当试图执行代码时,我的actionListener上不断出现NullPointerException。这是我的登录视图。在一些测试之后,LoginView类中发生异常

public class LoginView extends JDialog {

private static final long serialVersionUID = 1L;
private JTextField tfUsername;
private JPasswordField pfPassword;
private JLabel lbUsername;
private JLabel lbPassword;
private JButton btnLogin;
private JButton btnCancel;
private boolean succeeded;

/*public LoginView(Frame parent) {

    super(parent, "Login", true);
    setLocationRelativeTo(parent);
}*/

public void createUI(){

    JPanel panel = new JPanel(new GridBagLayout());
    GridBagConstraints cs = new GridBagConstraints();

    cs.fill = GridBagConstraints.HORIZONTAL;

    lbUsername = new JLabel("Username: ");
    cs.gridx = 0;
    cs.gridy = 0;
    cs.gridwidth = 1;
    panel.add(lbUsername, cs);

    tfUsername = new JTextField(20);
    cs.gridx = 1;
    cs.gridy = 0;
    cs.gridwidth = 2;
    panel.add(tfUsername, cs);

    lbPassword = new JLabel("Password: ");
    cs.gridx = 0;
    cs.gridy = 1;
    cs.gridwidth = 1;
    panel.add(lbPassword, cs);

    pfPassword = new JPasswordField(20);
    cs.gridx = 1;
    cs.gridy = 1;
    cs.gridwidth = 2;
    panel.add(pfPassword, cs);
    panel.setBorder(new LineBorder(Color.GRAY));

    btnLogin = new JButton("Login");
    btnLogin.addActionListener(new ActionListener(){


        public void actionPerformed(ActionEvent e) {
            System.out.println("Login in button is pushed ");

        }

    });

    btnCancel = new JButton("Cancel");
    /*btnCancel.addActionListener(new ActionListener() {

        public void actionPerformed(ActionEvent e) {
            dispose();
        }
    });*/
    JPanel bp = new JPanel();
    bp.add(btnLogin);
    bp.add(btnCancel);

    getContentPane().add(panel, BorderLayout.CENTER);
    getContentPane().add(bp, BorderLayout.PAGE_END);



    pack();
    setResizable(false);


}

//action listener will be handle in LoginController
public void addLoginListener(ActionListener listenForLoginButton){

    btnLogin.addActionListener(listenForLoginButton); //error occurs here

}

public void addCancelListener(ActionListener listenForCancelButton){

    btnLogin.addActionListener(listenForCancelButton);// and here

}

//return user-name
public String getUsername() {
    return tfUsername.getText().trim();
}

//return password
public String getPassword() {
    return new String(pfPassword.getPassword());
}

public boolean isSucceeded() {
    return succeeded;
}
}
下面是tha控制器及其内部类,即动作处理程序

/*The LoginController class handles the logic behind login validation and and 
 * error handling connected to login*/
public class LoginController{
@SuppressWarnings("unused")
private DatabaseConnection databaseConnection; //not using yet
private LoginView loginView;


/*the constructor two parameters databaseConnection and loginView
 * true to are MVC frameworke*/ 
public LoginController(DatabaseConnection databaseConnection, LoginView loginView){

    this.databaseConnection = databaseConnection;
    this.loginView = loginView;



    this.loginView.addLoginListener(new LoginHandler());
    this.loginView.addCancelListener(new LoginHandler());
}

public boolean authenticate(String username, String password) {
    /* hard-coded user-name and password, because we know what the 
     * user-name and password is*/

    if (username.equals("bob") && password.equals("secret")) {

        return true;

    }

    return false;
}



/***********************/
/*****Inner class*******/
/***********************/

class LoginHandler implements ActionListener{

    //an empty constructor
    public LoginHandler(){

    }

    public void actionPerformed(ActionEvent e) {

        //this switch will only handle 2 events, login is pushed or cancel is pushed
        switch(e.getActionCommand()){

        case "btnLogin":

            System.out.println("Login in button is pushed ");

            break;

        case "btnCancel":

            System.out.println("cancel in button is pushed ");

            break;


        }
    }
}

/***********************/
/****end inner class****/
/***********************/

}//end class
错误呢

Exception in thread "main" java.lang.NullPointerException
at se.bbs.nackademin.views.LoginView.addLoginListener(LoginView.java:94)
at se.bbs.nackademin.controllers.LoginController.<init>(LoginController.java:30)
at se.bbs.nackademin.main.Demo.main(Demo.java:23)
线程“main”java.lang.NullPointerException中的异常 在se.bbs.nackademin.views.LoginView.addLoginListener上(LoginView.java:94) 在se.bbs.nackademin.controllers.LoginController.(LoginController.java:30) 在se.bbs.nackademin.main.Demo.main(Demo.java:23)
堆栈跟踪显示LoginController构造函数的此行发生异常:

this.loginView.addLoginListener(new LoginHandler());
在这一行什么可能是空的?只有一种可能性:
this.loginView

此字段之前已使用构造函数的
loginView
参数值初始化

this.loginView = loginView;
因此,它只是意味着该构造函数的调用方传递null,而不是传递
LoginView
实例

谁是此构造函数的调用方?堆栈跟踪告诉我们:
se.bbs.nackademin.main.Demo.main(Demo.java:23)


所以,bug就在那里。类
Demo
的主方法将null传递给
LoginController
的构造函数。错误代码位于
Demo.java

中的第23行,异常堆栈跟踪会准确地告诉您问题所在。别忘了读它,如果你不懂,就把它贴出来。这是至关重要的信息。这就是您应该开始查找问题原因的地方。此外,您为什么要将使用
getPassword()
获得的内容更改为
String
。这样做是出于安全原因,您将应用程序推向了深渊,Java开发人员正试图从中走出一个深渊。此外,在
LoginView
类中编写
btnLogin.addActionListener(loginHandlerReferenceGoesher)
。我会支持@JBNizet所说的。Stacktraces旨在帮助开发人员隔离问题。不要跳过它们!请尽可能地张贴跟踪信息。还有,欢迎来到SO.:)sry,刚刚添加了StackTrace,但我看不出您在哪里调用createGUI-也许您根本忘了调用它?然后btnLogin/btnCancel仍然为空..感谢您的回答,JB Nizet解决了我的问题,在我的演示类中,我创建了一个实例loginView,但在将loginView传递到LoginController后触发createUI方法。