2013-07-19 25 views
0

我的問題是,當試圖執行我的代碼,我不斷得到我的actionListener的NullPointerException。這是我的登錄視圖。經過一些測試後,LoginView類中會發生異常。問題actionListener/actionhandler java的空指針異常

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; 
} 
} 

這裏是塔控制器及其內部類是操作處理程序

/*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) 
+5

異常堆棧跟蹤告訴你問題的確切位置。不要忽視閱讀,如果你無法理解,請發佈。這是至關重要的信息。這就是你應該開始找出問題原因的地方。 –

+2

此外,爲什麼你將'getPassword()'變爲'String'。這是出於安全原因而完成的,並且將您的應用程序推向深淵,Java開發人員正試圖從中推出應用程序。此外,在你的'LoginView'類裏寫'btnLogin.addActionListener(LoginHandlerReferenceGoesHere)'。 –

+0

我會第二個@JBNizet說的。 Stacktraces旨在幫助開發人員隔離問題。不要跳過它們!請儘可能發佈堆棧追蹤。並且,歡迎來到SO。 :) –

回答

2

堆棧跟蹤說,異常發生在這條線的LoginController構造函數:

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

在這條線上可能是空的?只有一種可能性:this.loginView

該字段已經在構造函數的參數loginView的值之前被初始化。

this.loginView = loginView; 

所以它只是意味着這個構造函數的調用者傳遞空的,而不是傳遞LoginView實例。

誰是這個構造函數的調用者?堆棧跟蹤告訴我們:se.bbs.nackademin.main.Demo.main(Demo.java:23)

所以,錯誤在那裏。類Demo的主要方法將null傳遞給構造函數LoginController。錯誤代碼位於Demo.java的第23行。

+1

+1完美解釋 –

+1

感謝您的回答,JB Nizet解決了我的問題,在我的Demo類中,我創建了一個實例loginView,但在將loginView傳入LoginController後觸發了createUI方法。 –