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