我在swing应用程序中显示unicode字符时出现问题
认为问题是使用的字体,它不包含适合中文的字符
(仅显示空框)
以下是我的问题的更多信息(我做了一些调查):
Linux(Kubuntu 14.04):
当我用JAVA 6开始我的程序时,中文字符不显示(仅空框)。
(通过getFont()询问标签字体返回:DejaVu Sans)
当我用JAVA 7启动程序时,中文字符显示正确!
(通过getFont()询问标签字体返回:DejaVu Sans)
Windows(8.1):
当我用JAVA 6开始我的程序时,中文字符显示正确!
(通过getFont()询问标签字体返回:SansSerif)
当我用JAVA 7启动程序时,中文字符显示正确!
(通过getFont()询问标签字体返回:SansSerif)
$ JAVA_HOME / lib / fonts,(似乎用作fallback-font)两个java版本(6 + 7)都包含相同的字体。 (在两个系统上)
字体文件大小相同(Java6 + Java7),fontconfig.properties.src也相同。
当我直接询问Label(通过getFont())时,它返回" SansSerif"在Windows(8.1)和" DejaVu Sans"在我的Kubuntu(14.04)上
(见截图)
使用JAVA 6在Linux上启动:
使用JAVA 7在Linux上启动:
" SANSSERIF"在Windows上正确显示字符,但使用哪个SansSerif-Font? MS SansSerif(名称中唯一一个带有SansSerif的字体)没有所有这些中文字符。
修改:
与DejaVuSans相同。
看起来DejaVu Sans没有中文字符! (但是,它们会显示出来!)
编辑2 :
我尝试了安德鲁发布的代码(参见:How to determine if 2 fonts have equivalent glyphs?),但中文示例文字为
这是结果:
使用JAVA 6在Linux上启动:
使用JAVA 7在Linux上启动:
编辑3 :
如需要,这里是我测试过的字符串:
String s = "\u6253\u5370\u8FC7\u671F\u8BC1\u4E66\u8BB0\u5F55"; //means: 打印过期证书记录
JOptionPane.showMessageDialog(null, s);
问题是:
实际使用了哪种字体(在系统上)以及如何找到?
提前谢谢!
答案 0 :(得分:5)
这是我自己的问题的答案。
我做了一些调查:
似乎是,对于某些类型的语言(字符),使用了特殊配置。
支持Linux和Solaris 11字体
从历史上看,JDK的逻辑字体是在fontconfig.properties中静态指定的 文件。但是,在Linux的各种实现上,没有 存在字体时的一致性。因此,没有自定义文件,亚洲 (CJK)文本等不会呈现。在JDK 7中,在Linux上,以及 Solaris 11,没有自定义的fontconfig.properties文件 对于OS版本,默认行为是使用系统 libfontconfig选择用于逻辑字体的字体。在这 例如,逻辑字体将反映Gnome / KDE使用的字体 使用相同平台库的桌面应用程序。
这是我在这里找到的: http://docs.oracle.com/javase/7/docs/webnotes/adoptionGuide/
这意味着首先,在Java 6和Java 7中选择正确的字体存在差异。
接下来,我检查了我的(java 6)fontconfig文件,我发现了以下内容(仅限于重要部分):
#Component Font Mappings
allfonts。 chinese-cn-iso10646 = - arphic-ar pl uming cn-light-r-normal - - %d - - -c - -iso10646-1#Font文件名
filename.-文鼎-ar_pl_uming_的 CN 强> -light-R-正常 - - %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
sequence.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):
现在一切似乎都还可以。
(我认为nims的答案是朝着类似的方向发展的,但它(在我看来)过于广泛。此外,java并不是真的混合和匹配字体。)
答案 1 :(得分:1)
Java 7在Linux上使用fontconfig,因此它知道在字体缺少字形时如何回退。要检查fontconfig在给定系统上使用的回退,您可以使用fc- *命令(fc-match等)
然而,除了系统规则之外,你的jre可能还包括私有备用规则(fontconfig * xml)
您无法在java 6上模拟此行为,因为fontconfig不是一个简单的优先级列表,其中在任何给定时间使用单个字体。它将混合和匹配字体,具体取决于要显示的文本的需要和应用程序表示的首选项(字体模式)。
如果有一种字体能够显示系统上存在的文本,则启用fontconfig的软件将始终有效。只要应用程序中硬编码的字体名称与可用的字体名称不匹配,不使用fontconfig的应用程序就会失败。 Linux系统上已安装的字体存在巨大差异,您不能指望一个安装中存在的字体也会出现在另一个安装中(正因为所有现代Linux应用程序都使用fontconfig而不关心)。