我可以在没有JVM重启的情况下在JavaFX 8中重新加载样式表吗?

问题描述 投票:5回答:2

我正在使用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重新加载样式表?或者,重新加载类以便缓存丢失的方法?

java clojure javafx javafx-8
2个回答
2
投票

请注意,您没有设置或更改样式表,而是添加样式表:

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

0
投票

我的开发方法是一样的:JavaFX在repl中使用Clojure,编辑css,而不是重启JVM。

我发现以下2条“规则”适用:

  1. 不要将样式表添加到场景中。即使您尝试书中的所有技巧,它也不会更新(清除)。奇怪的是,在所有阶段结束后,它会在一定时间后发生变化。但是,无法弄清楚原因。而是将其添加到父节点。
  2. 确保所有阶段都已关闭。如果任何阶段打开,您的旧样式将不会更新。我认为与缓存和线程有关。

更新:上面的内容不是很好,因为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))
© www.soinside.com 2019 - 2024. All rights reserved.