【发布时间】:2017-10-23 17:03:53
【问题描述】:
使用 Clojure,我正在尝试编写一个自定义 JavaFX 组件以在 Gluon SceneBuilder 中使用,以便从 .jar 文件中加载。也就是说,我想用我的自定义类将 SceneBuilder 指向 .jar,并让该东西显示在左侧的可拖动项目列表中。
我可以只用 FXML 显示视觉结构,但我也想包含一些行为。
在我的 Clojure 源代码中执行 (:gen-class) 的内容、运行 lein uberjar 并在 FXML 中使用 fx:root 构造之后,我可以在官方 Java @987654321 的修改版本中使用生成的类@。
当我在 CustomControlExample 中实例化我的自定义类时,我看到 Clojure 初始化代码正在运行的证据(通过 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))))
【问题讨论】:
-
也许你的组件需要一个宽度和一个高度。
-
嗯,刚刚添加了
(.setWidth this 800)和(.setHeight this 600),但没有雪茄。我将开始挖掘 SceneBuilder 代码,看看发生了什么。 -
我发现在 JarExplorer.java 中将
Thread.currentThread().setContextClassLoader(classLoader);添加到instantiateWithFXMLLoader(...)似乎可以解决眼前的问题,但现在 FXML 加载器中出现了 IllegalStateException "Location is not set"。可能更多类路径的东西......