javafx 8兼容性问题 – FXML静态字段

我devise了一个javafx应用程序,它在jdk 7中工作正常。当我尝试在java 8中运行它时,出现以下exception:

javafx.fxml.LoadException: at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2617) at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2595) at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441) at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3230) at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3191) at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3164) at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3140) at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3132) Exception in thread "JavaFX Application Thread" java.lang.NullPointerException: Root cannot be null at javafx.scene.Scene.<init>(Scene.java:364) at javafx.scene.Scene.<init>(Scene.java:232) at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86) at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238) at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74) at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54) at javafx.event.Event.fireEvent(Event.java:204) at javafx.concurrent.EventHelper.fireEvent(EventHelper.java:219) at javafx.concurrent.Task.fireEvent(Task.java:1357) at javafx.concurrent.Task.setState(Task.java:720) at javafx.concurrent.Task$TaskCallable$2.run(Task.java:1438) at com.sun.javafx.application.PlatformImpl$6$1.run(PlatformImpl.java:301) at com.sun.javafx.application.PlatformImpl$6$1.run(PlatformImpl.java:298) at java.security.AccessController.doPrivileged(Native Method) at com.sun.javafx.application.PlatformImpl$6.run(PlatformImpl.java:298) at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95) at com.sun.glass.ui.win.WinApplication._runLoop(Native Method) at com.sun.glass.ui.win.WinApplication.access$300(WinApplication.java:39) at com.sun.glass.ui.win.WinApplication$4$1.run(WinApplication.java:112) at java.lang.Thread.run(Thread.java:744) 

我发现原因是在控制器类的初始化方法我不能够在任何静态组件中使用内置的方法。 (例如:staticMyTextField.setText()导致在Java 8中的问题,但不是在Java 7)。 我无法在javafx指南中find有关此文档的任何信息。 有人可以请提供一些想法,为什么这是在Java 8中造成的问题? 如果有的话也分享相关的文件。

这听起来像你正试图将一个TextField注入到一个静态字段中。 就像是

 @FXML private static TextField myTextField ; 

这显然在JavaFX 2.2工作。 它在JavaFX 8中不起作用。由于没有官方文档支持这种用法,所以它并没有真正违反向后兼容性,尽pipe公平地讲, FXMLLoader所做的文档相当FXMLLoader

为什么你会想这样做呢? 这显然是一个非常可怕的想法。 假设你决定在同一个应用程序中重复使用你的FXML文件两次:第二次使用会覆盖静态字段的值,随后出现各种各样的混乱。 简单地说,如果你想在你的控制器中注入静态字段,那么你总是做错事情。

更新 :回复评论中的问题

特别是,不要使用静态字段只是为了使它们可以从课堂外访问。 静态字段有一个属于该类的值,而不是类的每个实例的值,并且只有在有意义的情况下才能使字段成为静态。 要允许访问实例数据,只需要引用实例。 FXMLLoader有一个getController()方法,允许您检索对控制器的引用。

相关的一点:从控制器公开UI控件也不是一个好主意。 你应该反而暴露数据。 例如,不是定义控制器中的getTextField()方法,而是定义一个textProperty()方法,该方法返回表示TextField内容的StringProperty 。 原因是当你的老板到办公室来告诉你他希望TextField被一个TextArea ,一个ComboBox<String>或其他一些控件取代时,如果外面的课程更难控制器正在使用您的TextField 。 由控制器表示的数据结构比实现向用户呈现数据的实现要less得多。

对于一些例子