控制器在javafx helloworld中返回null

时间:2013-08-23 12:21:52

标签: javafx-2 fxml

当然,我直接潜入创建一个简单的例子。

public class Main extends Application {

URL bla = getClass().getResource("/sample.fxml");

@Override
public void start(Stage primaryStage) throws Exception{
    //If you get weird errors: http://zenjava.com/javafx/maven/fix-classpath.html
        //but not actually my issue. Example displays fine in intellij.

    try {

        FXMLLoader loader = new FXMLLoader(bla);
        Parent root = loader.load(bla);

        primaryStage.setTitle("Hello World");
        primaryStage.setScene(new Scene(root));
        primaryStage.show();

        Controller controller = loader.<Controller>getController() ;
        assert(controller != null);
        controller.getLabel().setText("Kaboom!");
    } catch (Exception e) {
        // Exception gets thrown if the fxml file could not be loaded
        e.printStackTrace();
    }
}

public static void main(String[] args) {
    launch(args);
}
}

我看过https://forums.oracle.com/thread/2317621 我知道顶部的锚点需要在fxml中指向我的控制器。

<AnchorPane id="AnchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity"      minWidth="-Infinity" prefHeight="600.0" prefWidth="800.0" xmlns:fx="http://javafx.com/fxml" fx:controller="mypackage.Controller">
  <children>

它显示正常,但断言因为没有控制器而捕获! 此外initialize()确实运行,这意味着创建了以下控制器!

public class Controller {

@FXML
private Label label ;

public Label getLabel()
{
    return label ;
}

@FXML
public void initialize()
{
    System.out.println("Swear a lot!");
    System.out.println(label);
}
}

如果您正在观看此事,请向FX开发者发送一条说明:

如果你要在指向类的xml文件中使用弱耦合字符串,我真的希望.load()在找不到它正在寻找的内容时抛出一个有意义的运行时异常。没有理由永远返回null ...理想情况下从GWT小部件团队中获取一个页面,并在程序实际开始之前让预编译器失败,或者为流行的IDE提供最好的插件。

此外,你真的应该尽快为JavaFX启动和运行JavaFX的源代码(把它放在maven中),因此它可以自动下载,我可以解决问题本身。太难了。

我确信有一些简单的事我做错了,但这些工具应该让我免于此。

2 个答案:

答案 0 :(得分:6)

能够像这样获得控制器类

Controller controller = loader.<Controller>getController();

你需要调用实例化的FXMLLoader的加载方法,即
而不是

Parent root = loader.load(bla);

这里load()是静态的,调用

Parent root = (Parent) loader.load(bla.openStream());

但我同意应该记录在案。

答案 1 :(得分:1)

Uluk的回答已经解决了问题中提出的主要问题。

这个&#34;回答&#34;仅解决辅助问题。

  

我真的希望.load()能够找到一个有意义的运行时异常,如果它无法找到它正在寻找的内容。

JavaFX issue tracker中记录调整问题,以了解API更改,异常消息修改或文档改进请求。在这种情况下,它听起来像是文档和API使用说明。

另请注意,FXML文件的使用是可选的。在FXML中可以完成的所有操作也可以直接在Java API中完成,因此您不需要在xml文件中指向类&#34;的弱耦合字符串。

如果您确实有这种弱字符串耦合,某些开发环境(例如Idea 12.1+)将为您运行增量验证,检查,错误语法突出显示和fxml /代码导航。因此,当前的工具可以帮助您在一定程度上避免一些陷阱(尽管可能不是您帖子中引用的特定问题)。 Java框架已经在IDE中与XML集成了很长时间,并且它并不是一个完美的结合,但IDE开发人员已经非常善于解决一些最痛苦的问题。

  

此外,你真的应该尽快为JavaFX启动并运行JavaFX的源代码(把它放在maven中),因此它可以自动下载,我可以解决问题所在。

在JavaFX问题跟踪器中,有an existing request for JavaFX source code bundling with the JDK。该问题计划在Java 8发布之前实施。该解决方案不适用于JavaFX 2.2等早期JavaFX版本,因为这些版本大多是封闭源代码。

与此同时,您可能对从open-jfx存储库获取源代码的替代解决方案感兴趣,该解决方案在以下内容的答案中提供:JavaFX source code not showing

  

我确实看过openJDK,但它看起来像是一个任务。

可以理解 - 使用open-jfx存储库中的源比使用JDK发行版附带的捆绑src.zip更复杂,新的IDE项目自动引用(与当前jdk src.zip相同)由IDE使用。)

我确信JavaFX源代码捆绑可以轻松访问来自主要IDE的JavaFX源代码,这些代码将在Java 8发布时实现。

我不认为将JavaFX库和代码放在maven存储库中是一个很好的解决方案,因为库本身现在构成了JDK发行版的一部分。 JDK发行版中的其他代码不包含在maven存储库中。也许当Java 9出现模块化JDK方法时,这可能会改变。

  

除非Scene Builder可以创建/修改java代码,否则不建议使用xml。

不使用FXML不是建议 - 对于那些可能不喜欢基于XML的方法来匹配每周键入的字符串语言与强类型Java语言的人来说,它只是一种选择。

我对FXML使用的唯一真正建议是当你第一次开始JavaFX开发时(IMO)不使用FXML和SceneBuilder:

  1. 在学习JavaFX工具包的原理时,使用API​​会更有效。
  2. 学习的东西较少。
  3. 您没有GUI工具自动生成您可能还不知道如何正确使用的复杂UI元素。
  4. 您不必担心FXML加载器有多复杂,令人困惑和记录错误。
  5. 您不必担心在FXML文件和Java代码中保持UI元素之间的同步映射。
  6. 您必须从低级API角度了解布局和场景图结构。
  7.   

    如果您专门评估UI技术以便分离关注点,那么布局设计人员可以加入团队......那么您的关注列表就会非常静音

    当然,从跨职能团队的角度对JavaFX技术的任何评估自然会涉及对FXML和SceneBuilder使用的评估。

    为新JavaFX开发人员提供仅使用API​​执行初始JavaFX开发的原因并不是真正的问题。它们构成了我对开发人员(不是跨职能评估员)为什么只在最初学习JavaFX技术时坚持API的看法。

      

    我认为将此作为文档问题并不合适,因为它对用户的期望过高。

    这是一种可以理解的情绪。也许弃用静态FXMLLoader加载方法可能是一种更好的方法来防止这种用户错误的可能性。

    无论如何,请求更改文档或实施的最直接方法是在JavaFX issue tracker中创建问题请求,并在openjfx-dev mailing list上与开发人员讨论问题。 JavaFX目前正在积极开发中,因此这样的请求(如果及时制作)有可能在Java 8时间帧中实现。

    如果您有其他辅助问题,我建议将其发布到最能处理这些问题类型的论坛(例如Oracle JavaFX forumsopenjfx-dev JavaFX mailing list)。