`
run_xiao
  • 浏览: 194840 次
  • 性别: 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  
看不懂,代码测试过吗?????

相关推荐

    swing组件介绍(一)

    9. **国际化支持**:Swing内置了对多语言的支持,允许开发者轻松地创建支持不同语言的应用程序。 10. ** Swing Utility 类**:如JOptionPane和JFileChooser,它们提供了对话框和文件选择器等便捷功能。 综上所述,...

    Swing 组件大全

    Swing组件大全是一个深入探讨Java Swing库的资源,它涵盖了Swing提供的几乎全部组件,同时结合了数据库操作和第三方库jxl与TableLayout的使用。Swing是Java Foundation Classes (JFC)的一部分,用于构建图形用户界面...

    java Swing用户界面组件

    Swing还提供了一些AWT不具备的特性,如内置的国际化支持、可定制的外观和主题(LookAndFeel)、以及丰富的事件处理机制。 1. **容器组件**:Swing中的容器组件,如JFrame、JPanel、JScrollPane等,用于容纳其他组件...

    基于Java的开源的Swing组件 JIDE.zip

    **Java Swing组件与JIDE库** Java Swing是Java标准版(Java SE)的一部分,它提供了一组用于构建桌面应用程序的用户界面组件。Swing库基于Java AWT(Abstract Window Toolkit),但提供了更丰富的特性和更好的跨...

    基于java的开源的Swing组件 JIDE.zip

    7. **国际化支持**:JIDE组件库内置了对多语言的支持,方便开发者构建全球化应用。 8. **性能优化**:JIDE组件在设计时考虑了性能,通过高效的内存管理和渲染机制,确保了在处理大量数据时的流畅性。 9. **文档和...

    深入学习jfc swing组件

    8. **国际化与可访问性**: Swing支持应用程序的国际化,可以轻松地为不同语言的用户提供本地化界面。同时,它也考虑了可访问性,使视障用户也能通过屏幕阅读器等辅助工具使用应用。 9. **NimbusLookAndFeel**: ...

    Swing用户界面组件

    - **国际化**:Swing支持多语言,可以轻松地创建面向不同地区用户的程序。 - **可访问性**:Swing组件遵循无障碍标准,方便特殊需求的用户使用。 - **模型-视图-控制器**(MVC)架构:Swing组件遵循这一设计模式...

    swing自制组件(一)

    5. **国际化支持**:对于多语言应用,组件可能集成了i18n(国际化)功能,能根据用户设置显示不同语言的内容。 6. **可扩展性**:可能设计为一个可扩展的框架,允许其他开发者添加更多的功能或特性。 在源码分析...

    Java Swing组件实现的日历程序

    最后,国际化与可定制性:为了适应不同的语言环境,日历程序可能需要支持多语言。Java的ResourceBundle类可以帮助我们实现这一点。同时,用户可能希望自定义日历的颜色、字体等,这可以通过提供配置选项或使用Look...

    用swing组件做的餐饮管理系统

    10. **国际化支持** Swing支持资源包(Resource Bundle)机制,便于实现软件的多语言版本。只需为不同语言创建对应的资源配置文件,即可轻松切换系统语言。 总的来说,Swing组件为开发餐饮管理系统提供了强大的...

    浅析使用模型参数构造Java Swing组件.zip

    综上所述,“浅析使用模型参数构造Java Swing组件”这一主题涵盖了Swing组件的核心概念,包括模型、视图、事件处理、组件定制、布局管理、国际化以及并发处理。理解和掌握这些知识点,对于开发高效、用户友好的Java...

    java swing可视化插件

    1. **组件扩展**:提供更多的自定义组件,比如高级图表、日历控件、树形视图等,丰富了标准Swing组件库。 2. **布局管理**:更直观的布局管理工具,允许开发者在设计时预览组件的布局和排列。 3. **代码生成**:将...

    浅析Java swing组件窗体设计.zip

    Swing组件都是轻量级的,它们运行在Java虚拟机上,因此具有跨平台的特性。 二、容器与布局管理器 在Swing中,组件通常放置在容器(Container)内,容器可以包含其他组件或容器。JFrame是Swing中最常见的顶级容器,...

    Java Swing组件

    6. **国际化与本地化**:Swing支持多语言应用,通过ResourceBundle类可以方便地实现应用程序的国际化和本地化。 7. **工具栏(JToolBar)**:JToolBar组件可以用来创建工具栏,放置常用的按钮或菜单项,提高用户...

    JFC SWING—JAVA 基础类组件集

    此外,Swing 支持国际化和可访问性,使得应用程序能适应不同语言环境和满足特殊用户需求。 在深入学习:JFC SWING—JAVA 基础类组件集.pdf 中,你将找到关于这些组件和概念的详细讲解,包括它们的用法、属性、方法...

    swing学习心得资料

    此外,Swing还提供了一些高级特性,如模型-视图-控制器(MVC)设计模式的实现、模态对话框、JTable和JTree等复杂组件,以及国际化(i18n)支持。JTable允许用户显示和编辑表格数据,而JTree则用于展示层次结构的数据。 ...

    如何在SWT中使用AWT、SWING组件

    然而,AWT和SWING提供了更多的组件和功能,例如丰富的布局管理器和内置的国际化支持。 **AWT基础知识** AWT是Java最早提供的GUI库,它基于组件模型,包含基本的窗口、按钮、文本框等组件。AWT的优势在于其轻量级,...

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

    JFC Swing的高级特性还包括对键盘快捷键的支持、对国际化和本地化(i18n/l10n)的支持,这些特性让Swing的应用程序能够适应不同文化和语言环境。 通过阅读和学习《深入学习:JFC Swing-Java基础类组件集》,开发者...

Global site tag (gtag.js) - Google Analytics