javaGUI字体讨论

我们知道java有5种逻辑字体,分别是 SerifSanserifMonospaceDialog 以及 DialogInput。当你在程序中比如

UIDefaults ui = UIManager.getLookAndFeelDefaults();

ui.put("TextArea.font", new FontUIResource("DialogInput", Font.BOLD, 14));

 

这样你对所有TextArea默认的字体设置成DialogInput了,但是DialogInput到底对应什么字体呢?这就取决于你的程序所在JRE的情况了,

$JRE_HOME/lib/fontconfig.properties.*文件定义了这5种逻辑字体分别映射到哪些具体的字体,不同的平台下情况可能不同,你当然也可以修改这个配置。

如果这个配置文件定义某个具体字体不存在,那么你的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]
ComboBox.font:javax.swing.plaf.FontUIResource[family=Dialog,name=Dialog,style=bold,size=12]
ScrollPane.font:javax.swing.plaf.FontUIResource[family=Dialog,name=Dialog,style=plain,size=12]
Spinner.font:javax.swing.plaf.FontUIResource[family=Dialog,name=Dialog,style=bold,size=12]
RadioButtonMenuItem.font:javax.swing.plaf.FontUIResource[family=Dialog,name=Dialog,style=bold,size=12]
Slider.font:javax.swing.plaf.FontUIResource[family=Dialog,name=Dialog,style=bold,size=12]
EditorPane.font:javax.swing.plaf.FontUIResource[family=Dialog,name=Dialog,style=plain,size=12]
OptionPane.font:javax.swing.plaf.FontUIResource[family=Dialog,name=Dialog,style=plain,size=12]

。。。。。。。。。。。。。。。。。。。。。

都是Dialog字体,如果我在加一行代码:UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

我是在Windows环境下,所以应该得到Windows的LookAndFeel。

这时再遍历发现:

ToggleButton.font:javax.swing.plaf.FontUIResource[family=SimSun,name=宋体,style=plain,size=12]
ComboBox.font:javax.swing.plaf.FontUIResource[family=SimSun,name=宋体,style=plain,size=12]
ScrollPane.font:javax.swing.plaf.FontUIResource[family=SimSun,name=宋体,style=plain,size=12]
Spinner.font:javax.swing.plaf.FontUIResource[family=SimSun,name=宋体,style=plain,size=12]
RadioButtonMenuItem.font:javax.swing.plaf.FontUIResource[family=SimSun,name=宋体,style=plain,size=12]
Slider.font:javax.swing.plaf.FontUIResource[family=SimSun,name=宋体,style=plain,size=12]
EditorPane.font:javax.swing.plaf.FontUIResource[family=SimSun,name=宋体,style=plain,size=12]
OptionPane.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组件这个问题我也不清楚,有人是否能解释一下呢?其实关于字体,这里说的还不够,真希望有更全面的解释一下这个主题。

 

 

 

 

 

 

你可能感兴趣的:(javaGUI字体讨论)