2013-10-03 87 views
4

我一直在试验FXMLLoader并使用setControllerFactory方法使用自定义Callback<P,R>实现。JavaFX自定义控制器工厂

The ORACLE documentation说以下内容:

的实现可以返回一个空值,表明它 或无法创建给定类型的控制装置;在这种情况下, 加载程序将采用 默认控制器构建机制。

我想达到的结果是,我可以使用依赖注入框架来创建需要参数的任何控制器,但我会让FXMLLoader负载不需要任何参数控制器。

所以,如果我有使用ViewController类不接受任何参数,下面这个简单的FXML文件...

<StackPane fx:id="pane" 
      xmlns:fx="http://javafx.com/fxml" 
      fx:controller="my.package.ViewController"> 
</StackPane> 

我用下面这个简单的控制器工厂实现来通知我想要的FXMLLoader调用load()方法我的初始化方法后,管理在这种情况下控制器的建设...

loader.setControllerFactory(new Callback<Class<?>, Object>(){ 
    @Override 
    public Object Call(Class<?> type) { 
     return null; // Let the FXMLLoader handle construction... 
    } 
}); 

ViewController类为n曾经叫(我已经用断点验证了这一点)。

如果我更改我的控制器工厂实现以返回ViewController类的实例,那么一切都按预期工作。

任何人都可以帮助我清除我的困惑吗?我错误地使用Callback接口还是ORACLE文档不正确?

+0

您正在使用哪个版本的JavaFX?正如oracle引用的描述所说,它可能对版本2.1有效,因为覆盖的方法是'getController(Class type)',而在2.2中则是'call(Class param)'。所以这个行为也可以改变,试用版本2.1。 –

+0

我使用的是2.2版本。我注意到了回调语法的区别,但认为这是因为2.2文档中没有提及它所做的改变。这不是一个大问题,因为我可以使用依赖注入框架来创建在其构造函数中没有参数的控制器。 –

+1

这是[FXMLLoader JavaFX 8源代码](http://hg.openjdk.java.net/openjfx/8/master/rt/file/tip/modules/fxml/src/main/java/javafx/fxml/FXMLLoader的.java)。虽然它不是2.2,但其大部分代码是相似的。 controllerFactory的唯一用法是'setController(controllerFactory.call(type));'。所以它在2.2中可能是相同的。只是好奇你正在使用哪种DI框架? –

回答

12

的JavaFX确实在FXMLLoader如下:

try { 
     if (controllerFactory == null) { 
     setController(ReflectUtil.newInstance(type)); 
     } else { 
     setController(controllerFactory.call(type)); 
     } 
    } catch (InstantiationException exception) { 
     throw new LoadException(exception); 
    } catch (IllegalAccessException exception) { 
     throw new LoadException(exception); 
    } 

所以,是的,oracle的教程是不正确。

+0

这是来自Uluk Biy的评论中发布的版本2.2还是版本8? –

+2

这两个版本的代码是相同的。 – Sebastian