`
run_xiao
  • 浏览: 192420 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

Swing组件国际化

    博客分类:
  • Java
阅读更多
很长一段时间一直在做Applet开发,前不久客户提出要做界面的国际化。我也有一直思考这个问题,Java本身对国际化支持很好的,最简单的方式就是在创建每个Component之前,把文本就国际化然后再塞给这个组件。例如:(resources是根据Locale读入的ResourceBundle)
java 代码
  1. JFrame frame = new JFrame();   
  2. frame.setTitle(resources.getString("Title"));   
这样做实在太不雅,另外也无法在运行时随着Locale改变而改变界面的语言。
在网上看到一篇文章http://www.progdoc.de/papers/intSwing/intswing/intswing.html,提到一种很有趣的做法,通过设置每个组件的ComponentUI,在ComponentUI渲染该组件之前,把文本国际化。
先介绍一下ComponentUISwing组件是基于MVC模式的,但同经典的MVC有点不一样,SwingViewController合并到同一个委托对象中:ComponentUI,该对象都有paint()方法负责渲染其关联的组件。
那么怎么知道每个组件用的什么ComponentUI来画这个组件呢?有一个叫UIManager的大总管来负责设置整个界面的样式,通过setLookAndFeel(LookAndFeel)方法设置LookAndFeel,而LookAndFeel的实现中即包括对所有组件的ComponentUI的设置。
例如:Windows风格的界面
java 代码
  1. public class WindowsLookAndFeel extends BasicLookAndFeel{   
  2.              protected void initClassDefaults(UIDefaults table){   
  3.                     super.initClassDefaults(table);   
  4.     
  5.                     final String windowsPackageName = "com.sun.java.swing.plaf.windows.";   
  6.     
  7.                     Object[] uiDefaults = {   
  8.                        "ButtonUI", windowsPackageName + "WindowsButtonUI",   
  9.                          "CheckBoxUI", windowsPackageName + "WindowsCheckBoxUI",   
  10.                                  "CheckBoxMenuItemUI", windowsPackageName + "WindowsCheckBoxMenuItemUI",   
  11.                               "LabelUI", windowsPackageName + "WindowsLabelUI",   
  12.                             "RadioButtonUI", windowsPackageName + "WindowsRadioButtonUI",   
  13.                                     "RadioButtonMenuItemUI", windowsPackageName + "WindowsRadioButtonMenuItemUI",   
  14.                    ……  
设置渲染Button使用WindowsButtonUI,画Label使用WindowsLabelUI…..等等
所以我们要定制自己的国际化控件继承WindowsLookAndFeel,然后重载initClassDefaults方法,在其中插入自己指定的ComponentUI
java 代码
  1. public class MLWindowsLookAndFeel extends WindowsLookAndFeel {   
  2.     protected void initClassDefaults(UIDefaults table) {   
  3.         super.initClassDefaults(table);   
  4.         Object[] classes = {   
  5.                            "LabelUI", mlPackage + "MLWindowsLabelUI",   
  6.                                                         ………………   
  7.         };   
  8.         table.putDefaults(classes);   
  9.     }   
  10. }  
这样任何一个JLabel显示的时候都调用我们自定义的MLWindowsLabelUI中的paint()方法
我们就可以在这个地方做手脚了
java 代码
  1. public class MLWindowsLabelUI extends WindowsLabelUI {   
  2.     private final static MLWindowsLabelUI ML_WINDOWSLLABEL_UI = new  
  3.             MLWindowsLabelUI();   
  4.     /**  
  5.      * 必须重载该方法,因为UIManager会调用该方法获得其实例,所以不重写会获得其父类的实例  
  6.      * @param c JComponent  
  7.      * @return ComponentUI  
  8.      */  
  9.     public static ComponentUI createUI(JComponent c) {   
  10.         //因为树上的Cell和下拉框中显示也用了Label控件,但其无需国际化,返回其父类的实例   
  11.         if(c instanceof TreeCellRenderer ||c instanceof ListCellRenderer){   
  12.             return new WindowsLabelUI();   
  13.         }   
  14.         return ML_WINDOWSLLABEL_UI;   
  15.     }   
  16.     /**  
  17.      * 在格式化Label的文本前,将其国际化,再调用父类的格式文本方法,  
  18.      * 若在这之后重载其他方法以实现国际化会不正确,因为已格式化的文本可能跟原来不一样  
  19.      * 比如过长的文体会用...代替  
  20.      */  
  21.     protected String layoutCL(JLabel label,FontMetrics fontMetrics,String text,Icon icon,Rectangle viewR,Rectangle iconR,Rectangle textR) {   
  22. return super.layoutCL(label,fontMetrics,MessageUtil.getMessage(text),icon,viewR,iconR, textR);   
  23.     }   
  24. }  
有两个地方需要注意的:首先必须重载父类的createUI方法,否则当调用该类的createUI是返回的还是父类的实现,所以不会有任何效果,因为这个我Debug了好长时间。
再就是,我们也并不会真的去重载paint()方法,因为要画一个控件是个很麻烦的事情,我们只需要找出其画需要的文本的那个方法然后重载,调用其父类对应方法传入已国际化的文本就OK了。当然要找出合适的方法重载也有点麻烦,需要大概把paint()执行流程通读一边。对于Label,我之前是重载paintEnabledText(),但发现当Label长度不够时,文本就会变成省略号,结果以这个为Key去查资源文件肯定不对,所以要找到合适的方法可能需要反复试验。
使用直接继承的方式,现在只能局限于Windows风格的界面,可考虑使用装饰模式,我们的LookAndFeel直接继承BasicLookAndFeel,然后构造方法中传入另一个LookAndFeel的实例,将其他方法的实现都委托给该LookAndFeelLabelUI也使用同样的方式。这样应该就可适用于其他风格的界面了。
分享到:
评论
1 楼 sknice 2013-01-23  
看不懂,代码测试过吗?????

相关推荐

    java(awt/swing)局域网即时聊天源码

    运用面向对象编程,继承、封装和多态等,Java语言的基本语法,Java IO;多线程编程,网络编程,序列化,反射,程序国际化;基本的界面编程(AWT和Swing)等基础知识。是学习java基础的一个极好案例。

    深入学习:jfc swing—java 基础类组件集.rar

    国际上,在选择编程语言时,无论是编程者还是决策者都会首选Java,因为其程序可商品化,可以被更多人、更多系统所用。目前,介绍Java编程的书很多,但深层次的书较少,而编程者,特别是有经验的编程者恰恰希望阅读或...

    深入学习:JFC Swing——Java基础类组件集

    国际上,在选择编程语言时,无论是编程者还是决策者都会首选Java,因为其程序可商品化,可以被更多人、更多系统所用。目前,介绍Java编程的书很多,但深层次的书较少,而编程者,特别是有经验的编程者恰恰希望阅读或...

    JChess:一个简单的 Java 国际象棋游戏

    它使用 Java 的 Swing 库作为可视化组件,可能违反了大多数代码质量指南和 OOP 原则,因为我最近才开始学习这些。 从好的方面来说,我认为评论很好地解释了正在发生的事情。 从我的测试来看,它应该能够正确地执行...

    Java SE实践教程 源代码 下载

    第10章 准备环球旅行——应用程序国际化 243 10.1 讲解 244 10.1.1 概念介绍 244 10.1.2 设置Locale 249 10.1.3 隔离语言环境相关数据 252 10.1.4 格式化 258 10.2 练习 266 10.2.1 对单独的文件进行国际化 ...

    Java SE实践教程 pdf格式电子书 下载(一) 更新

    第10章 准备环球旅行——应用程序国际化 243 10.1 讲解 244 10.1.1 概念介绍 244 10.1.2 设置Locale 249 10.1.3 隔离语言环境相关数据 252 10.1.4 格式化 258 10.2 练习 266 10.2.1 对单独的文件进行国际化 ...

    Java SE实践教程 pdf格式电子书 下载(四) 更新

    第10章 准备环球旅行——应用程序国际化 243 10.1 讲解 244 10.1.1 概念介绍 244 10.1.2 设置Locale 249 10.1.3 隔离语言环境相关数据 252 10.1.4 格式化 258 10.2 练习 266 10.2.1 对单独的文件进行国际化 ...

    java jdk-api-1.6 中文 chmd

    java.util 包含 collection 框架、遗留的 collection 类、事件模型、日期和时间设施、国际化和各种实用工具类(字符串标记生成器、随机数生成器和位数组)。 java.util.concurrent 在并发编程中很常用的实用工具类...

    java图书馆swing源码-chess-java:为Penn的CIS120课程构建的简单JavaChess游戏

    java图书馆swing源码国际象棋 Java 2014 年Spring,我在宾夕法尼亚大学的编程课程中创建了一个两人国际象棋游戏,其中包含将死检测和国际象棋时钟。 我们的目标是用 Java 开发和测试无错误的独立游戏,并配有 GUI 和...

    IBM-JAVA教程

    第十章 国际化和 Applet.ppt 第十一章 输入输出处理——流的处理.ppt 第十二章 输入输出处理——文件操作.ppt 第十三章 输入输出处理——网络编程.ppt 第十四章 多线程.ppt 第十五章 异常(Exception)处理.ppt

    JAVA_API1.6文档(中文)

    java.util 包含 collection 框架、遗留的 collection 类、事件模型、日期和时间设施、国际化和各种实用工具类(字符串标记生成器、随机数生成器和位数组)。 java.util.concurrent 在并发编程中很常用的实用工具类...

    JAVA核心技术第八版(上下卷)全部源码

    高级特征》是Java技术权威指南,全面覆盖Java技术的高级主题,包括流与文件、XML、网络、数据库编程、高级Swing、高级 AWT、JavaBean构件、安全、分布式对象、脚本、编译与注解处理等,同时涉及本地化、国际化以及...

    JIDE Grids (表格)开发员技术手册

    DateComboBox and DateChooserPanel - 一套月份/日期选择控件,从面板选择到组合框,到单元格编辑,支持国际化和本地化(i18n和l10n) AbstractComboBox - 支持用任何控件做弹出式面板 FilterableListModel - 支持...

    Java2核心技术.part5

    Java2核心技术第I卷.基础知识 目录: 译者序 前言 第1章Java程序设计概述 ...1.1 Java程序设计平台 ...1.2 Java“白皮书”的关键术语 ...7.1 Swing概述 ...第10章 国际化 第11章 本地方法 第12章 XML 第13章 注释

    Java2核心技术.part3

    Java2核心技术第I卷.基础知识 目录: 译者序 前言 第1章Java程序设计概述 ...1.1 Java程序设计平台 ...1.2 Java“白皮书”的关键术语 ...7.1 Swing概述 ...第10章 国际化 第11章 本地方法 第12章 XML 第13章 注释

    Java2核心技术.part1

    Java2核心技术第I卷.基础知识 目录: 译者序 前言 第1章Java程序设计概述 1.1 Java程序设计平台 1.2 Java“白皮书”的关键术语 1.2.1简单性 ...第10章 国际化 第11章 本地方法 第12章 XML 第13章 注释

    Java2核心技术.part6

    Java2核心技术第I卷.基础知识 目录: 译者序 前言 第1章Java程序设计概述 ...1.1 Java程序设计平台 ...1.2 Java“白皮书”的关键术语 ...7.1 Swing概述 ...第10章 国际化 第11章 本地方法 第12章 XML 第13章 注释

    Java2核心技术.part4

    Java2核心技术第I卷.基础知识 目录: 译者序 前言 第1章Java程序设计概述 ...1.1 Java程序设计平台 ...1.2 Java“白皮书”的关键术语 ...7.1 Swing概述 ...第10章 国际化 第11章 本地方法 第12章 XML 第13章 注释

    Java2核心技术.part2

    Java2核心技术第I卷.基础知识 目录: 译者序 前言 第1章Java程序设计概述 ...1.1 Java程序设计平台 ...1.2 Java“白皮书”的关键术语 ...7.1 Swing概述 ...第10章 国际化 第11章 本地方法 第12章 XML 第13章 注释

    java api最新7.0

    java.util 包含 collection 框架、遗留的 collection 类、事件模型、日期和时间设施、国际化和各种实用工具类(字符串标记生成器、随机数生成器和位数组)。 java.util.concurrent 在并发编程中很常用的实用工具类。...

Global site tag (gtag.js) - Google Analytics