为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

繁星淼淼 2023-09-20 17:08:55
我有两个控制器FXMLDocumentController有TableView客户表。NewCustomerController第二个控制器添加新行。这是我的代码FXML文档.fxml<AnchorPane id="AnchorPane" prefHeight="283.0" prefWidth="437.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="mytableview.FXMLDocumentController">    <children>        <Button fx:id="button" layoutX="309.0" layoutY="25.0" onAction="#handleButtonAction" text="New Customer" />      <TableView fx:id="customerTable" layoutX="6.0" layoutY="61.0" prefHeight="215.0" prefWidth="426.0">        <columns>          <TableColumn fx:id="custname" prefWidth="75.0" text="Customer Name" />          <TableColumn fx:id="city" prefWidth="75.0" text="City" />        </columns>         <columnResizePolicy>            <TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />         </columnResizePolicy>      </TableView>    </children></AnchorPane>  新客户.fxml<AnchorPane id="AnchorPane" prefHeight="172.0" prefWidth="209.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.171" fx:controller="com.newcustomer.NewCustomerController">   <children>      <Button layoutX="141.0" layoutY="129.0" mnemonicParsing="false" onAction="#newCustomer" text="Add" />      <TextField fx:id="cNameTextField" layoutX="14.0" layoutY="26.0" promptText="Customer Name" />      <TextField fx:id="custCityTextField" layoutX="14.0" layoutY="77.0" promptText="City" />   </children></AnchorPane>FXMLDocumentController.javapublic class FXMLDocumentController implements Initializable {private FXMLDocumentController documentController; //updated@FXMLpublic TableView<Customer> customerTable;@FXMLpublic TableColumn<Customer, String> custname;@FXMLpublic TableColumn<Customer, String> city;  @Overridepublic void initialize(URL url, ResourceBundle rb) { //updated    custname.setCellValueFactory(new PropertyValueFactory<>("name"));    city.setCellValueFactory(new PropertyValueFactory<>("city"));           }
查看完整描述

1 回答

?
人到中年有点甜

TA贡献1895条经验 获得超7个赞

谈到您的实际问题,我注意到您的代码中存在三个问题。


关于您在 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.

}

然而,上述修复是无用的,因为您正在创建一个未被使用的 FXMLDocumentController 的新实例(如 @kleopatra 指定的)。您必须实际传递要与之通信的控制器实例。您需要在 NewCustomerController 中创建该控制器的实例变量并设置它。


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

}

NewCustomerController.java


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

}

最后,您只需将 CellValueFactory 设置到 TableColumns 一次,而不是每次设置客户时。您可以将这两行移动到initialize() 方法。


@Override

public void initialize(URL url, ResourceBundle rb) {

    custname.setCellValueFactory(new PropertyValueFactory<>("name"));

    city.setCellValueFactory(new PropertyValueFactory<>("city"));

}


查看完整回答
反对 回复 2023-09-20
  • 1 回答
  • 0 关注
  • 73 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信