2015-12-06 2 views
1

У меня есть один родительский контроллер, который содержит одну кнопку. Когда я нажимаю кнопку, он открывает новое окно и отображает некоторые данные в таблице. Код, который я использовал для открытия окна, -JavaFX передает значения от дочернего к родительскому

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

Он правильно открывает окно. Теперь мне нужно, когда я дважды нажимаю на строку таблицы дочернего окна, она должна установить некоторое значение в текстовом поле родительского контроллера. Как передать это значение из дочернего контроллера в родительский контроллер?

ответ

4

Вывести объект в своем дочернем контроллере и наблюдать за ним из «родительского» контроллера. Существует не действительно достаточно информации в вашем вопросе, чтобы дать точный ответ, но это будет выглядеть примерно так:

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(); 
Смежные вопросы