简体   繁体   English

Java 尝试获取方法时返回 Null

[英]Java Return Null When Tried to Get Method

first of all I know this is duplicated question.首先,我知道这是重复的问题。 But I've search and tried from stackoverflow listed on Google to quora but still cant resolve my Get method still return null.但是我已经搜索并尝试了从 Google 上列出的stackoverflow到 quora 但仍然无法解决我的 Get 方法仍然返回 null。

This is my class loginModel.java under package com.hello.model 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;
  }
}

This is my loginView.java under package com.hello.view这是我在 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();
    }
  }
}

I want call my username from menuView.java under package com.hello.view after login success我想在登录成功后从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);
  }
}

As per my question when I call Get method from loginModel, messagebox return null.根据我的问题,当我从 loginModel 调用 Get 方法时,消息框返回 null。

I've tried:我试过了:

  1. Put system.out.println directly in loginModel.java , value return and call system.out.println in menuView.java at the same time but value return null.将 system.out.println 直接放到loginModel.java中,同时返回值并在menuView.java中调用 system.out.println 但返回值 Z37A6259CC0C1DDAE299A7866489。 How?如何?
  2. Send string between jframe with menu = menuView(username) in loginView.java and retrieve in menuView.java , value return null Send string between jframe with menu = menuView(username) in loginView.java and retrieve in menuView.java , value return null
  3. Using no model and create set string in loginView and call it in menuView , value return null不使用 model 并在loginView中创建设置字符串并在menuView中调用它,值返回 null

I need values that I want to use in another class/package/jframe.我需要我想在另一个类/包/jframe 中使用的值。 Am I doing wrong?我做错了吗?

I am not well versed in Swing but I can see the problem, just not the exact solution.我不太精通 Swing 但我可以看到问题,只是不是确切的解决方案。

Your code creates an instance of loginModel in both the menuView and in loginView.您的代码在 menuView 和 loginView 中创建了一个 loginModel 实例。 Then in loginView is sets the name in the instance it has, in in menuView it gets the name from its own instance.然后在 loginView 中设置它拥有的实例中的名称,在 menuView 中它从它自己的实例中获取名称。

You need to create a single instance of the model and share it between the two views.您需要创建 model 的单个实例并在两个视图之间共享它。

In a pojo way I would pass the loginModel to both "views" in a constructor.以一种 pojo 方式,我会将 loginModel 传递给构造函数中的两个“视图”。

menu = new menuView(login);

And in menuView并在 menuView

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

Your menuView instance isn't using the loginModel class that you instantiate in loginView , it's using the new one you created using new menuView() when you initialized the login variable in the menuView class.您的menuView实例未使用您在loginModel中实例化的loginView ,它使用的是您在menuView class 中初始化login变量时使用new menuView()创建的新实例。 You just need to add a setter method for the loginModel attribute in the menuView class like this:您只需要在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;
  }
}

Then call the setter in loginView.loginFunction like this:然后像这样调用loginView.loginFunction中的设置器:

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

Notice the only changes to your code are the added setLogin method on the menuView class and the call to menu.setLogin(login) in loginView.loginFunction .请注意,对代码的唯一更改是在 menuView class 上添加了setLogin方法以及在menuView中对menu.setLogin(login)loginView.loginFunction

You need to think in stages/steps.您需要分阶段/步骤进行思考。 Login is a single step, it has one of two outcomes, success or failure.登录是一个步骤,它有两种结果之一,成功或失败。

Your app needs to perform this step and take appropriate action based on the outcome of the result.您的应用需要执行此步骤并根据结果的结果采取适当的措施。

You also need to think about "separation of responsibility" - in this case, it's not really the responsibility of the loginView to perform the login operation, it just coordinates the user input.您还需要考虑“责任分离”——在这种情况下,执行登录操作loginView的真正职责,它只是协调用户输入。

The responsibility actually falls to the LoginModel责任实际上落在了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");
                }
            }
        }
    }

}

This is an overly simplified example, as the actual responsibility for performing the login should fall to the controller, which would then generate the model, but I'm getting ahead of myself.这是一个过于简化的示例,因为执行登录的实际责任应该落在 controller 身上,然后它会生成 model,但我已经超越了自己。

Because the flow of the app shouldn't be controlled/determined by the login view, the LoginView should itself be a dialog.因为应用程序的流程不应该由登录视图控制/确定,所以LoginView本身应该是一个对话框。 This way, it can be shown when you need it, it can perform what ever operations it needs and then go away, leaving the rest of the decision making up to who ever called it这样,它可以在您需要时显示,它可以执行它需要的任何操作,然后 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");
        }
    }
}

This then means you might put it together something like this...这意味着你可以把它放在一起像这样......

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

This takes you a step closer to a more decoupled solution, where you feed information to the classes when they need it, rather than the classes making decisions about what they should create/use.这使您更接近于一个更加解耦的解决方案,您可以在需要时将信息提供给类,而不是让类决定它们应该创建/使用什么。

It also moves you a step closer to re-usable classes, as they do their specific job and nothing more.它还使您更接近可重用的类,因为它们只做自己的特定工作,仅此而已。

You might find taking the time to read up on "model-view-controller" will help you better understand this approach您可能会发现花时间阅读“模型-视图-控制器”将帮助您更好地理解这种方法

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM