我已经在here问过类似的问题,但似乎不清楚,因为我在项目中有很多代码,无法在此处发布所以请不要标记为重复。
正因为如此,我然后决定创建一个新项目,其中只有一个 Label,以使代码小而干净,并消除其他潜在的嫌疑人我得到的错误。
所以这是我的Java源代码
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文件
/**/
@font-face {
font-family:'Roboto';
src:url("Roboto-Thin.ttf");
}
#sampleLabel{
-fx-font-family: Roboto ;
}
这是我在 Intellij Idea 中遇到的错误
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
谢谢,非常感谢任何帮助。
我找到了可能的原因和解决方法: 在引擎盖下,css-loader 使用函数
Font.loadFont
在你的 CSS 中加载字体。
Font.loadFont
如果失败则简单地返回 null
,给出“警告”。
似乎此功能不适用于
%20
它的路径/ url-string。
所以需要解析路径,然后用空格替换。
这意味着您将不得不使用代码而不是 CSS(目前)加载字体。
在 Clojure 中,我的解决方法如下所示:
(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.))
;-)
我正在使用 Eclipse 的 e(fx)clipse 插件,它无法将您的 CSS 文件识别为有效的 JavaFX CSS。然而,当我启动程序时我没有得到异常,它只是使用默认字体。
通过以下更改,正在加载和显示字体。
/**/
@font-face {
font-family: Roboto; /* removed '' */
src: url("Roboto-Thin.ttf");
}
#sampleLabel{
-fx-font-family: Roboto ; /* added -fx- prefix */
}
所以,差不多 2 年后,我发现了自己对同样问题的回应。
但现在我有一个更酷更优雅的解决方案,在研究了
com.sun.javafx.css.StyleManager
的源代码之后:只需自己解析样式表并加载字体。
在此处查看相关源代码:932-662行
(是的,这一切都在 Clojure 中,但我相信你能弄明白。)
我从这个开始:
(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
(出于某种原因,关闭日志记录不起作用)。
样式表是这样解析的:
(defn stylesheet-parsed [path]
(.parse (CSSParser.) (cio/resource path)))
最后加载字体:
(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,所以我们理论上可以扩展它来更广泛地处理@font-face。
这里是
load-fonts
的更 Clojure-y 实现,它返回所有加载字体的列表:
(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)))))
需要进口:
(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])
待办事项:
1.轮到伐木。 (这很烦人,虽然只是开发中的问题。)
2. 测试是否有任何字体未加载,然后才进行替代解析和加载。但可能简单的检查需要的处理量与实际加载字体的额外时间一样多。
修复: 在
vec
的左边添加flatten
,以确保实现惰性seqs。
在我的例子中,这是由字体文件名中的“-”字符产生的,将其替换为“_”即可。
我确定字体系列必须是相同的文件名,但替换所有特殊字符''(空格)并拆分驼峰字。
所以:
之前(不工作):
@font-face {
font-family: 'RifficFree Bold';
src: url("../fonts/RifficFree-Bold.ttf");
}
.bingo-number, .label{
-fx-font-family: 'RifficFree Bold';
}
(工作后):
@font-face {
font-family: 'Riffic Free Bold';
src: url("../fonts/RifficFree_Bold.ttf");
}
.bingo-number, .label{
-fx-font-family: 'Riffic Free Bold';
}
对于那些像我一样仍然有这个问题并且不想或不知道如何使用 Clojure 的人,这里是如何仅在 Java 中做到这一点:
在将样式表添加到您的场景之前,使用
Font.loadFont(getClass().getResourceAsStream([fontpath...]), [Some font-size, for example 12]);
-fx-font-family
css-Property 和加载的字体。
我在 Reddit 上找到了适合我的解决方案。这是链接:Reddit 帖子
在 CSS 样式表中定义字体系列时,请确保使用字体文件第一行中提到的确切名称。
例如,如果第一行是“Pixeloid Sans”,则字体系列应指定如下:
-fx-font-family: "Pixeloid Sans";
我还删除了
@font-face
声明,因为它是不必要的。
最后,我要提一下,我所有的 .tff 文件都位于 /resources 中的一个文件夹中。