簡體   English   中英

Java 嘗試獲取方法時返回 Null

[英]Java Return Null When Tried to Get Method

首先,我知道這是重復的問題。 但是我已經搜索並嘗試了從 Google 上列出的stackoverflow到 quora 但仍然無法解決我的 Get 方法仍然返回 null。

This is my class loginModel.java under package com.hello.model

public class loginModel {
  public String username;

  public void setUsername(String username) {
      this.username = username;
  }

  public String getUsername() {
      return this.username;
  }
}

這是我在 package com.hello.view下的 loginView.java

import com.hello.model.loginModel;

public class loginView extends javax.swing.JFrame {
  loginModel login = new loginModel();

  public loginView() {
      initComponents();
      this.setLocationRelativeTo(null);
      loginFunction();
  }

  private void loginFunction(){
    String username = usernameText.getText();
    String password = passwdText.getText();
    String query = "select * from access where username = '" +username+ "' AND password = '" +password+"'";
    databaseConnect db = new databaseConnect();

    try (Connection con = DriverManager.getConnection(db.url, db.user, db.password);
        Statement st = con.createStatement();
        ResultSet rs = st.executeQuery(query)) {

        if(rs.next()) {
            if(username.equals(rs.getString("username")) && password.equals(rs.getString("password"))){
                JOptionPane.showMessageDialog(null, "login Success");
                String name = rs.getString("name");
                String privilege = rs.getString("privilege");
                login.setUsername(name);

                menu = new menuView();
                menu.setVisible(true);
                this.setVisible(false);
            }
        } else {
                JOptionPane.showMessageDialog(null, "username or password incorrect");
            }
    } catch (SQLException e) {
        System.err.format("SQL State: %s\n%s", e.getSQLState(), e.getMessage());

    } catch (Exception e) {
        e.printStackTrace();
    }
  }
}

我想在登錄成功后從package com.hello.view下的 menuView.java 調用我的用戶名

import com.hello.model.loginModel;
import com.hello.view.loginView;

public class menuView extends javax.swing.JFrame {    
  private String username;
  loginModel login = new loginModel();

  public menuView() {
    initComponents();
    this.setLocationRelativeTo(null);
    initMenu();
  }

  private void initMenu(){
    username = login.getUsername();
    JOptionPane.showMessageDialog(this, username);
  }
}

根據我的問題,當我從 loginModel 調用 Get 方法時,消息框返回 null。

我試過了:

  1. 將 system.out.println 直接放到loginModel.java中,同時返回值並在menuView.java中調用 system.out.println 但返回值 Z37A6259CC0C1DDAE299A7866489。 如何?
  2. Send string between jframe with menu = menuView(username) in loginView.java and retrieve in menuView.java , value return null
  3. 不使用 model 並在loginView中創建設置字符串並在menuView中調用它,值返回 null

我需要我想在另一個類/包/jframe 中使用的值。 我做錯了嗎?

我不太精通 Swing 但我可以看到問題,只是不是確切的解決方案。

您的代碼在 menuView 和 loginView 中創建了一個 loginModel 實例。 然后在 loginView 中設置它擁有的實例中的名稱,在 menuView 中它從它自己的實例中獲取名稱。

您需要創建 model 的單個實例並在兩個視圖之間共享它。

以一種 pojo 方式,我會將 loginModel 傳遞給構造函數中的兩個“視圖”。

menu = new menuView(login);

並在 menuView

public menuView(loginModel login) {
    this.login = login;
}

您的menuView實例未使用您在loginModel中實例化的loginView ,它使用的是您在menuView class 中初始化login變量時使用new menuView()創建的新實例。 您只需要在menuView class 中為loginModel屬性添加一個 setter 方法,如下所示:

import com.hello.model.loginModel;
import com.hello.view.loginView;

public class menuView extends javax.swing.JFrame {    
  private String username;
  loginModel login = new loginModel();

  public menuView() {
    initComponents();
    this.setLocationRelativeTo(null);
    initMenu();
  }

  private void initMenu(){
    username = login.getUsername();
    JOptionPane.showMessageDialog(this, username);
  }

  public void setLogin(loginModel loginModel) {
    this.login = loginModel;
  }
}

然后像這樣調用loginView.loginFunction中的設置器:

... code before
 login.setUsername(name);
 menu = new menuView();
 menu.setLogin(login);
 menu.setVisible(true);
 this.setVisible(false);
... code after

請注意,對代碼的唯一更改是在 menuView class 上添加了setLogin方法以及在menuView中對menu.setLogin(login)loginView.loginFunction

您需要分階段/步驟進行思考。 登錄是一個步驟,它有兩種結果之一,成功或失敗。

您的應用需要執行此步驟並根據結果的結果采取適當的措施。

您還需要考慮“責任分離”——在這種情況下,執行登錄操作loginView的真正職責,它只是協調用戶輸入。

責任實際上落在了LoginModel

// Just a custom exception to make it easier to determine 
// what actually went wrong
public class LoginException extends Exception {

    public LoginException(String message) {
        super(message);
    }

}

// LoginModel ... that "does" stuff
public class LoginModel {

    private String username;
    DatabaseConnect db;

    public LoginModel(DatabaseConnect db) {
        this.db = db;
    }

    // I would consider not doing this.  You need to ask what reasons would
    // the app need this information and expose it only if there is really a 
    // reason to do so
    public String getUsername() {
        return username;
    }

    public boolean isLogedIn() {
        return username != null;
    }

    public void validate(String username, String password) throws SQLException, LoginException {

        String query = "select * from access where username = ? AND password = ?";

        try ( Connection con = DriverManager.getConnection(db.url, db.user, db.password);  PreparedStatement st = con.prepareStatement(query)) {
            st.setString(1, username);
            st.setString(2, password);

            try ( ResultSet rs = st.executeQuery()) {
                if (rs.next()) {
                    this.username = username;
                } else {
                    throw new LoginException("Invalid user credentials");
                }
            }
        }
    }

}

這是一個過於簡化的示例,因為執行登錄的實際責任應該落在 controller 身上,然后它會生成 model,但我已經超越了自己。

因為應用程序的流程不應該由登錄視圖控制/確定,所以LoginView本身應該是一個對話框。 這樣,它可以在您需要時顯示,它可以執行它需要的任何操作,然后 go 離開,將決策的 rest 留給曾經調用它的人

public class LoginView extends javax.swing.JDialog {

    private LoginModel model;

    public LoginView(LoginModel model) {
        initComponents();
        setModal(true);
        this.model = model;
        this.setLocationRelativeTo(null);
    }

    // This will get executed when the user taps some kind of "perform login button"
    private void loginFunction() {
        String username = usernameText.getText();
        String password = passwdText.getText();

        try {
            model.validate(username, password);
            dispose()
        } catch (SQLException ex) {
            // This should probably be considered a fatal error
            model = null;
            dispose();
        } catch (LoginException ex) {
            JOptionPane.showMessageDialog(this, "Login vaild");
        }
    }
}

這意味着你可以把它放在一起像這樣......

DatabaseConnect db = new DatabaseConnect();
LoginModel model = new LoginModel(db);

LoginView loginView = new LoginView(model);
// Because we're using a modal dialog, the code execution will wait here
// till the window is disposed/closed
loginView.setVisible(true);

if (loginView.model != null) {
    // model is now valid and can continue to be used
    // in what ever fashion you need
} else {
    JOptionPane.showMessageDialog(null, "Fatal Error");
}

這使您更接近於一個更加解耦的解決方案,您可以在需要時將信息提供給類,而不是讓類決定它們應該創建/使用什么。

它還使您更接近可重用的類,因為它們只做自己的特定工作,僅此而已。

您可能會發現花時間閱讀“模型-視圖-控制器”將幫助您更好地理解這種方法

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM