3 Replies Latest reply: Apr 30, 2012 10:51 AM by 885691 RSS

    New stage with data passed to it

    934066
      I have been trying for a day to do what seemed like an easy thing. I 'm opening a .fxml stage containing a button to open a second .fxml stage. I can open the stage, even have a form on that stage add data and save that data to a back end db no problem. However when I try to populate textfields in the new stage the @FMXL bound variables are all null.

      This is the new stage backing controller

      public class NewFXML implements Initializable {

      @FXML
      private TextField myTextField;

      public void view(String data){
      try {
      Stage stage = new Stage();
      Parent root = FXMLLoader.load(getClass().getResource("NewFXML.fxml"));

      stage.setScene(new Scene(root));
      stage.show();
      //my textfield is null -- why?
      myTextField.setText(data);
      } catch (IOException ex) {
      Logger.getLogger(NewFXML.class.getName()).log(Level.SEVERE, null, ex);
      }
      }

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

      and the fxml for the page.
      <AnchorPane id="AnchorPane" prefHeight="200.0" prefWidth="320.0" xmlns:fx="http://javafx.com/fxml" fx:controller="testdatapass.NewFXML">
      <children>
      <TextField fx:id="myTextField" layoutX="88.0" layoutY="35.0" prefHeight="22.0" prefWidth="205.0" />
      <Label id="label1" layoutX="31.0" layoutY="38.0" text="My Field" />
      </children>
      </AnchorPane>

      On the opening stage the button calls the view(String data) method. like so
      public class Sample implements Initializable {

      private NewFXML newFXML = new NewFXML();

      @FXML
      private void handleButtonAction(ActionEvent event) {
      newFXML.view("My text to display");
      }

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

      Where am I going wrong?
        • 1. Re: New stage with data passed to it
          885691
          The problem is this line:
          private NewFXML newFXML = new NewFXML();
          In general, you don't need to create the controller yourself - FXMLLoader creates it for you. Try using one of the load() methods defined by FXMLLoader to load your content instead. FXMLLoader will automatically inject your annotated member fields and call initialize() for you.

          Hope this helps,
          Greg
          • 2. Re: New stage with data passed to it
            934066
            Thanks Greg, I had worked that out just before your very helpful reply I have changed the button listener method (seems a bit long winded) to the following which has worked.
            @FXML
            private void handleButtonAction(ActionEvent event) {
            try {
            Stage stage = new Stage();
            //Parent root = FXMLLoader.load(getClass().getResource("NewFXML.fxml"));
            //Parent root = FXMLLoader.load(getClass().getResource("NewFXML.fxml"),null,null,new Callback<Class<?>, Object>);

            URL location = getClass().getResource("NewFXML.fxml");
            FXMLLoader fxmlLoader = new FXMLLoader();
            fxmlLoader.setLocation(location);
            fxmlLoader.setBuilderFactory(new JavaFXBuilderFactory());

            Parent root = (Parent) fxmlLoader.load(location.openStream());
            stage.setScene(new Scene(root));
            stage.show();
            NewFXML newFXML = (NewFXML)fxmlLoader.getController();
            newFXML.view("my string at last");
            } catch (IOException ex) {
            Logger.getLogger(Sample.class.getName()).log(Level.SEVERE, null, ex);
            }

            }

            Back to the real project now.
            • 3. Re: New stage with data passed to it
              885691
              You are correct - your handler code is a bit longer than it needs to be. If you are using JavaFX 2.1, instead of this:
              URL location = getClass().getResource("NewFXML.fxml");
              FXMLLoader fxmlLoader = new FXMLLoader();
              fxmlLoader.setLocation(location);
              fxmlLoader.setBuilderFactory(new JavaFXBuilderFactory());
              
              Parent root = (Parent) fxmlLoader.load(location.openStream());
              stage.setScene(new Scene(root));
              you can just do this:
              FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("NewFXML.fxml"));
              stage.setScene(new Scene((Parent)fxmlLoader.load()));