我使用登录页面实现javafx应用程序,并为不同用户的角色提供了几个页面。
用户识别是在Login.java类中实现的,该类应该被称为模型。 但是用户的字符串登录名和密码出现在LoginController.java文件中的页面元素中。所以现在我在控制器中提交了表单提交事件处理程序:
public class LoginController {
@FXML private TextField loginField;
@FXML private TextField passwordField;
@FXML private Button loginButton;
@FXML private Text messageText;
@FXML
protected void submitLoginForm(ActionEvent event) {
if (!Login.getInstance().authorise(loginField.getText(), passwordField.getText())) {
messageText.setText("Invalid credentials.");
}
}
这就是我在登录中所拥有的:
public class Login {
private Scene scene;
private User loggedUser;
private static Login instance;
public Login(Scene scene) {
this.scene = scene;
instance = this;
}
public static Login getInstance() {
return instance;
}
public boolean authorise(String userId, String password) {
loggedUser = User.recognize(userId, password);
if (loggedUser.equals(User.UNAUTHORISED)) {
return false;
}
goToInfoScreen();
return true;
}
User.recognize()只返回特定用户,该用户保存在上面的Login类中:
public static User recognize(String l, String p) {
return Arrays.stream(values())
.filter(user ->
user.login.equals(cryptWithMD5(l.toLowerCase().trim()))
&&
user.pass.equals(cryptWithMD5(p)))
.findFirst().orElse(UNAUTHORISED);
}
这样可行,但我不得不从控制器调用每个模型的静态实例。更重要的是,我有getInstance()方法以及公共构造函数。这对我来说很奇怪。
同样的情况是注销方法。我在Login模型类中有这个逻辑:
public void logout(){
loggedUser = null;
goToLoginScreen();
}
使用静态实例从控制器调用它:
@FXML protected void processLogout(ActionEvent event) {
Login.getInstance().logout();
}
在start()方法中,我创建了一个模型Login实例:
@Override
public void start(Stage primaryStage) throws Exception {
Scene scene = new Scene(new StackPane(), 800, 600);
Login loginManager = new Login(scene);
loginManager.goToLoginScreen();
我的问题是: 从控制器调用模型实例似乎真的好吗?或者解决这种情况的最佳做法是什么? (也许将模型实例作为控制器的构造函数参数发送?然后在start()方法中只调用控制器的方法?)
还有一点:在我的登录模型中,我识别出一个用户角色,需要根据他的角色在下一个屏幕上隐藏或显示一些元素。
所以我可能需要在我的模型中获得所需的屏幕控制器并使用这样的setter将用户发送给它?
InfoPageController controller = loader.getController();
controller.setLoggedUser(loggedUser);
然后在InfoPageController中说出类似
的内容if (loggedUser.equals(User.ADMIN)) advancedTabPane.setVisible(true);
再说一遍:这是否可以,或者还有另一种正确的方法来调整已登录用户的界面?