JavaFX将值从子级传递给父级

时间:2015-12-06 13:38:51

标签: java-8 javafx-2 fxml

我有一个包含一个按钮的父控制器。当我点击按钮时,它打开新窗口并将一些数据显示在表格中。我用于打开窗口的代码是

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

正确打开窗口。现在我需要的是,当我双击子窗口的表行时,它应该在父控制器文本框中设置一些值。我们如何将这个值从子控制器传递给父控制器?

2 个答案:

答案 0 :(得分:6)

在子控制器中显示属性,并从“父”控制器中观察它。你的问题中没有足够的信息来给出准确的答案,但它看起来像是:

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

答案 1 :(得分:0)

在下面的示例中,单击“保存”按钮时,帐户窗口(子帐户/对话框)会将新选择的帐户名称传递回父窗口。在父窗口上...

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

                });