NullPointerException 将字符串从 window 传递到另一个

NullPointerException passing a string from a window to another

长话短说,我搜索了与我的类似的问题,因此我可以解决此问题 "by my own"。我找到了这些示例 and ,但其中 none 对我有用。

我需要将在第一个 window 的 TextField 中键入的字符串传递给下一个 window。

我的主要:

public class Main extends Application{

    /**
     * @param stage
     * @throws java.lang.Exception
     */
     @Override
     public void start(Stage stage) throws Exception {

        FXMLLoader floader = new FXMLLoader();        
        Parent root = FXMLLoader.load(getClass().getResource("java1.fxml"));
        Java1Controller j1 = (Java1Controller)floader.getController();

        Scene scene = new Scene(root);

        stage.setScene(scene);
        stage.setResizable(false);
        stage.show();

    }


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

由于我使用的是 FXML,这里是 Window1 (java1) 的控制器:

    public class Java1Controller implements Initializable {

    @FXML
    private TextField tSend;
    @FXML
    private Button bSend; 


    /**
     * Initializes the controller class.
     */
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        // TODO
    }    

    @FXML
    private void sendText(ActionEvent event) throws IOException {

        FXMLLoader fLd = new FXMLLoader();       

        Parent novo = FXMLLoader.load(getClass().getResource("java2.fxml"));       

        Java2Controller j2 = (Java2Controller)fLd.getController();
        j2.setLbText(tSend.getText());

        Scene novScene = new Scene(novo);     

        Stage novStage = (Stage)((Node)(event.getSource())).getScene().getWindow();                
        novStage.setScene(novScene);
        novStage.setResizable(false);

        novStage.show();
    }  



}

Window2(java2)的控制器:

    public class Java2Controller implements Initializable {

    @FXML
    private Label lbText;
    @FXML
    private Button bOK;

    /**
     * Initializes the controller class.
     * @param url
     * @param rb
     */

    /**
     * @param string the string to set
     */
    public void setLbText(String string) {
        lbText.setText(string);
    }

    @FXML
    private void closeJPane(ActionEvent event) {

        Stage stage = (Stage)((Node)(event.getSource())).getScene().getWindow();
        stage.close();
    }

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        // TODO
    } 


}

问题指向 Java1Controller 行,我在其中使用自定义函数设置文本 (j2.setLbText)。为什么?如果重要的话,我正在使用 Netbeans 8.2 和 JavaFX Scene Builder 11.0。

FXML Java1:

<Pane maxHeight="252.0" maxWidth="388.0" minHeight="252.0" minWidth="388.0" prefHeight="252.0" prefWidth="388.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="main.Java1Controller">
   <children>
      <Label layoutX="126.0" layoutY="76.0" text="Insira texto aqui:">
         <font>
            <Font size="16.0" />
         </font>
      </Label>
      <TextField fx:id="tSend" layoutX="109.0" layoutY="102.0" />
      <Button fx:id="bSend" layoutX="169.0" layoutY="178.0" mnemonicParsing="false" onAction="#sendText" text="Send" />
   </children>
</Pane>

FXML Java2:

<Pane maxHeight="388.0" maxWidth="252.0" minHeight="252.0" minWidth="388.0" prefHeight="252.0" prefWidth="388.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="main.Java2Controller">
   <children>
      <Label fx:id="lbText" layoutX="137.0" layoutY="106.0" text="Texto enviado">
         <font>
            <Font size="16.0" />
         </font>
      </Label>
      <Button fx:id="bOK" layoutX="164.0" layoutY="178.0" mnemonicParsing="false" onAction="#closeJPane" prefHeight="26.0" prefWidth="61.0" text="OK" />
   </children>
</Pane>

您正在使用 static load 方法加载 fxml。这样,一个新的 FXMLLoader 实例将通过您无法获得引用的方法创建。您自己创建的 FXMLLoader 实例永远不会用于加载 fxml 文件,因此无法通过其 getController 属性:

使用控制器
// here you create a loader without setting a location
FXMLLoader fLd = new FXMLLoader();       
// here a static method uses another loader instance to load the fxml
Parent novo = FXMLLoader.load(getClass().getResource("java2.fxml"));       
// here you try to retrieve the controller from the loader instance that is still in the same state as after the constructor completion
Java2Controller j2 = (Java2Controller)fLd.getController();

更改您的代码并使用您自己创建的加载程序实例来加载 fxml:

// create loader with location set
FXMLLoader fLd = new FXMLLoader(getClass().getResource("java2.fxml"));

// use loader instance to load fxml from location specified
Parent novo = fLd.load();

// the controller should now be available
Java2Controller j2 = (Java2Controller)fLd.getController();

assert j2 != null