2014-09-04 33 views
4

我在我的swing應用程序中顯示unicode字符時遇到問題。
在認爲問題是使用的字體,它不包含適合中文的字符。
(只空顯示)
Unicode字符不在Swing中呈現,實際使用什麼字體?

這裏有一些更多的相關信息,以我的問題(我做了一些調查):
的Linux(Kubuntu的14.04)
當我開始我的JAVA程序6,中文字符是不顯示(只有空格)。
(通過getFont()返回標籤字體返回:DejaVu Sans)
當我用JAVA 7開始我的程序時,中文字符顯示正確!
當我與Java 6中開始我的計劃,中國文字中正確顯示:

的Windows(8.1)(要求通過標籤字體的getFont()返回幻覺記憶三世)!
(通過getFont()返回標籤字體返回:SansSerif)
當我用JAVA 7開始我的程序時,中文字符顯示正確!
(詢問標籤通過的getFont字體()返回:SANSSERIF)

$ JAVA_HOME/LIB /字體,(這似乎被用作後備-字體)兩者的Java版本(6 + 7)包含相同的字體。 (在兩個系統上)
字體文件具有相同的大小(Java6 + Java7)和fontconfig.properties.src也是相同的。

當我直接詢問Label(通過getFont())時,它在Windows(8.1)和我的Kubuntu(14.04)上返回「SansSerif」和「DejaVu Sans」。
(見截圖)

開始於Linux的用JAVA 6:
enter image description here

開始於Linux的用JAVA 7:
enter image description here

「SANSSERIF」 在Windows被正確顯示的字符,但是使用了哪些SansSerif-Font? MS SansSerif(唯一帶有SansSerif名稱的字體)並不包含所有這些中文字符。

編輯
和DejaVuSans一樣。
看起來DejaVu Sans沒有漢字! (但是,他們顯示!)

編輯2
我試圖安德魯發佈的代碼(參見:How to determine if 2 fonts have equivalent glyphs?),但與中國例如文本
這是結果:

開始於Linux的用JAVA 6:
enter image description here

開始在Linux上使用JAVA 7:
enter image description here

編輯3
爲reqested,這裏的字符串,我已經測試:

String s = "\u6253\u5370\u8FC7\u671F\u8BC1\u4E66\u8BB0\u5F55"; //means: 打印過期證書記錄 
JOptionPane.showMessageDialog(null, s); 

的問題是:
哪些字體(在系統上)是真正使用,我如何能找出?
在此先感謝!

+0

我不知道的你的問題的答案。 OTOH,找到哪些字體***可以顯示字符串,我建議檢查['字體。canDisplayUpTo(String)'](http://docs.oracle.com/javase/8/docs/api/java/awt/Font.html#canDisplayUpTo-java.lang.String-).. – 2014-09-04 10:40:26

+0

感謝您的建議,但與'Font.canDisplay ...'我找不到**哪個**字體被使用。 – Ben 2014-09-04 10:43:39

+0

確實如此,但你總是可以使用**的**字體** ***順便說一句 - 我想也應該可以比較'Serif'字體的'GlyphVector'和所有字體的'GlyphVector',爲那些產生相同的字形矢量的列表。但是這不是我想要投入生產應用程序的東西。因爲它可能很耗時。我無法真正看到確定特定系統上的邏輯字體映射到哪些字體的問題。如屏幕截圖所示,它們可能會在Java版本之間發生變化。 – 2014-09-04 10:49:04

回答

4

這是我自己問題的答案。

我做了一些更多的調查:
它似乎是,對於某些類型的語言(字符),使用特殊的配置。

支持Linux和Solaris 11點的字體
歷史上,JDK中的邏輯字體的fontconfig.properties 文件進行靜態指定。但是,在Linux的各種實現中,在字體的存在下不存在一致性。所以,沒有自定義文件,亞洲 (CJK)文本等,將不會呈現。在JDK 7的Linux和 Solaris 11中,如果缺少OS版本的自定義fontconfig.properties文件 ,則缺省行爲是使用系統 libfontconfig選擇用於邏輯字體的字體。在此 的情況下,邏輯字體將反映使用相同平臺庫的桌面應用程序使用的Gnome/KDE 012所使用的字體。

這是我在這裏找到: http://docs.oracle.com/javase/7/docs/webnotes/adoptionGuide/

這意味着,首先,有在Java 6中和Java 7
下一步選擇正確的字體的差異,我檢查了我(Java 6中) fontconfig的文件,我發現以下(減少到只有重要部分):

#元器件字體映象
allfonts。 中國-CN-ISO10646 = -arphic-AR PL uming CN-光-R-normal-- - %D- - -C- -iso10646-1

#字體文件名
文件名。-文鼎-ar_pl_uming_ CN -light-R-normal-- - %D- - -C- -iso10646-1 = /usr/share/fonts/truetype/arphic/uming.ttc

#檢索序列
sequence.allfonts = latin-1
sequence.allfonts。 UTF-8.zh.CN =拉丁-1- CJK,中國-CN-ISO10646
sequence.allfonts.UTF-8.zh.TW =拉丁-1- CJK,中國-TW-ISO10646
序列。 allfonts.UTF-8.zh.HK =拉丁-1- CJK,中國-HK-ISO10646

此指定的字體(這裏:uming.ttc)應被使用的,當默認字體不能顯示請求的角色。
之後,我檢查了/usr/share/fonts/truetype/arphic/uming.ttc的存在。
此字體/文件是不是禮物!
(我查了3個不同的Ubuntu的安裝!)

我不知道到底爲什麼它沒有被安裝(但在Java中的fontconfig仍然使用),但在執行後(不同的PC上,但同樣的問題):

sudo apt-get install fonts-arphic-uming 

安裝缺少字體,我再次測試(用JAVA 6):

enter image description here

伊芙現在似乎沒問題了。

(我認爲NIMS答案進入類似的方向,但它是(在我看來)過於broadly.Further,Java並沒有真正混合比賽字體。)

1

Java 7在Linux上使用fontconfig,因此它知道如何在字體丟失字形時備用。要檢查fontconfig在給定系統上使用的回退,可以使用fc- *命令(fc-match等)

但是,除了系統文件(fontconfig * xml)之外,您的jre可能還包含專用備用規則

您不能在java 6上模擬這種行爲,因爲fontconfig不是一個簡單的優先級列表,在任何給定的時間都使用單個字體。它將混合和匹配字體,具體取決於要顯示的文本的需要以及應用程序表示的偏好(字體模式)。

如果有一種字體能夠顯示在系統上顯示的文本,啓用fontconfig的軟件將始終工作。一旦應用中硬編碼的字體名稱與可用內容不匹配,應用程序將不會使用fontconfig。 Linux系統中已安裝的字體有很大的差異,你不能指望一個安裝中的字體也會出現在另一個安裝的字體中(正因爲所有的現代Linux應用程序都使用fontconfig而不關心)。

+0

*「它會根據文本的需要混合和匹配字體」*有趣。我已經開始懷疑,但沒有任何信息可以證實。 – 2014-09-05 10:51:39

+0

好的,但我有一些問題:** 1。**:我不使用任何自定義/非默認字體。 ** 2。**:我沒有對默認(java/swing)配置進行任何更改。 ** 3:**:在Windows中,在Java 6和Java 7之間顯示中文字體時沒有問題。 – Ben 2014-09-05 10:54:50

+0

Windows字體列表通常非常統一,因爲它的速度非常緩慢,並且受到Microsoft使用專有技術的限制字體。它的桌面根目錄意味着默認安裝可能捆綁比Linux服務器更多的字體。因此,舊的「使用硬編碼字體列表」Java 6方法不太可能導致此平臺上的錯失。 (也是由SUN生產的Java 6,SUN唯一關心的桌面平臺是Windows,因爲沒有人再使用Solaris作爲桌面了,它永遠不會承認Linux吃了它的蛋糕,SUN已經提出了一個沒有人採用fontconfig的競爭者)。 – nim 2014-09-05 11:33:18