JavaFx не смог загрузить шрифт @font-face из-за com.солнце.в JavaFX.стиль CSS.StyleManager loadStylesheetUnPrivileged
Я уже задавал подобный вопрос здесь но, кажется, это было неясно, так как у меня было много кода в проекте и я не мог опубликовать его здесь так пожалуйста не отмечайте как дубликат.
из-за этого я тогда решил создать новый проект только с метка в нем сделать код маленьким и чистым, а также устранить другие потенциальных подозреваемых ошибки, которую я получаю.
Так вот мой 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.ТЦФ. Я также обновлен с jdk-8u65 до jdk-8u66
спасибо, любая помощь очень ценится.
3 ответов
я нашел возможную причину и обойти:
Под капотом css-загрузчик использует функцию Font.loadFont
чтобы загрузить шрифт в CSS.
Font.loadFont
просто возвращает null
если это не удается, которые дают "предупреждения".
похоже, что эта функция не работает с %20
это его путь/url-строку.
Поэтому вам нужно решить путь, а затем заменить его с места.
Это означает, что вам придется загружать шрифты с кодом вместо 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.))
;-)
Я использую плагин e (fx)clipse для Eclipse, который не распознает ваш 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 более широко.
вот более Clojure-y реализация load-fonts
который возвращает список всех загруженных шрифтов:
(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])
TODO:
1. Очередь лесозаготовок. (Это раздражает, хотя только проблема в развитии.)
2. Проверьте, не были ли загружены какие-либо шрифты, и только потом на альтернативный разбор и загрузку. Но, вероятно, простая проверка потребует такой же обработки, как и фактическая загрузка шрифтов дополнительное время.
исправить:
добавлено vec
слева от flatten
, чтобы гарантировать, что ленивые seqs реализованы.