2013-02-15 73 views
1

背景:我創建了一個使用JFXPanel嵌入Swing框架中的JavaFX應用程序。我一直在使用Eclipse作爲IDE。 「主應用程序」是另一個類,它只用於創建一個擴展JFXPanel以在實例化時加載我的.fxml文件的類的實例。當從Eclipse執行主類時,一切都很好,我的.fxml文件中指定的fx:控制器調用了其方法initialize()(我可以通過它在加載時對UI進行的更改進行分析),並且沒有任何問題。但是,當我將所有東西打包成一個JAR並嘗試將我的JFXPanel擴展類添加到一個Swing JFrame實例時,它設法加載.fxml文件,只是精細讀取圖像,樣式表等,而其餘的該代碼正常工作,但fx:controllerinitialize()方法從未被調用過。我沒有問題從jar內部或外部的其他類訪問類,我甚至嘗試設置一個ControllerFactory,它將返回Controller的一個實例,並嘗試各種組合設置FXMLLoader的類加載器並使用無論是調用load()的靜態和非靜態方法。結果總是相同的:從IDE啓動時它將起作用,但在從我的打包jar啓動時不起作用。我知道這個jar不會丟失任何文件,因爲就像我說的那樣,從Java代碼中找到該類並沒有問題,並且捆綁的fxml/css文件似乎加載正常,減去控制器問​​題。JavaFX 2.2在JAR文件中加載時未調用控制器initialize()

有人曾經遇到過這種情況,或者有什麼想法可能會發生什麼FXMLLoader未能設置控制器?這可能是某種錯誤嗎?

+0

你的jar是如何部署的?對於JavaFX 2.2,由於FXML使用反射,FXML目前無法在未簽名的webstart或applet中工作。我也相信,由於如何管理OSGI類加載(儘管我從未嘗試過),可能需要進行一些調整以使JavaFX 2.2 FXML應用程序可以在OSGI環境中工作。您的Jar應該使用JavaFX部署工具打包,否則它可能找不到正確的運行時。也許其中一件事是你的問題。 – jewelsea 2013-05-01 21:09:34

回答

0

我無法來解決這個問題。當fxml/css文件加載正常並引用正確的控制器類時,我仍然無法看到控制器類的initialize()方法一旦被打包到jar中就會被調用。

由於我唯一需要的控制器是抓取fxml文件中定義的各種UI對象,以便我可以用它們進行真正的編程,我選擇了創建遞歸搜索來查找這些單獨的小部件通過他們的FXML ID [似乎查找「身份證」第一則「外匯:身份證」如果「身份證」找不到]在場景樹..

//grabs fxml file relative to root of the jar 
FXMLLoader loader = new FXMLLoader(ClassLoader.getSystemClassLoader().getResource("app.fxml")); 
Parent javaFXRoot = (Parent) loader.load(); 

public Node findWidgetByID(String id, Parent javaFXRoot) 
{ 
    return findObject(root, id); 
} 

private Node findObject(Parent root, String id) 
{ 
    for (Node node : root.getChildrenUnmodifiable()) 
    { 
     if (node.getId() != null && node.getId().equals(id)) 
     { 
      return node; // found the node, return it 
     } 
     Node retValue = null; 
     if (node instanceof Parent) 
     { 
      retValue = findObject(((Parent) node), id); // recursive search 
     } 
     if (retValue != null) //if our node was found by the recursive search, return that 
     { 
      return retValue; 
     } 
    } 
    return null; 
} 
1

將我的JavaFX軟件打包到.jar文件時,我遇到了類似的問題。原來這是一個關於相對路徑的問題。你對IDE沒有任何問題,但是當它在jar中編譯時會遇到問題。

這是解決使用以下代碼來調用我的.fxml文件。

getClass().getClassloader().getResource("/my/view/selector.fxml") 

,這不能不說是「理性」爲你的錯誤,我不知道,但是這肯定難倒我了一會兒,似乎是相當多的問題,我有。

原題:Executable Jar limited to one window with JavaFX

+0

問題不在於查找fxml文件或jar中的任何內容,問題在於在加載fxml後控制器類的initialize方法未被調用。 fxml文件本身(和css)被發現並加載得很好。因爲我只需要這個來獲取對fxml中組件的引用以便進一步編碼,所以我選擇了創建一個「通過id查找小部件」的遞歸搜索方法來在場景的根目錄上運行,以便根據它們的fxml來查找各種組件IDS。 – 2013-05-01 19:49:23

+0

我沒有100%跟進,但我認爲如果你用你所做的(顯示一些代碼)回答了這個問題,這將是很好的。這可能會有助於其他人看這個。 – blo0p3r 2013-05-01 19:59:23

0

我有同樣的問題,其中initialize()方法是從IDE調用的,但不是來自(陰影)的jar。

問題是我們使用的ProGuard配置爲保留protectedpublic方法。然而,initialize()方法被宣佈爲private。因此它混淆了方法名稱,JavaFX找不到任何適當命名的方法,並且從未調用過initialize()

要混淆你的JavaFX註釋的方法和字段停止ProGuard的,包括這個規則到您的proguard.conf

-keepattributes javafx.fxml.FXML 

-keepclassmembers class * { 
    @javafx.fxml.FXML *; 
} 

第一行會保持@FXML註釋,其他規則保持@FXML註解的類成員名稱。