首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >JavaFx无法加载@字体,因为com.sun.javafx.css.StyleManager loadStylesheetUnPrivileged

JavaFx无法加载@字体,因为com.sun.javafx.css.StyleManager loadStylesheetUnPrivileged
EN

Stack Overflow用户
提问于 2015-12-02 06:25:39
回答 5查看 7.1K关注 0票数 11

我已经问了一个类似的问题,这里,但似乎还不清楚,因为我在项目中有很多代码,不能在这里发布,所以不要标记为重复。

正因为如此,我决定创建一个新项目,其中只有一个标签,以使代码变得更小、更干净,并消除其他潜在的错误嫌疑人--

下面是我的Java源代码

代码语言:javascript
运行
复制
public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {
        Group root = new Group();

        Label label = new Label("Sample Label");
        label.setId("sampleLabel");
        root.getChildren().add(label);

        Scene scene = new Scene(root, 300, 275);
        scene.getStylesheets().add(getClass().getResource("applicationStyles.css").toExternalForm());
        primaryStage.setTitle("Hello World");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

这是我的css文件

代码语言:javascript
运行
复制
/**/
@font-face {
    font-family:'Roboto';
    src:url("Roboto-Thin.ttf");
}
#sampleLabel{
    -fx-font-family: Roboto ;
}

这就是我在Intellij的想法中遇到的错误

代码语言:javascript
运行
复制
Dec 02, 2015 9:16:34 AM com.sun.javafx.css.StyleManager loadStylesheetUnPrivileged
INFO: Could not load @font-face font [file:/C:/Users/UserName/Desktop/Java8%20projects/TeamViewer/out/production/TeamViewer/sample/Roboto-Thin.ttf]

所有项目文件都在一个包中,字体文件也存在于out>production>TeamViewer>sample>Roboto-Thin.ttf.中。我还从jdk-8u65升级到jdk-8u66。

谢谢,我们非常感谢您的帮助。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2016-02-01 16:13:10

我找到了可能的原因和解决方案: CSS加载器使用函数Font.loadFont在CSS中加载字体。如果失败,Font.loadFont只返回null,这会给出“警告”。

这个函数似乎不适用于%20,它的路径/url。因此,您需要解析路径,然后用一个空格替换它。这意味着你必须用代码来加载你的字体,而不是用CSS (现在)。

在Clojure中,我的工作如下所示:

代码语言:javascript
运行
复制
(require '[clojure.java.io :as cio])
(require '[clojure.string :as s])
(-> "fonts/SourceCodePro-Regular.ttf" 
  cio/resource 
  str 
  (s/replace "%20" " ") 
  (javafx.scene.text.Font/loadFont  10.))

;-)

票数 4
EN

Stack Overflow用户

发布于 2015-12-04 22:27:15

我正在使用e(Fx),它不识别您的JavaFX文件为有效的CSS。当我启动程序时,我不会得到异常,但是,它只是使用默认的字体。

通过以下更改,将加载并显示字体。

代码语言:javascript
运行
复制
/**/
@font-face {
    font-family: Roboto; /* removed '' */
    src: url("Roboto-Thin.ttf");
}
#sampleLabel{
    -fx-font-family: Roboto ; /* added -fx- prefix */
}
票数 1
EN

Stack Overflow用户

发布于 2017-12-31 12:37:23

所以,差不多两年后,我发现了我自己对同样的问题的回应。

但是现在,在研究了com.sun.javafx.css.StyleManager的源代码之后,我有了一个更酷更优雅的解决方案:自己解析样式表并加载字体。

参见此处的相关源代码:第932-662行

(是的,这都是Clojure写的,但我相信你能搞清楚的。)

我首先要说的是:

代码语言:javascript
运行
复制
(defn add-stylesheet [^Scene scene path]
  (let [logger (Logging/getCSSLogger)
        level (.level logger)]
    (.setLevel logger PlatformLogger$Level/OFF)  ;; turn off logger
    (-> scene .getStylesheets (.add path))  ;; set stylesheet
    (.setLevel logger level) ;; turn logger back on
    (-> path stylesheet-parsed load-fonts))) ;; parse and load fonts

(由于某种原因,关闭日志无法工作)。

对样式表的解析如下:

代码语言:javascript
运行
复制
(defn stylesheet-parsed [path]
  (.parse (CSSParser.) (cio/resource path)))

最后,这些字体包含以下内容:

代码语言:javascript
运行
复制
(defn- load-fonts [^Stylesheet stylesheet]
  (doseq [^FontFace fontface (.getFontFaces stylesheet)]
    (doseq [^FontFace$FontFaceSrc ffsrc (.getSources fontface)]
      (let [src (-> ffsrc .getSrc (cs/replace "%20" " "))] ;; <- sanitizing path for Font/getFont
        (println "Loading font:" src)
        (let [f (Font/loadFont src 10.)]
          (println "Font loaded:" f))))))

这个很好,看起来很像原版。一个优点是,这里我们不只是检查URL类型,所以理论上我们可以扩展它以更广泛地处理@字体。

下面是load-fonts的一个更关闭的实现,它返回加载的所有字体的列表:

代码语言:javascript
运行
复制
(defn- load-fontface-src [^FontFace$FontFaceSrc ffsrc]
  (-> ffsrc .getSrc (cs/replace "%20" " ") (Font/loadFont 10.)))

(defn- load-fontface [^FontFace ff]
  (map load-fontface-src (.getSources ff)))

(defn- load-fonts [^Stylesheet stylesheet]
  (vec (flatten (map load-fontface (.getFontFaces stylesheet)))))

所需的进口:

代码语言:javascript
运行
复制
(import
  '[com.sun.javafx.css.parser CSSParser]
  '[com.sun.javafx.css Stylesheet FontFace FontFace$FontFaceSrc]
  '[com.sun.javafx.util Logging]
  '[sun.util.logging PlatformLogger$Level])

TODO:

  1. 转向伐木。(这很烦人,虽然只是开发中的一个问题。)
  2. 测试看看是否有任何字体没有加载,然后才进行可供选择的解析和加载。但是,简单的检查可能需要与实际加载字体一样多的处理时间。

FIX:将vec添加到flatten的左侧,以确保实现延迟的seqs。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34036207

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档