JavaFX pass values from child to parent

后端 未结 2 1695
后悔当初
后悔当初 2020-12-06 04:00

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

2条回答
  •  甜味超标
    2020-12-06 04:21

    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 customerTable ;
    
        private final ReadOnlyObjectWrapper currentCustomer = new ReadOnlyObjectWrapper<>();
    
        public ReadOnlyObjectProperty currentCustomerProperty() {
            return currentCustomer.getReadOnlyProperty() ;
        }
    
        public Customer getCurrentCustomer() {
            return currentCustomer.get();
        }
    
        public void initialize() {
            // set up double click on table:
    
            customerTable.setRowFactory(tv -> {
                TableRow 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 customerTable ;
    
        private Consumer customerSelectCallback ;
    
        public void setCustomerSelectCallback(Consumer callback) {
            this.customerSelectCallback = callback ;
        }
    
        public void initialize() {
            // set up double click on table:
    
            customerTable.setRowFactory(tv -> {
                TableRow 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();
    

提交回复
热议问题