Swing弹出框的多语言支持

客户的需求是,在Swing的弹出框里面显示俄文,比如Yes显示为Да(这特么是个啥)。话说现在真没什么人研究swing了,苦的一比。

看了一下在启动swing界面之前使用
Locale.setDefault(Locale.CHINA);

就可以设置当前语言。

同样,在读源码后发现可以通过以下方式设置JComponent的默认Locale
AppContext.getAppContext().put("JComponent.defaultLocale", locale);


结果发现JAVA Swing原生不支持通过设置Locale的方式把俄文显示在对话框上(没细查JDK是不是有全语言文字版本,我本机的JDK只有CN,de,es,fr,it,ja,ko,sv等语言,可看后文详解。)
同时,我死活没有找到这些显示的文字,例如"是(Y)","否(N)","Yes"之类的是在哪里放进去的。

这个问题只好一步一步反向查找了,切入点还是JButton的setText() jdk7U45

1. 断点在AbstractButton的setText(),发现传进来的文本实际上是由BasicOptionPaneUI$ButtonFactory工厂持有的

2.再断点在BasicOptionPaneUI$ButtonFactory的构造方法上,发现这个text是通过UIManager.getString("OptionPane.yesButtonText", l)方法生成的,l这个变量就是一个locale。

**********分割线****************
这里其实已经能解决问题了,UIManager提供了put方法,按照key把应该显示的值存进去就行了,但是作为刨根问底的程序猿,你能不往下看么?
******************************

3.这个值是啥时候放进UIManager的?

4.读UIManager的代码发现,这其实是个Cache的管理者,真正的缓存都放在了UIDefaults类里。可以看到UIDefaults是个容器:
public class UIDefaults extends Hashtable<Object,Object>


5.还是要问了,UIDefaults什么时候设置的这个值?

6.断点在HashTable里。。。启动时候反向查了半天,终于有了端倪。

7.UIDefault里面有个resourceBundles,一看到bundle就联想到了国际化,所以断点到了UIDefault.addResourceBundle()

8.终于找到了com.sun.swing.internal.plaf.basic.resources.basic,以及同目录下的其他语言资源(这个类一看就是个sonar issue,说好的首字母大写呢)。

9.比较坑的是在JDK的rt源码调试时候,局部变量都是不可见的,并且传递参数都是以arg0,arg1这种形式显示在variable里面的。原因是下载的JDK默认编译都没加调试信息,所以调试起来比较痛苦。

10.解决方法可以利用JAVA_HOME的src.zip自己做个rt.jar,加上参数生成调试信息,帖子可以见R大的回帖:
http://hllvm.group.iteye.com/group/topic/25798#182845

和另外一个帖子:
http://zhaohaolin.iteye.com/blog/1887538

====完====

猜你喜欢

转载自wwwcomy.iteye.com/blog/2197456