controller.Java
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;
public class Controller {
public TextField txtField;
public PasswordField passField;
public Button btn;
public Label access;
private String USNM = "crimsoncoder";
private String PASS = "toor";
▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬问题从这里开始▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
private String usnm = txtField.getText();
private String pass = passField.getText();
private String acc = access.getText();
private final String ACCESS_GRANTED = "/ACCESS_GRANTED/";
private final String ACCESS_DENIED = "|/?ACCESS_DENIED?/|";
public void onClick() {
if (usnm.equals(USNM)) {
if (pass.equals(PASS)) {
acc = ACCESS_GRANTED;
} else {
acc = ACCESS_DENIED;
}
} else {
acc = ACCESS_DENIED;
}
}
}
在Controller.java中声明getText()
,setText()
和toString()
变量后,调用方法usnm
,pass
和acc
返回NullPointerException
。知道为什么会这样吗?
新守则:
public class Controller {
@FXML
private TextField txtField;
@FXML
private PasswordField passField;
@FXML
private Button btn;
@FXML
private Label access;
private String USNM = "crimsoncoder";
private String PASS = "toor";
private static final String ACCESS_GRANTED = "/ACCESS_GRANTED/";
private static final String ACCESS_DENIED = "|/?ACCESS_DENIED?/|";
public void onClick() {
String usnm = txtField.getText();
String pass = passField.getText();
if (usnm.equals(USNM)) {
if (pass.equals(PASS)) {
access.setText(ACCESS_GRANTED);
} else {
access.setText(ACCESS_DENIED);
}
} else {
access.setText(ACCESS_DENIED);
}
}
}
这里的设计实际上存在很多问题。首先,您试图在场景中实际存在这些控件之前访问txtField
和passField
控件的值。
使用JavaFX和FXML,这些控件不会构建(或注入)并且可用于控制器,直到场景初始化为止。
控件引用也应该是private
并使用@FXML
关键字注释,如下所示:
@FXML
private TextField txtField;
这基本上告诉Java,TextField
已经在相关的FXML文档中定义。
并且您需要在单击LOGIN
按钮后获取用户名和密码字段的值,因此请更新您的onClick()
方法以检索当时的值:
public void onClick() {
String usnm = txtField.getText();
String pass = passField.getText();
String acc;
if (usnm.equals(USNM)) {
if (pass.equals(PASS)) {
acc = ACCESS_GRANTED;
} else {
acc = ACCESS_DENIED;
}
} else {
acc = ACCESS_DENIED;
}
System.out.println(acc);
}
所以,对于更好的Controller.java
,你可以使用这样的东西:
public class Controller {
@FXML
public TextField txtField;
@FXML
public PasswordField passField;
@FXML
public Button btn;
@FXML
public Label access;
private String USNM = "crimsoncoder";
private String PASS = "toor";
private static final String ACCESS_GRANTED = "/ACCESS_GRANTED/";
private static final String ACCESS_DENIED = "|/?ACCESS_DENIED?/|";
public void onClick() {
String usnm = txtField.getText();
String pass = passField.getText();
String acc;
if (usnm.equals(USNM)) {
if (pass.equals(PASS)) {
acc = ACCESS_GRANTED;
} else {
acc = ACCESS_DENIED;
}
} else {
acc = ACCESS_DENIED;
}
System.out.println(acc);
}
}
我建议你不要使用实例变量,而是使用局部变量。换句话说,以这种方式重写您的方法:
public void onClick(){
String usnm = txtField.getText();
String pass = passField.getText();
...
}
希望这会有所帮助。
附:看起来ACCESS_GRANTED
和ACCESS_DENIED
应该是常量,所以为它们添加静态标识符。
这是因为当类控制器初始化时,它是来自另一个实例变量的init实例变量的托盘,它是null。我的主张是这一举动
private String usnm = txtField.getText();
private String pass = passField.getText();
private String acc = access.getText();
当某人填充此字段时触发的方法,并让create instance变量为null。
恩。
private String usnm
private String pass
private String acc
但:
我看到你尝试像MVC那样做 - 我认为你做错了 - 读一下这个模式。