2 Replies Latest reply: Oct 24, 2012 6:08 AM by user536690 RSS

    NPE in initialize

    user536690
      Hi,

      After reading introduction_to_fxml I got an impression that an initialize method can be used as spring's afterPropertiesSet or EJB's a @PostConstruct method - that is expected all member variable set when it is invoked. But when I tried I got NPE. The code I tried looks like following.

      Main app:
      public class MyApp extends Application {
      
          @Override
          public void start(Stage stage) throws Exception {
              Parent root = FXMLLoader.load(getClass().getResource("/myapp.fxml"));///MAIN LOAD
      
              Scene scene = new Scene(root, 320, 240);
              scene.getStylesheets().add("/myapp.css");
              stage.setScene(scene);
              stage.setTitle("my app");
              stage.show();
          }
      
          public static void main(String[] args) { launch(); }
      }
      myapp.fxml:
      ...
      <VBox fx:id="root" xmlns:fx="http://javafx.com/fxml" >
             <ControlA>
                 <SomeClass>       
                 </SomeClass>
             </ControlA>
      </VBox>
      SomeClass.java:
      @DefaultProperty("aproperty")
      public class ControlA extends StackPane {
         private SomeClass aproperty;
      
           public ContentPane(){
              try {
                  FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/controls/ControlA.fxml"));
                  fxmlLoader.setRoot(this);
                  fxmlLoader.setController(this);
      
                  fxmlLoader.load();//ControlA LOAD
      
              } catch (IOException exception) {
                  throw new RuntimeException(exception);
              }
          }
      
          public void initialize() {
               //aproperty is null here, called from ControlA LOAD
          }
      
         //aproperty get/set
         public void setAproperty(SomeClass p){//it is called from MAIN LOAD
         ....
      }
      The component's initialize method is called from its load method and its property is being set from parent's load method which is called later. And it looks understandable, a component's property values can't be constructed until parent fxml is read. But if so, what is best practice to init a component before it will be used and after all the props were initialized?

      Best regards, Eugene.
        • 1. Re: NPE in initialize
          daniel
          Hi Eugene,

          I would perform the initialization steps that do not depend on the value of A property in initialize(), and perform the initialization steps that depend on the value of A property whenever that value is changed.

          If A is a simple bean property - that would probably mean doing part of the initialization in the setter for A. If A is an observable property, then you could register a ChangeListener (or InvalidationListener) on A in initialize - and defer the initialization/set up of everything that depends on the value of A to that listener.

          Hope this helps,

          -- daniel
          • 2. Re: NPE in initialize
            user536690
            Well, with single property using setter for initializing may work, although it's ugly. But what if there are more than one property? And initialization should be done when all are ready? I'm just want to be sure I haven't missed any other jfx-provided callbacks/tricks before adding Guice to my project ;)

            Thank you for helping!