JavaFX 2.0 + FXML. Updating scene values from a different Task

11,656

1) You can get the controller from the FXMLLoader but don't know is it possible from Scene :

FXMLLoader fxmlLoader = new FXMLLoader();
Pane p = fxmlLoader.load(getClass().getResource("foo.fxml").openStream());
bar.foo fooController = (bar.foo) fxmlLoader.getController();

To use the fooController later in a different part of your code, you can use Node#setUserData(). For example after the code above:

p.setUserData(fooController);
...
// after a while of app logic and code
bar.foo controller_of_p = (bar.foo) p.getUserData();

This gives a workaround and a shortcut to achieve your goal.

2) If your node has an id then you can directly Node#lookup() it rather than constructing a for-loop :

TextField txt = (TextField) pane.lookup("#nodeId");
Share:
11,656
Javier
Author by

Javier

Updated on June 21, 2022

Comments

  • Javier
    Javier almost 2 years

    I want to get the controller from a scene that i've loaded with FXMLoader. The use case is:

    1. My JSON manager receives a JSON object
    2. The task I've launched shows a new Scene using

      Parent p = FXMLLoader.load(getClass().getResource("foo.fxml"));
      Scene scene = new Scene(p);
      stage.setScene(scene);
      

      After that, i have the empty scene.

    3. Now I do this to fill the components

      AnchorPane pane = (AnchorPane)((AnchorPane) scene.getRoot()).getChildren().get(0);
      for(Node node : pane.getChildren()){
          String id = node.getId();
          if(id.equals(NAME)){
               ((TextField)node).setText(value);
          }
      }
      

    My question, is there an easier way to do this? I have a controller specified in FXML

    <AnchorPane id="AnchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="526.0" minWidth="356.0" prefHeight="526.0" prefWidth="356.0" 
    xmlns:fx="http://javafx.com/fxml" fx:controller="bar.foo">
    

    I want to get the instance with the bind values (TextField called name in this case)

    Thanks in advance

  • Javier
    Javier about 12 years
    Thanks for your answer, it was a point using node.lookup. The way you show to get the controller doesn't works for me because I need the current controller instance. This way creates a new controller and a new pane.
  • Sergey Grinev
    Sergey Grinev about 12 years
    why? Use this code instead of FXMLLoader.load(getClass().getResource("foo.fxml")); and you will get the same pane as in your code.
  • Uluk Biy
    Uluk Biy about 12 years
    @Javier. Updated the answer. Please have a look.
  • Javier
    Javier about 12 years
    That's exactly what I'm looking for Uluk Bly, thanks!. @Sergey: If you use loader.getResource(...) different times, each time the controller instance will be different.
  • Sergey Grinev
    Sergey Grinev about 12 years
    @Javier, i've looked into history and nobody suggested doing that. But nvm as you got your problem solved. :)