Javafx 将登录令牌从 LoginController 传递到 CalendarController
Javafx pass login token from LoginController to CalendarController
我正在使用 Angela 的屏幕管理框架,我正在尝试编写一个非常简单的 日历应用程序。在编写 UI 和控制器并使用上述框架时,所有屏幕都会在程序启动时立即初始化。这意味着我不知道用户何时实际查看某个视图。
我需要来自服务器的 login-token(在 LoginController
中分配)来触发 CalendarController
中某种类型的更改值事件当前 运行 在后台(我想)。目前我不知道 Calendar.fxml
何时可见 and/if 用户已登录,因此我不知道如何构建我的逻辑以使函数在 [=12= 中启动] 仅 在设置 登录令牌 之后。
在这里呆了几天,如果有任何帮助,我们将不胜感激。我尝试使用 ObservableList 和 Listlistener 接口无济于事。这是我的LoginController
的相应部分。 TokenFactory 是一个 class 的静态字段和方法(主要是为了调试)。
@FXML
public boolean login() throws JSONException, UnirestException {
if(validateUsernameField() && validatePasswordField()) {
HttpResponse<JsonNode> jsonResponse = Unirest.post(TokenFactory.getSERVER_ADR())
.field("username", usernameField.getText())
.field("password", passwordField.getText())
.asJson();
if ( ((String) jsonResponse.getBody().getObject().get("message")).equalsIgnoreCase("OK")) {
String token = ((String) jsonResponse.getBody().getObject().get("token"));
//Ignore JSON to debug
TokenFactory.setToken("fakeToken123");
responseLabel.setText("Logging in...");
myController.setScreen(ScreensFramework.CalendarID);
return true;
} else {
responseLabel.setText("Wrong username or password.");
passwordField.clear();
}
} return false;
}
//Screen management
ScreensController myController;
这里有很多选择:
第一个选项:不是在启动时加载所有屏幕,而是在登录成功时只加载日历屏幕。那么你的 CalendarController
的 initialize()
方法基本上可以假定用户已登录。
第二个选项:修改框架,使其在加载控制器时return引用控制器,或者在加载后让您访问控制器。第一个版本看起来像:
public <T extends ControlledScreen> T loadScreen(String name, String resource) {
try {
FXMLLoader myLoader = new FXMLLoader(getClass().getResource(resource));
Parent loadScreen = (Parent) myLoader.load();
T myScreenControler = myLoader.getController();
myScreenControler.setScreenParent(this);
addScreen(name, loadScreen);
return myScreenControler ;
} catch (Exception e) {
System.out.println(e.getMessage());
return null;
}
}
现在,当您首次加载日历屏幕时,您可以获得对其控制器的引用:
CalendarController calendarController = screensController.loadScreen(...);
所以现在当您成功登录时,您可以调用 calendarController
上的方法。请注意 loadScreen(...)
的 return 类型已更改,因此您可能需要相应地修改其他代码。
或者,您可以在 ScreensController
中引入新地图:
public class ScreensController extends StackPane {
private Map<String, Node> screens = new HashMap<>();
private Map<String, ControlledScreen> controllers = new HashMap<>();
// ...
public boolean loadScreen(String name, String resource) {
try {
FXMLLoader myLoader = new FXMLLoader(getClass().getResource(resource));
Parent loadScreen = (Parent) myLoader.load();
ControlledScreen myScreenControler = ((ControlledScreen) myLoader.getController());
myScreenControler.setScreenParent(this);
addScreen(name, loadScreen);
// also save the controller:
controllers.put(name, myScreenControler);
return true;
} catch (Exception e) {
System.out.println(e.getMessage());
return false;
}
}
// ...
// new method to retrieve controller:
public ControlledScreen getController(String name) {
return controllers.get(name);
}
// modify the remove method to clean up the controller as well:
public boolean unloadScreen(String name) {
if (screens.remove(name) == null) {
System.out.println("Screen didn't exist");
return false;
} else {
controllers.remove(name);
return true;
}
}
}
现在当用户登录时,你可以做
CalendarController calendarController =
(CalendarController) myController.getController(ScreensFramework.CalendarID);
并在 calendarController
.
上调用您需要的任何方法
第三个选项:创建一个BooleanProperty loggedIn = new SimpleBooleanProperty();
并在用户登录时将其设置为true
。然后安排你的CalendarController
能够观察到它并在用户登录时做出反应。它改变。我不太喜欢这个选项,因为安排 CalendarController
看到 loggedIn
属性 几乎肯定会涉及该控制器和另一个 class 之间的某种额外耦合,但它是可能的。
我正在使用 Angela 的屏幕管理框架,我正在尝试编写一个非常简单的 日历应用程序。在编写 UI 和控制器并使用上述框架时,所有屏幕都会在程序启动时立即初始化。这意味着我不知道用户何时实际查看某个视图。
我需要来自服务器的 login-token(在 LoginController
中分配)来触发 CalendarController
中某种类型的更改值事件当前 运行 在后台(我想)。目前我不知道 Calendar.fxml
何时可见 and/if 用户已登录,因此我不知道如何构建我的逻辑以使函数在 [=12= 中启动] 仅 在设置 登录令牌 之后。
在这里呆了几天,如果有任何帮助,我们将不胜感激。我尝试使用 ObservableList 和 Listlistener 接口无济于事。这是我的LoginController
的相应部分。 TokenFactory 是一个 class 的静态字段和方法(主要是为了调试)。
@FXML
public boolean login() throws JSONException, UnirestException {
if(validateUsernameField() && validatePasswordField()) {
HttpResponse<JsonNode> jsonResponse = Unirest.post(TokenFactory.getSERVER_ADR())
.field("username", usernameField.getText())
.field("password", passwordField.getText())
.asJson();
if ( ((String) jsonResponse.getBody().getObject().get("message")).equalsIgnoreCase("OK")) {
String token = ((String) jsonResponse.getBody().getObject().get("token"));
//Ignore JSON to debug
TokenFactory.setToken("fakeToken123");
responseLabel.setText("Logging in...");
myController.setScreen(ScreensFramework.CalendarID);
return true;
} else {
responseLabel.setText("Wrong username or password.");
passwordField.clear();
}
} return false;
}
//Screen management
ScreensController myController;
这里有很多选择:
第一个选项:不是在启动时加载所有屏幕,而是在登录成功时只加载日历屏幕。那么你的 CalendarController
的 initialize()
方法基本上可以假定用户已登录。
第二个选项:修改框架,使其在加载控制器时return引用控制器,或者在加载后让您访问控制器。第一个版本看起来像:
public <T extends ControlledScreen> T loadScreen(String name, String resource) {
try {
FXMLLoader myLoader = new FXMLLoader(getClass().getResource(resource));
Parent loadScreen = (Parent) myLoader.load();
T myScreenControler = myLoader.getController();
myScreenControler.setScreenParent(this);
addScreen(name, loadScreen);
return myScreenControler ;
} catch (Exception e) {
System.out.println(e.getMessage());
return null;
}
}
现在,当您首次加载日历屏幕时,您可以获得对其控制器的引用:
CalendarController calendarController = screensController.loadScreen(...);
所以现在当您成功登录时,您可以调用 calendarController
上的方法。请注意 loadScreen(...)
的 return 类型已更改,因此您可能需要相应地修改其他代码。
或者,您可以在 ScreensController
中引入新地图:
public class ScreensController extends StackPane {
private Map<String, Node> screens = new HashMap<>();
private Map<String, ControlledScreen> controllers = new HashMap<>();
// ...
public boolean loadScreen(String name, String resource) {
try {
FXMLLoader myLoader = new FXMLLoader(getClass().getResource(resource));
Parent loadScreen = (Parent) myLoader.load();
ControlledScreen myScreenControler = ((ControlledScreen) myLoader.getController());
myScreenControler.setScreenParent(this);
addScreen(name, loadScreen);
// also save the controller:
controllers.put(name, myScreenControler);
return true;
} catch (Exception e) {
System.out.println(e.getMessage());
return false;
}
}
// ...
// new method to retrieve controller:
public ControlledScreen getController(String name) {
return controllers.get(name);
}
// modify the remove method to clean up the controller as well:
public boolean unloadScreen(String name) {
if (screens.remove(name) == null) {
System.out.println("Screen didn't exist");
return false;
} else {
controllers.remove(name);
return true;
}
}
}
现在当用户登录时,你可以做
CalendarController calendarController =
(CalendarController) myController.getController(ScreensFramework.CalendarID);
并在 calendarController
.
第三个选项:创建一个BooleanProperty loggedIn = new SimpleBooleanProperty();
并在用户登录时将其设置为true
。然后安排你的CalendarController
能够观察到它并在用户登录时做出反应。它改变。我不太喜欢这个选项,因为安排 CalendarController
看到 loggedIn
属性 几乎肯定会涉及该控制器和另一个 class 之间的某种额外耦合,但它是可能的。