JavaFX 将值从子级传递到父级
JavaFX pass values from child to parent
我有一个包含一个按钮的父控制器。当我单击按钮时,它会打开新的 window 并将一些数据显示到 table 中。我用来打开 window 的代码是
Stage stage = new Stage();
FXMLLoader fxmlLoader = new FXMLLoader(
getClass().getResource("../layout/SearchCustomer.fxml"));
Parent parent = (Parent) fxmlLoader.load();
Scene scene = new Scene(parent);
stage.initModality(Modality.APPLICATION_MODAL);
stage.initOwner(parent.getScene().getWindow());
stage.setScene(scene);
stage.resizableProperty().setValue(false);
stage.showAndWait();
正常打开window。现在我需要的是,当我双击子 window 的 table 行时,它应该在父控制器文本框中设置一些值。我们如何将这个值从子控制器传递给父控制器?
在您的子控制器中公开一个 属性 并从 "parent" 控制器观察它。您的问题中确实没有足够的信息来给出准确的答案,但它看起来像:
public class ChildController {
@FXML
private TableView<Customer> customerTable ;
private final ReadOnlyObjectWrapper<Customer> currentCustomer = new ReadOnlyObjectWrapper<>();
public ReadOnlyObjectProperty<Customer> currentCustomerProperty() {
return currentCustomer.getReadOnlyProperty() ;
}
public Customer getCurrentCustomer() {
return currentCustomer.get();
}
public void initialize() {
// set up double click on table:
customerTable.setRowFactory(tv -> {
TableRow<Customer> row = new TableRow<>();
row.setOnMouseClicked(e -> {
if (row.getClickCount() == 2 && ! row.isEmpty()) {
currentCustomer.set(row.getItem());
}
}
});
}
}
然后你就这样做:
Stage stage = new Stage();
FXMLLoader fxmlLoader = new FXMLLoader(
getClass().getResource("../layout/SearchCustomer.fxml"));
Parent parent = (Parent) fxmlLoader.load();
ChildController childController = fxmlLoader.getController();
childController.currentCustomerProperty().addListener((obs, oldCustomer, newCustomer) -> {
// do whatever you need with newCustomer....
});
Scene scene = new Scene(parent);
stage.initModality(Modality.APPLICATION_MODAL);
stage.initOwner(parent.getScene().getWindow());
stage.setScene(scene);
stage.resizableProperty().setValue(false);
stage.showAndWait();
另一种方法是在子控制器中使用 Consumer
作为回调:
public class ChildController {
@FXML
private TableView<Customer> customerTable ;
private Consumer<Customer> customerSelectCallback ;
public void setCustomerSelectCallback(Consumer<Customer> callback) {
this.customerSelectCallback = callback ;
}
public void initialize() {
// set up double click on table:
customerTable.setRowFactory(tv -> {
TableRow<Customer> row = new TableRow<>();
row.setOnMouseClicked(e -> {
if (row.getClickCount() == 2 && ! row.isEmpty()) {
if (customerSelectCallback != null) {
customerSelectCallback.accept(row.getItem());
}
}
}
});
}
}
在这个版本中你可以
Stage stage = new Stage();
FXMLLoader fxmlLoader = new FXMLLoader(
getClass().getResource("../layout/SearchCustomer.fxml"));
Parent parent = (Parent) fxmlLoader.load();
ChildController childController = fxmlLoader.getController();
childController.setCustomerSelectCallback(customer -> {
// do whatever you need with customer....
});
Scene scene = new Scene(parent);
stage.initModality(Modality.APPLICATION_MODAL);
stage.initOwner(parent.getScene().getWindow());
stage.setScene(scene);
stage.resizableProperty().setValue(false);
stage.showAndWait();
在我下面的示例中,当单击保存按钮时,帐户 window (child/dialog) 将新选择的帐户名称传递回父 window。在父级 window ...
Stage nstage = new Stage();
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("Accounts.fxml"));
Parent root = (Parent) fxmlLoader.load();
AccountsController accController = fxmlLoader.getController();
accController.dialogMode(); //Call a function in acconunt windoow to preset some fields
Scene scene = new Scene(root);
nstage.setTitle("Create Company Account");
nstage.setScene(scene);
Stage stage = (Stage) src.getScene().getWindow();
nstage.initOwner(stage);
nstage.initModality(Modality.APPLICATION_MODAL);
//nstage.initStyle(StageStyle.UNDECORATED);
nstage.show();
nstage.setOnCloseRequest(new EventHandler<WindowEvent>(){
public void handle(WindowEvent we) {
txtCompany.setText( accController.lbl1.getText() );
}
});
我有一个包含一个按钮的父控制器。当我单击按钮时,它会打开新的 window 并将一些数据显示到 table 中。我用来打开 window 的代码是
Stage stage = new Stage();
FXMLLoader fxmlLoader = new FXMLLoader(
getClass().getResource("../layout/SearchCustomer.fxml"));
Parent parent = (Parent) fxmlLoader.load();
Scene scene = new Scene(parent);
stage.initModality(Modality.APPLICATION_MODAL);
stage.initOwner(parent.getScene().getWindow());
stage.setScene(scene);
stage.resizableProperty().setValue(false);
stage.showAndWait();
正常打开window。现在我需要的是,当我双击子 window 的 table 行时,它应该在父控制器文本框中设置一些值。我们如何将这个值从子控制器传递给父控制器?
在您的子控制器中公开一个 属性 并从 "parent" 控制器观察它。您的问题中确实没有足够的信息来给出准确的答案,但它看起来像:
public class ChildController {
@FXML
private TableView<Customer> customerTable ;
private final ReadOnlyObjectWrapper<Customer> currentCustomer = new ReadOnlyObjectWrapper<>();
public ReadOnlyObjectProperty<Customer> currentCustomerProperty() {
return currentCustomer.getReadOnlyProperty() ;
}
public Customer getCurrentCustomer() {
return currentCustomer.get();
}
public void initialize() {
// set up double click on table:
customerTable.setRowFactory(tv -> {
TableRow<Customer> row = new TableRow<>();
row.setOnMouseClicked(e -> {
if (row.getClickCount() == 2 && ! row.isEmpty()) {
currentCustomer.set(row.getItem());
}
}
});
}
}
然后你就这样做:
Stage stage = new Stage();
FXMLLoader fxmlLoader = new FXMLLoader(
getClass().getResource("../layout/SearchCustomer.fxml"));
Parent parent = (Parent) fxmlLoader.load();
ChildController childController = fxmlLoader.getController();
childController.currentCustomerProperty().addListener((obs, oldCustomer, newCustomer) -> {
// do whatever you need with newCustomer....
});
Scene scene = new Scene(parent);
stage.initModality(Modality.APPLICATION_MODAL);
stage.initOwner(parent.getScene().getWindow());
stage.setScene(scene);
stage.resizableProperty().setValue(false);
stage.showAndWait();
另一种方法是在子控制器中使用 Consumer
作为回调:
public class ChildController {
@FXML
private TableView<Customer> customerTable ;
private Consumer<Customer> customerSelectCallback ;
public void setCustomerSelectCallback(Consumer<Customer> callback) {
this.customerSelectCallback = callback ;
}
public void initialize() {
// set up double click on table:
customerTable.setRowFactory(tv -> {
TableRow<Customer> row = new TableRow<>();
row.setOnMouseClicked(e -> {
if (row.getClickCount() == 2 && ! row.isEmpty()) {
if (customerSelectCallback != null) {
customerSelectCallback.accept(row.getItem());
}
}
}
});
}
}
在这个版本中你可以
Stage stage = new Stage();
FXMLLoader fxmlLoader = new FXMLLoader(
getClass().getResource("../layout/SearchCustomer.fxml"));
Parent parent = (Parent) fxmlLoader.load();
ChildController childController = fxmlLoader.getController();
childController.setCustomerSelectCallback(customer -> {
// do whatever you need with customer....
});
Scene scene = new Scene(parent);
stage.initModality(Modality.APPLICATION_MODAL);
stage.initOwner(parent.getScene().getWindow());
stage.setScene(scene);
stage.resizableProperty().setValue(false);
stage.showAndWait();
在我下面的示例中,当单击保存按钮时,帐户 window (child/dialog) 将新选择的帐户名称传递回父 window。在父级 window ...
Stage nstage = new Stage();
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("Accounts.fxml"));
Parent root = (Parent) fxmlLoader.load();
AccountsController accController = fxmlLoader.getController();
accController.dialogMode(); //Call a function in acconunt windoow to preset some fields
Scene scene = new Scene(root);
nstage.setTitle("Create Company Account");
nstage.setScene(scene);
Stage stage = (Stage) src.getScene().getWindow();
nstage.initOwner(stage);
nstage.initModality(Modality.APPLICATION_MODAL);
//nstage.initStyle(StageStyle.UNDECORATED);
nstage.show();
nstage.setOnCloseRequest(new EventHandler<WindowEvent>(){
public void handle(WindowEvent we) {
txtCompany.setText( accController.lbl1.getText() );
}
});