簡體   English   中英

javafx 8 兼容性問題 - FXML 靜態字段

[英]javafx 8 compatibility issues - FXML static fields

我設計了一個在 jdk 7 中運行良好的 javafx 應用程序。當我嘗試在 java 8 中運行它時,出現以下異常:

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)

我發現原因是在控制器類的 initialize 方法中,我無法在任何靜態組件中使用內置方法。 (例如: staticMyTextField.setText() 在 java 8 中導致問題,但在 java 7 中沒有)。 我無法在 javafx 指南中找到與此相關的任何記錄。 有人可以提供一些關於為什么這會導致 Java 8 出現問題的想法嗎? 並共享與此相關的文檔(如果有)。

聽起來您正在嘗試將TextField注入靜態字段。 就像是

@FXML
private static TextField myTextField ;

這顯然適用於 JavaFX 2.2。 它在 JavaFX 8 中不起作用。由於沒有官方文檔支持這種用法,因此它並沒有真正違反向后兼容性,盡管公平地說,關於FXMLLoader所做的確切功能的文檔非常糟糕。

@FXML字段@FXML靜態並沒有多大意義。 加載 FXML 文件時,它會為 FXML 文件中的每個元素創建新對象。 一個新的控制器實例與對FXMLLoader.load(...)每次調用相關聯,並且該控制器實例中的字段被注入為 FXML 元素創建的相應對象。 因此注入的字段必須特定於控制器實例。 如果您在控制器中有一個靜態注入字段,並且您兩次加載相同的 FXML 文件並在 UI 中顯示它兩次,那么您將無法引用兩組控件。

更新:回復評論中的問題

特別是,不要使用靜態字段只是為了使它們可以從類外部訪問。 靜態字段具有屬於該類的單個值,而不是該類的每個實例的值,並且只有在有意義的情況下才應做出將字段設為靜態的決定。 換句話說, static定義了scope ,而不是accessibility 要允許訪問實例數據,您只需擁有對實例的引用。 FXMLLoader有一個getController()方法,允許您檢索對控制器的引用。

相關的一點:從控制器公開 UI 控件也不是一個好主意。 您應該改為公開數據。 例如,不是在控制器中定義getTextField()方法,而是定義一個textProperty()方法,該方法返回表示TextField內容的StringProperty 這樣做的原因是,當您的老板來到辦公室並告訴您他希望將TextField替換為TextAreaComboBox<String>或其他一些控件時,如果在外面的類,這將變得更加困難的控制器正在使用您的TextField 與數據呈現給用戶的方式的實現相比,由您的控制器表示的數據結構不太可能發生變化。

對於一些例子

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM