Java 如何将值从第二个控制器传递到已打开的阶段(第一个控制器)?

Java 如何将值从第二个控制器传递到已打开的阶段(第一个控制器)?,java,javafx,tableview,fxml,fxmlloader,Java,Javafx,Tableview,Fxml,Fxmlloader,我有两个控制器 FXMLDocumentController具有TableView自定义表。 NewCustomerController添加第二个控制器以添加新行。 这是我的密码 FXMLDocument.fxml 我希望在TableView中添加一行,但它不起作用。 我到底错过了什么 首先,我建议通过@kleopatra提供的链接了解控制器之间通信的概念 谈到您的实际问题,我注意到代码中存在三个问题。其中一个已由@kleopatra指定 关于您在newCustomer方法中得到的NPE,您启动

我有两个控制器

FXMLDocumentController具有TableView自定义表。 NewCustomerController添加第二个控制器以添加新行。 这是我的密码

FXMLDocument.fxml

我希望在TableView中添加一行,但它不起作用。 我到底错过了什么


首先,我建议通过@kleopatra提供的链接了解控制器之间通信的概念

谈到您的实际问题,我注意到代码中存在三个问题。其中一个已由@kleopatra指定

关于您在newCustomer方法中得到的NPE,您启动了FXMLLoader实例,但没有加载它。因此,getController为null。要解决这个问题,您需要在调用getController之前先调用load方法

public void newCustomer(ActionEvent e) throws IOException {
    String name = cNameTextField.getText();
    String stringCity = custCityTextField.getText();
    Customer customer = new Customer(10, name, stringCity);
    FXMLLoader fXMLLoader = new FXMLLoader(getClass().getResource("/mytableview/FXMLDocument.fxml"));
    fXMLLoader.load(); // YOU ARE MISSING THIS LINE
    FXMLDocumentController fXMLDocumentController = fXMLLoader.<FXMLDocumentController>getController();
    fXMLDocumentController.inflateUI(customer); // Getting NPE at this line.
}
NewCustomerController.java

最后,您只需要将CellValueFactory设置为TableColumns一次,而不是每次设置customer。您可以移动这两行来初始化方法

@Override
public void initialize(URL url, ResourceBundle rb) {
    custname.setCellValueFactory(new PropertyValueFactory<>("name"));
    city.setCellValueFactory(new PropertyValueFactory<>("city"));
}

我尝试了提供的问题链接,但它们将转到a到b控制器,而不是反向方式。不管怎样,谢谢。那你为什么不把你的问题编辑成a,删除已经确定的bug呢?b演示了剩余的问题?不管怎样,我走了。我已经提供了我能做的。但是,由于我没有对这个问题给予更多的关注,因此我一直在删除注释,这让人感到非常遗憾——它们确实包含了对潜在帮助者有用的信息:a此代码中的错误是在CustomerController.newCustomer中手动实例化一个新的主控制器,从而更新一个未使用的tableview b这是重复的其中之一是控制器之间参数传递的规范QA。非常感谢。我根据你的回答做了修改。它摆脱了NPE,但没有做任何更改。我理解他提供的链接,而且我能够从“A”到“B”进行通信,但不能在“A”已经加载的地方恢复它。那是我的问题。这让我很困惑。不以相反的方式理解。您仍在newCustomer中实例化新控制器。。。阅读答案/更新问题时要彻底!!我会一直努力直到我得到结果。另外,我想另一种方法是对所有FXML使用单一控制器。我也想试试这个。多谢各位much@kleopatra现在我对newCustomer{}方法进行了更改,删除了实例化代码,但仍然不起作用。
public class FXMLDocumentController implements Initializable {

private FXMLDocumentController documentController; //updated

@FXML
public TableView<Customer> customerTable;

@FXML
public TableColumn<Customer, String> custname;

@FXML
public TableColumn<Customer, String> city;  

@Override
public void initialize(URL url, ResourceBundle rb) { //updated
    custname.setCellValueFactory(new PropertyValueFactory<>("name"));
    city.setCellValueFactory(new PropertyValueFactory<>("city"));           
}

@FXML
private void handleButtonAction(ActionEvent event) throws IOException {
    Parent parent = FXMLLoader.load(getClass().getResource("/com/newcustomer/NewCustomer.fxml"));
    controller.setFXMLDocumentController(documentController); //updated
    Stage stage = new Stage();
    Scene scene = new Scene(parent);
    stage.setScene(scene);
    stage.show();
}

public void inflateUI(Customer customer) {
    custname.setCellValueFactory(new PropertyValueFactory<>("name"));
    city.setCellValueFactory(new PropertyValueFactory<>("city"));
    customerTable.getItems().add(customer);
}
public class NewCustomerController implements Initializable { 

 private FXMLDocumentController documentController; //updated

@FXML
private TextField cNameTextField;

@FXML
private TextField custCityTextField;

@Override
public void initialize(URL url, ResourceBundle rb) {
}
    public void setFXMLDocumentController(FXMLDocumentController fXMLDocumentController) { //updated
    this.documentController = fXMLDocumentController;
}

public void newCustomer(ActionEvent e) throws IOException {
    String name = cNameTextField.getText();
    String stringCity = custCityTextField.getText();

    Customer customer = new Customer(10, name, stringCity);
    FXMLLoader fXMLLoader = new FXMLLoader(getClass().getResource("/mytableview/FXMLDocument.fxml"));
    documentController = fXMLLoader.<FXMLDocumentController>getController(); //Newly updated
    documentController.inflateUI(customer); // Newly updated 
    }

}
public class MyTableView extends Application {

    public MyTableView() {
    }

    @Override
    public void start(Stage stage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));

        Scene scene = new Scene(root);

        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }

}
public void newCustomer(ActionEvent e) throws IOException {
    String name = cNameTextField.getText();
    String stringCity = custCityTextField.getText();
    Customer customer = new Customer(10, name, stringCity);
    FXMLLoader fXMLLoader = new FXMLLoader(getClass().getResource("/mytableview/FXMLDocument.fxml"));
    fXMLLoader.load(); // YOU ARE MISSING THIS LINE
    FXMLDocumentController fXMLDocumentController = fXMLLoader.<FXMLDocumentController>getController();
    fXMLDocumentController.inflateUI(customer); // Getting NPE at this line.
}
@FXML
private void handleButtonAction(ActionEvent event) throws IOException {
    FXMLLoader fXMLLoader = new FXMLLoader(getClass().getResource("/com/newcustomer/NewCustomer.fxml"));
    Parent parent = fXMLLoader.load();
    NewCustomerController controller = fXMLLoader.getController();
    controller.setFXMLDocumentController(this); // Pass this controller to NewCustomerController
    Stage stage = new Stage();
    Scene scene = new Scene(parent);
    stage.setScene(scene);
    stage.show();
}
private FXMLDocumentController fXMLDocumentController;

public void setFXMLDocumentController(FXMLDocumentController fXMLDocumentController) {
    this.fXMLDocumentController = fXMLDocumentController;
}

public void newCustomer(ActionEvent e) throws IOException {
    String name = cNameTextField.getText();
    String stringCity = custCityTextField.getText();
    Customer customer = new Customer(10, name, stringCity);
    fXMLDocumentController.inflateUI(customer);//You are passing to the currently loaded controller
}
@Override
public void initialize(URL url, ResourceBundle rb) {
    custname.setCellValueFactory(new PropertyValueFactory<>("name"));
    city.setCellValueFactory(new PropertyValueFactory<>("city"));
}