Reputation: 1984
I have one parent controller which contain one button. When I click on button it open new window and show some data into table. The code I have used for opening window is
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();
It opens window properly. Now what I need is, when I double click on the row of table of the child window, It should set some value in parent controller textbox. How would we pass this value from child controller to parent controller?
Upvotes: 3
Views: 6357
Reputation: 421
In my example below, the account window (child/dialog) passes the newly selected account name back to the parent window when the save button is clicked. On the parent 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() );
}
});
Upvotes: 0
Reputation: 209225
Expose a property in your child controller and observe it from the "parent" controller. There isn't really enough information in your question to give a precise answer, but it would look something like:
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());
}
}
});
}
}
and then you just do:
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();
An alternative approach is to use a Consumer
as a callback in the child controller:
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());
}
}
}
});
}
}
And in this version you do
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();
Upvotes: 12