JavaFX pass values from child to parent

谁都会走 提交于 2019-11-26 21:04:42

问题


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?


回答1:


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();



回答2:


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() );
                    }

                });


来源:https://stackoverflow.com/questions/34118025/javafx-pass-values-from-child-to-parent

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!