2015-12-02 32 views
10

Avevo già chiesto una domanda simile here ma sembra che non fosse chiaro poiché avevo molto codice nel progetto e non è stato possibile postarlo qui Quindi per favore non contrassegnare come duplicato.JavaFx Impossibile caricare il carattere @ font-face a causa di com.sun.javafx.css.StyleManager loadStylesheetUnPrivileged

A causa di ciò, ho poi deciso di creare un nuovo progetto con un semplice Label in esso per rendere il codice piccola e pulita e anche per eliminare altri potenziali sospetti dell'errore sto ottenendo.

ecco il mio codice sorgente 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); 
    } 
} 

e questo è il mio file css

/**/ 
@font-face { 
    font-family:'Roboto'; 
    src:url("Roboto-Thin.ttf"); 
} 
#sampleLabel{ 
    -fx-font-family: Roboto ; 
} 

Questo è l'errore che sto ricevendo in 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] 

Tutti i file di progetto sono in un unico pacchetto e il file di caratteri è presente anche in uscita> produzione> TeamViewer> esempio> Roboto-Thin.ttf. Ho anche aggiornato da jdk-8u65 a jdk-8u66

Grazie, qualsiasi aiuto è molto apprezzato.

+0

Si sta utilizzando il filtro delle risorse Maven? Ho appena affrontato lo stesso problema e risulta essere causato dal filtro Maven, in quanto ho dimenticato di escluderli dal filtraggio. –

+0

@MajedAbdulaziz Grazie mille per la risposta, ma non sto usando Maven, non penso che questa sia la causa nel mio caso. –

+0

In quale posizione rispetto al file sorgente e al file di classe compilato si trova 'Roboto-Thin.ttf'? – hotzst

risposta

2

ho trovato la possibile causa e un work-around: Sotto il cofano il CSS-loader utilizza la funzione Font.loadFont per caricare il font-face nel CSS. Font.loadFont restituisce semplicemente null in caso di errore, che fornisce "avviso".

Sembra che questa funzione non funzioni con %20 il suo percorso/stringa-url. Quindi è necessario risolvere il percorso e quindi sostituirlo con uno spazio. Ciò significa che dovrai caricare i tuoi font con codice anziché con CSS (per ora).

In Clojure mio lavoro-around si presenta così:

(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.)) 

;-)

+1

L'ho risolto rimuovendo semplicemente lo spazio per eliminare% 20, ma questo risolve anche il problema. Grazie mille +1 –

1

Sto utilizzando il plug-in clipse (fx) per Eclipse, che non riconosce il file CSS come CSS JavaFX valido. Tuttavia, non ottengo l'eccezione quando avvio il programma, semplicemente utilizza il carattere predefinito.

Con le seguenti modifiche, il carattere viene caricato e visualizzato.

/**/ 
@font-face { 
    font-family: Roboto; /* removed '' */ 
    src: url("Roboto-Thin.ttf"); 
} 
#sampleLabel{ 
    -fx-font-family: Roboto ; /* added -fx- prefix */ 
} 
+0

Grazie per la risposta, ma sto ancora ricevendo lo stesso errore, scusa anche di aver dimenticato il prefisso '-fx-' ma l'ho appena aggiunto –

+0

Il problema è con Intellij Idea –

+0

Hai provato a compilarlo/eseguirlo con javac/java normale, senza IDE? Ho appena provato da solo e anche il tuo CSS originale funziona bene in questo modo. – Prometheus

1

Così, quasi 2 anni più tardi, e mi sono imbattuto la mia risposta allo stesso problema che ho ancora.

Ma ora ho una soluzione più elegante e più elegante, dopo aver studiato il codice sorgente per com.sun.javafx.css.StyleManager: È sufficiente analizzare personalmente i fogli di stile e caricare i caratteri.

Vedi codice sorgente rilevanti qui: lines 932-662

(. Sì, questo è tutto in Clojure, ma sono sicuro che si può capire)

parto da questo:

(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 

(La disattivazione della registrazione non funziona, per qualche motivo).

Il foglio di stile viene analizzato con questo:

(defn stylesheet-parsed [path] 
    (.parse (CSSParser.) (cio/resource path))) 

E infine i font vengono caricati con questo:

(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)))))) 

Questo funziona bene, e guarda un po 'come l'originale. Un vantaggio è che qui non controlliamo solo il tipo URL, quindi potremmo estenderlo teoricamente per gestire in modo più estensivo @ font-face.

Ecco una maggiore implementazione Clojure-Y di load-fonts che restituisce un elenco di tutti i font caricati:

(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))))) 

e le importazioni necessarie:

(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. Turn of registrazione. (È fastidioso, anche se solo un problema in fase di sviluppo.)
2. Verificare se i caratteri non sono stati caricati e solo dopo l'analisi e il caricamento alternativi. Ma probabilmente il semplice controllo richiederebbe una quantità di elaborazione pari a quella di un caricamento dei font in un tempo extra.

FIX: aggiunto vec a sinistra di flatten, per garantire che i seq pigri siano realizzati.