使用Clojure,我尝试编写一个用于Gluon SceneBuilder的自定义JavaFX组件,从.jar文件加载。也就是说,我想用我的自定义类将SceneBuilder指向.jar,并将该东西显示在左侧的可拖动项目列表中。
我可以只使用FXML显示视觉结构,但我也希望包含一些行为。
在我的Clojure源代码中运行(:gen-class)
内容,运行lein uberjar
,并在FXML中使用fx:root
构造后,我能够在官方Java example的修改版本。
当我在CustomControlExample
中实例化我的自定义类时,我看到了运行Clojure init代码的证据(通过printlns和图形中的其他内容)。
所以我的自定义类似乎正常工作。它有两个构造函数 - 有和没有String
参数,并且从HBox扩展。当我在NetBeans中查看生成的.class
文件并使用JarExplorer时,我可以验证这些。由于是Clojure构造类,该类中有更多东西,但它至少具有与示例相同数量和类型的构造函数。
问题是当我导入uberjar文件时,我的自定义组件没有出现在SceneBuilder中。
所以问题是:SceneBuilder需要在类中看到什么完全才能使其显示为自定义可拖动组件?
以下是我的一个源文件的相关部分(它包含一个用于处理启动FX运行时的实用程序库)。
的src / toyui / GridSettingsPane.clj:
(ns toyui.GridSettingsPane
(:gen-class
:extends javafx.scene.layout.HBox
:post-init post-init
:init init
:constructors {[] []
[String] []})
(:use [jfxutils.core :exclude [-main]]))
(defn -init
([]
(-init "unnamed-init"))
([name]
(println "hi from -init")
[[] []]))
(defn -post-init
([this]
(-post-init this "unnamed-post-init"))
([this name]
(println "hi from -post-init")
(jfxutils.core/app-init)
(let [loader (javafx.fxml.FXMLLoader. (clojure.java.io/resource "GridSettingsPane.fxml"))]
(.setRoot loader this)
(.setController loader this)
(.load loader)
loader))))
答案 0 :(得分:0)
我发现SceneBuilder正在使用一些实时类加载。 Clojure默认为*use-context-classloader*
= true
,所以我能够通过修改场景构建器代码来加载类,如上面的评论中那样。然而,在寻找某种类型的资源时仍然遇到一些麻烦。我认为它仍然可能是由于课程路径等。
在这个过程中我还发现SceneBuilder动态地创建了一个小的FXML文件(实际上是流),其中包括<?import toyui.GridSettingsPane?>
,并且在该流上运行常规的FXML加载器。
所以我去修改FXMLExample以从.fxml文件中导入我的Clojure类并且它有效。
所以结论是肯定的,当我从普通程序运行时,我的类将在FXML中按原样运行,但由于某种原因,当jar浏览器正在查找时,它不会加载。