2 Replies Latest reply: May 4, 2013 2:26 PM by 1006513 RSS

    ControllerFactory in FXMLLoader not being called when loading from uri

    1006513
      Im trying to use the setControllerFactory() method in FXMLLoader for dependency injection, but stumbled upon an issue that looks like a bug to me. The controller factory works fine when loading the fxml from an input stream, but does not get invoked when loading from an uri. I wrote a simple unit test to demonstrate the issue:
      public class FXMLLoaderTest {
      
           private FXMLLoader loader;
      
           @Test
           public void testFXMLFactory() throws IOException {
                FXMLLoader loader = new FXMLLoader();
                Callback<Class<?>, Object> callback = new Callback<Class<?>, Object>() {
                     @Override
                     public Object call(Class<?> aClass) {
                          System.out.println("Controller factory called");
                          return new String("Works");
                     }
                };
                loader.setControllerFactory(callback);
                
                // This makes the test fail
                //Object node = loader.load(getClass().getClassLoader().getResource("controllerTest.fxml"));
                
                // While this works as expected
                Object node = loader.load(getClass().getClassLoader().getResourceAsStream("controllerTest.fxml"));
      
                assertThat(loader.getController(), is(equalTo((Object) "Works")));
           }
      }
      Im using javafx 2.2 shipped with JDK 7u21. Am I missing something or should I file an issue for this?
        • 1. Re: ControllerFactory in FXMLLoader not being called when loading from uri
          James_D
          FXMLLoader.load(URL) is a static method, so your commented line
          Object node = loader.load(getClass().getClassLoader().getResource("controllerTest.fxml"));
          is equivalent to (and probably should be written as)
          Object node = FXMLLoader.load(getClass().getClassLoader().getResource("controllerTest.fxml"));
          Obviously, the static method is unaware of the controller factory you set on your FXMLLoader instance.

          To use a URL with an FXMLLoader instance, either pass the URL to the FXMLLoader constructor:
          FXMLLoader loader = new FXMLLoader(getClass().getClassLoader().getResource("controllerTest.fxml"));
          or to the setLocation(...) method:
          FXMLLoader loader = new FXMLLoader();
          loader.setLocation(getClass().getClassLoader().getResource("controllerTest.fxml"));
          and then set the controller factory as before.
          • 2. Re: ControllerFactory in FXMLLoader not being called when loading from uri
            1006513
            You're right, I guess I was looking at the code for too long... Thank you!
            Anyway, why do the static load() method have a type parameter, while all the instance methods just return objects, requiring extra casting?