我正在使用Java 1.8u25,我正在使用如下的样式表(Java和Clojure等价物)。
//Java
new Pane().getStylesheets().add("some_style.css")
//Clojure
(doto (Pane.)
(-> .getStylesheets (.add "some_style.css")))
我使用的是Clojure,我不会在测试运行之间重启JVM。但是,我会为每次运行创建一个新的GUI实例。 JavaFX在某处缓存样式表,因此编辑CSS文件无效。有没有办法强制JavaFX重新加载样式表?或者,重新加载类以便缓存丢失的方法?
答案 0 :(得分:1)
请注意,您不是设置或更改样式表,而是添加样式表:
new Pane().getStylesheets().add("some_style.css")
您调用add()
方法!所以基本上它是你的Pane
缓存先前加载的样式表。
解决方案很简单:在再次加载之前,删除(清除)旧的:
Pane p = new Pane();
// Load first time:
p.getStylesheets().add("some_style.css");
// Later to reload:
p.getStylesheets().clear();
p.getStylesheets().add("some_style.css");
// some_style.css will be read again and applied
注意:强>
如果您使用多个CSS文件,clear()
可能不是您想要的。在这种情况下,您可以使用clear()
方法删除特定样式表(您要重新加载),而不是remove()
,然后再重新添加。
注意#2:
加载CSS文件时,应使用URL到资源,而不仅仅是文件名。如果仅提供文件名,则它也必须包含包名。这样做既可以从文件系统也可以从jar文件中运行:
p.getStylesheets().add(YourClass.class.getResource("some_style.css")
.toExternalForm()); // if some_style.css is next to YourClass.java
答案 1 :(得分:0)
我的开发方法是相同的:JavaFX在repl中使用Clojure,编辑CSS,而不重新启动JVM。
我发现以下两个“规则”适用:
更新: 上面的代码不是很好,因为CSS不会应用于弹出窗口和对话框。 经过进一步的测试,我发现(也许是由于我在Clojure中构建JavaFX对象的方式,我需要在一定的延迟后将CSS重新“应用”到场景中。
我现在有以下代码片段,这些片段似乎对我来说很有效。
(我什至可以忽略“规则2”。)
(defn fxthread? []
(Platform/isFxApplicationThread))
(defn later* [expr]
(if (fxthread?)
(try (expr) (catch Throwable e e (println e)))
(Platform/runLater #(try (expr) (catch Throwable e e (println e))))))
(defmacro future-sleep-later [ms & body]
`(future (Thread/sleep ~ms) (later* (fn [] ~@body))))
(defn external [path]
(.toExternalForm (cio/resource (str path))))
(defn add-stylesheet [scene-or-parent path & [refresh? delay]]
(let [css (external path)
ss (.getStylesheets scene-or-parent)]
(.add ss css)
(when refresh?
(future-sleep-later (or delay 2000)
(doto ss (.remove css) (.add css))))
scene-or-parent))