锁定老帖子 主题:javaGUI字体讨论
精华帖 (3) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-07-22
我们知道java有5种逻辑字体,分别是 UIDefaults ui = UIManager.getLookAndFeelDefaults(); ui.put("TextArea.font", new FontUIResource("
这样你对所有TextArea默认的字体设置成
如果这个配置文件定义某个具体字体不存在,那么你的java程序字符显示就会出现”口口口口口口口口口口口口“。所以有时候一个程序某些平台上跑的好好的, 到另一个平台就会出现”口口口口口口口口口口口口“。 现在假设您直接设置某个具体字体,而不是逻辑字体,那么当然你就没有映射的问题,比如 UIDefaults ui = UIManager.getLookAndFeelDefaults(); ui.put("TextArea.font", new FontUIResource("Comic Sans MS", Font.BOLD, 20)); 但是这样,如果你的目标平台上没有Comic Sans MS,也会出现”口口口口口口口口口口口口“,另外,一种字体也是有它对应支持的字符集的而不是什么字符都能支持的,比如"Comic Sans MS”这种字体不能支持中文,所以即使你的系统存在"Comic Sans MS"字体,但是在TextArea输入中文的时候也会出现”口口口口口口口口口口口“。 那么如果我打开NetBeans,画了个画面,不做什么设置,然后运行,一切OK,这时是什么字体呢? 获得 UIDefaults ui = UIManager.getLookAndFeelDefaults();然后遍历发现: ToggleButton.font:javax.swing.plaf.FontUIResource[family=Dialog,name=Dialog,style=bold,size=12] 。。。。。。。。。。。。。。。。。。。。。 都是Dialog字体,如果我在加一行代码:UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 我是在Windows环境下,所以应该得到Windows的LookAndFeel。 这时再遍历发现: ToggleButton.font:javax.swing.plaf.FontUIResource[family=SimSun,name=宋体,style=plain,size=12] 。。。。。。。。。。。。。。。。。。。。。 是宋体,是一个具体字体而不是逻辑字体,说明Swing几个内置的实现几个主要系统的LookAndFeel,会设置对应系统常用字体,比如因为我是 Windows系统所以配了宋体,想必只要是中文Windows系统不可能没有宋体吧。 现在很多人写的Swing程序,一般也不会特地去设定自己的字体,而是没设,然后一般又会加载当前系统的LookAndFeel,所以会写上一句 UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 但是听说有些Swing程序在Windows好的到了其他环境出现”口口口口口口口口口口口口“,如果是以上的写法(没有特地设置过字体),那么按理说 会设置对应系统常用字体,如果因为目标系统没有这个字体,而出现”口口口口口口口口口口口口“,对于Swing对应LookAndFeel的实现来说一定找的是 常用字体,为何目标系统会缺乏呢?是目标系统的错还是java的错?java对于常用字体的判定错误?我就不清楚了。
所以理论上来说如果我不设置字体,并且写UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());那么对应LookAndFeel会设定一个默认对应系统的常用字体,如果实现的好,那么确实是运行各个环境都没有问题。但是现实是没有那么完美。当然还有很多第三方LookAndFeel,他们对于UIDefaults的设置是什么,可以通过 UIManager.getLookAndFeelDefaults();获得。
这上面说的是Swing,但是AWT组件默认的字体是怎样决定呢?这个本来也真没想管它,因为本更不会去用AWT组件,但是当我要做系统托盘图标的时候发现问题来了,因为SystemTray st = SystemTray.getSystemTray();然后st可以加入TrayIcon,而TrayIcon只能放PopupMenu,注意是PopupMenu而不是JPopupMenu,所以是AWT组件,然后构造MenuItem放入PopupMenu,如果传入MenuItem的是中文字符,结果运行点击托盘图标时菜单出现”口口口口口口“了。我调用item.getFont()查看字体,但是MenuItem返回的是null,这下我不解了,查查资料也没有结果,所以关于AWT组件这个问题我也不清楚,有人是否能解释一下呢?其实关于字体,这里说的还不够,真希望有更全面的解释一下这个主题。
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-07-23
关于MenuItem中文字符”口口口口口口“问题来源我找到了,我的源代码文件是UTF-8在Eclipse里面改为GBK后,再运行能正常显示中文,我觉得这很奇怪,为什么要判定我的源代码文件编码方案呢?
我再改回UTF-8,然后打包出去,然后运行打包后的jar,发现没有问题,可以显示,但是如果在Eclipse里面运行就会有”口口口口口口“,这下我晕了,这是为什么啊?难道Eclipse依据我的源代码编码方案向VM传了什么参数,然后AWT依据这个参数的设置来处理,然后出现了问题”口口口口口口“。毕竟打包出去的jar没有”口口口口口口“。 Swing的组件是没有这个问题的,AWT的机制到底是怎样的呢? 望诸位解释解释啊。 |
|
返回顶楼 | |
发表时间:2009-07-24
又有了一些进展,原来对源代码文件的编码方案设定会影响java的“file.encoding”属性,自然也就影响到比如String的getbytes()方法的结果,getbytes()方法的文档里面解释似乎是依据本地平台的编码方案进行Byte化,我一开始理解为就是按本地操作系统的字符集来byte化,但是实际上不一定,因为VM启动时有个参数可以设定的,就是-Dfile.encoding=XXX ,而IDE开发环境似乎会根据你的源代码文件的编码方案来对VM设定这个参数,但是如果你强行设定了这个参数,那么就以你设定的为准。
所以我源代码编码方案还是“UTF-8”,但是我VM启动参数里面加了这一行-Dfile.encoding=GBK,那么运行结果最后也是正常的。可见AWT机制相当粗糙,它可能会对字符串直接getbytes(),然后会将这堆bytes再调用本地操作系统API,比如我在Windows上的话,本地操作系统的当前字符集是GBK,而这堆Bytes是以UTF-8编码的,windows的API如果以GBK解它的话,自然也就完蛋了。 |
|
返回顶楼 | |
发表时间:2009-07-24
其实这也引出了另外一个问题,就是java到底如何获得本地操作系统的当前字符集而不仅仅是java VM的当前字符集?因为java VM的当前字符集完全可以在VM启动时设定的,它很可能和本地操作系统不一致。
|
|
返回顶楼 | |
发表时间:2010-07-20
系统托盘我也遇到过,一直没有解决。
|
|
返回顶楼 | |
浏览 5917 次