首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >FXML锅炉板规范

FXML锅炉板规范
EN

Stack Overflow用户
提问于 2014-09-06 02:12:00
回答 1查看 573关注 0票数 0

是否有一种方法来处理典型的锅炉板代码来实例化和加载FXML?

典型的版本:

代码语言:javascript
复制
public void start(Stage primaryStage) 
{   
    URL fxmlUrl = this.getClass().getResource( /* your string path*/ );

    FXMLLoader loader = new FXMLLoader(fxmlUrl);

    try 
    {   
        primaryStage = loader.load();
        this.controller = loader.getController();
    } 
    catch(IOException ioe)
    {
        ioe.printStackTrace();
    }

    primaryStage.show();
}

注对于上面的代码,支持FXML文件以<Stage></Stage>作为根。这只是我的偏好。加载和匹配到FXML根可以进行相应的调整。无论如何,加载FXML文件并获得对控制器的引用是关键部分(在大多数情况下)。

我尝试创建一个实用程序方法,如下所示,以帮助防止这个锅炉板代码:

代码语言:javascript
复制
<R, C> void loadFXML(R root, C controller, String path)
{
    URL fxmlUrl = this.getClass().getResource( path );

    FXMLLoader loader = new FXMLLoader(fxmlUrl);

    try 
    {   
        root = loader.load();
        controller = loader.getController();
    } 
    catch(IOException ioe)
    {
        ioe.printStackTrace();
    }
}

但是,在某些阶段存在空指针错误,或者加载不正确。我相信这与泛型和/或铸造有关。

这段代码怎么能被修改呢?或者,也许可以建议另一种类型的代码来解决这个问题?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-09-06 02:55:12

问题是(可能;您没有显示您的Null指针异常来自何处),您只是设置局部变量rootcontroller,然后让它们超出作用域。

请记住,Java以逐值的方式处理方法参数:因此该方法创建rootcontroller引用的本地副本。当您的方法调用

代码语言:javascript
复制
root = loader.load();
controller = loader.getController();

它只是更新本地引用,而不是传递给方法的引用。所以如果你这么做

代码语言:javascript
复制
Parent root = null ;
MyController controller = null ;
loadFXML(root, controller, "Main.fxml");
System.out.println(root);
System.out.println(controller);

您将看到值null

一个解决办法是传递对象的可变包装器,并更新这些包装器。ObjectProperty对此很有帮助:

代码语言:javascript
复制
<R, C> void loadFXML(String path, ObjectProperty<R> root, ObjectProperty<C> controller)
{
    URL fxmlUrl = this.getClass().getResource( path );

    FXMLLoader loader = new FXMLLoader(fxmlUrl);

    try 
    {   
        root.set(loader.load());
        controller.set(loader.getController());
    } 
    catch(IOException ioe)
    {
        ioe.printStackTrace();
    }

}

另一个选项是创建一个封装这两个值并返回其实例的类:

代码语言:javascript
复制
public class ViewController<V,C> {
    private final V view ;
    private final C controller ;
    public ViewController(V view, C controller) {
        this.view = view ;
        this.controller = controller ;
    }
    public V getView() {
        return view ;
    }
    public C getController() {
        return controller ;
    }
}

然后

代码语言:javascript
复制
<R, C> ViewController<R, C> loadFXML(String path)
{
    URL fxmlUrl = this.getClass().getResource( path );

    FXMLLoader loader = new FXMLLoader(fxmlUrl);

    try 
    {   
        R root = loader.load();
        C controller = loader.getController();
        return new ViewController<R,C>(root, controller);
    } 
    catch(IOException ioe)
    {
        ioe.printStackTrace();
        throw new UncheckedIOException(ioe); // this is likely fatal, so just throw an unchecked exception
    }
}

不过,你是否在细节上得到了任何节省,这是值得商榷的:

代码语言:javascript
复制
ViewController<Parent, MyController> viewController = loadFXML("Main.fxml");
Parent root = viewController.getView();
MyController controller = viewController.getController();

最后一个注意是,在几乎所有用例中,您实际上只在事后对控制器做任何重要的工作;您通常只是将视图设置为场景的根,或者将其添加到另一个布局窗格中。您可以通过让方法接受Consumer<R>并返回控制器来利用这一点(在Java 8中):

代码语言:javascript
复制
public <R, C> C loadFXML(Consumer<R> rootHandler, String path) {
    URL fxmlUrl = this.getClass().getResource( path );

    FXMLLoader loader = new FXMLLoader(fxmlUrl);

    try 
    {   
        R root = loader.load();
        C controller = loader.getController();
        rootHandler.accept(root);
        return controller ;
    } 
    catch(IOException ioe)
    {
        ioe.printStackTrace();
        throw new UncheckedIOException(ioe); // this is likely fatal, so just throw an unchecked exception
    }
}

,您可以使用类似的方法调用

代码语言:javascript
复制
Scene scene = new Scene();
MyController controller = loadFXML(scene::setRoot, "Main.fxml");
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25696223

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档