我为两个窗户/舞台编写了一个控制器。 第一个窗口在MainClass中打开。如果用户点击按钮,则控制器中的第二个。 如何在applyFor()方法中从second.fxml获取TextField?
感谢。
@FXML
protected void requestNewAccount(ActionEvent event) {
try {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("second.fxml")); // TextFields in there
Parent root = (Parent) fxmlLoader.load();
Stage stage = new Stage();
stage.initModality(Modality.APPLICATION_MODAL);
stage.setTitle("Second Window");
Scene scene = new Scene(root);
String css = MainOnlineCustomer.class.getResource("/style.css").toExternalForm();
scene.getStylesheets().clear();
scene.getStylesheets().add(css);
stage.setScene(scene);
stage.show();
} catch (IOException e) {
logger.error(e);
}
}
/**
* closes the "second"-Window
* @param event
*/
@FXML
protected void cancel(ActionEvent event) {
final Node source = (Node) event.getSource();
final Stage stage = (Stage) source.getScene().getWindow();
stage.close();
}
@FXML
protected void applyFor(ActionEvent event) {
// get values from TextField in second.fxml here!!!
}
答案 0 :(得分:0)
在fxmls之间共享控制器并不好,除非它们用于相同的目的。在这里,两个fxml似乎都有不同的用途(帐户管理,登录或类似的其中一个,并为另一个创建一个新帐户)。更糟糕的是,这些类不共享相同的控制器实例,这意味着您可以从使用相同的控制器获得的小(并且可能是唯一的)益处,这里不使用。你最好使用不同的控制器。
由于您使用Modality.APPLICATION_MODAL
作为模态,因此我建议您使用showAndWait
代替show
来打开新阶段。这将进入一个嵌套的事件循环,它允许UI保持响应,并在阶段关闭后调用showAndWait
后继续。
此外,向second.fxml
的控制器添加一个方法,允许您检索结果。
这会创建一个具有给定名称和姓氏的Person
对象。
FXMLLoader loader = new FXMLLoader(getClass().getResource("second.fxml"));
Stage subStage = new Stage();
subStage.initModality(Modality.APPLICATION_MODAL);
subStage.setTitle("Second Window");
Scene scene = new Scene(loader.load());
subStage.setScene(scene);
subStage.showAndWait();
Optional<Person> result = loader.<Supplier<Optional<Person>>>getController().get();
if (result.isPresent()) {
// do something with the result
}
public class SecondController implements Supplier<Optional<Person>> {
@FXML
private TextField givenName;
@FXML
private TextField familyName;
private boolean submitted = false;
// handler for submit action
@FXML
private void submit() {
submitted = true;
givenName.getScene().getWindow().hide();
}
// handler for cancel action
@FXML
private void cancel() {
givenName.getScene().getWindow().hide();
}
@Override
public Optional<Person> get() {
return submitted ? Optional.of(new Person(givenName.getText(), familyName.getText())) : Optional.empty();
}
}
请注意,您可以通过这种方式访问控制器可用的任何数据。我不建议直接访问任何节点(例如TextField
s),因为这会更难以更改UI。
此处不需要使用Supplier
界面,但我选择这样做以实现SecondController
与主窗口之间的松散耦合。