背景:我已经使用JFXPanel创建了一个嵌入在Swing框架中的JavaFX应用程序。我一直在使用Eclipse作为IDE。 “主应用程序”是另一个类,它只用于创建一个类的实例,该类在实例化时扩展JFXPanel
以加载我的.fxml文件。从Eclipse执行主类时,一切都很好,我的.fxml文件中指定的fx:controller调用了它的initialize()
方法(我可以告诉它在加载时对UI做出的更改)并且没有问题
但是,当我将所有内容打包到JAR并尝试将我的JFXPanel扩展类添加到Swing JFrame
实例时,它设法加载.fxml文件,只需读取图像,样式表等,以及其余的代码按预期运行,但从不调用fx:controller
的{{1}}方法。我从jar内部或外部的其他类访问类没有问题,我甚至尝试设置一个ControllerFactory,它将返回Controller的一个实例,并尝试设置initialize()
'的各种组合s类加载器并使用调用FXMLLoader
的静态和非静态方法。结果始终相同:从IDE启动时它会起作用,但从我的打包jar启动时却不起作用。我知道jar没有丢失任何文件,因为就像我说的那样从Java代码中找到类没有问题,并且捆绑的fxml / css文件似乎正在加载,减去控制器问题。
之前有人遇到过此问题,或者想知道load()
无法设置控制器可能会发生什么?这可能是某种错误吗?
答案 0 :(得分:1)
将JavaFX软件打包成.jar文件时遇到了类似的问题。原来这是相对路径的问题。你的IDE对此没有任何问题,但是当在jar中编译它时会遇到问题。
使用以下代码解析我的.fxml文件。
getClass().getClassloader().getResource("/my/view/selector.fxml")
要说这是你的错误的“原因”,我不确定,但这肯定让我困扰了一段时间,似乎是我的问题。
答案 1 :(得分:0)
我无法解决这个问题。虽然fxml / css文件加载正常并且引用了正确的控制器类,但是一旦将所有内容打包到jar中,我仍然无法看到控制器类的initialize()方法被调用。
因为我唯一需要控制器的是获取fxml文件中定义的各种UI对象,以便我可以用它们进行真正的编程,我选择只创建一个递归搜索来查找这些单独的小部件他们的fxml ID [似乎首先查找'id'然后'fx:id'如果在场景树中找不到'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;
}
答案 2 :(得分:0)
我遇到了同样的问题,即从IDE调用<gateway>
方法,而不是从(阴影)jar调用。
问题是我们使用的ProGuard配置为保留initialize()
和protected
方法。但是,public
方法已声明为initialize()
。因此,它混淆了方法名称,JavaFX无法找到任何适当命名的方法,并且private
从未被调用过。
要阻止ProGuard模糊JavaFX带注释的方法和字段,请将此规则包含在initialize()
中:
proguard.conf
第一行将保留-keepattributes javafx.fxml.FXML
-keepclassmembers class * {
@javafx.fxml.FXML *;
}
注释,另一个规则保留@FXML
注释的类成员名称。