赛迪网 > IT技术 技术应用子站 > 文章
  IT资讯搜索
 
IT产品搜索
[程序开发][网管世界][网络安全][数据库技术]
[操作系统][嘉宾聊天·在线访谈][活动集锦]
[精彩专题][Symantec专区][订阅IT技术周刊]
[开发论坛][网管论坛][安全论坛][数据库论坛]
[操作系统论坛][Sybase专区][IBM dW技术专区]
[病毒求助][病毒与漏洞播报][文档·源码下载]

Java用户界面本地化实例讲解

发布时间:2005.10.27 17:14     来源:赛迪论坛    作者:E剑

国际化是使程序具有足够的灵活性、能在世界上任何地区运行的过程。国际化所要求的必然结果是地方化――使一个程序能够运行在特定地区的过程。本文尝试用一个简单的例子来演示Java用户界面本地化。Java语言内核基于Unicode3.0(Java 1.4)提供了对不同国家和不同语言文字的内部支持,由于先天的原因,Java对于国际化的支持远远要比C/C++来的优越。

     在我看来本地化必须满足以下的三个条件:

     1、程序必须能读、写和操作本地化的文本。

     2、程序在显示日期和时间、使数字格式化以及排序子串时,必须符合地方习惯。(通过java.text包里面的类可以实现这些要求)

     3、所有用户可见的文本都能在运行时获得,而不是直接写入程序中。(通过java.util包里的ResourceBundle类和他的子类可以实现这些要求。)

     实现这三个方面可以真正实现程序的国际化。

     首先让我们来了解一下地区。地区代表一个地理上、政治上或文化上的区域。在Java中,地区由java.util.Locale类表示。地区常常以一种语言来定义,该语言则由其标准的小写双字母代码表示。(例如:en代表英国,fr代表法国,zh代表中国),但有时候语言是不能代表一个地区的,那就要在语言后面再加上一个国家或该国家的地域(例如:en_US代表美国,zh_TW)。Locale类保存着一个静态的默认地区,它可以用Locale.setDefault()和Locale.getDefault()来设置和查询。一个程序可以生成和使用任意数目的非默认Locale对象。

     让我们再来看一下Unicode字符编码。Java使用Unicode的字符编码,其本身就是迈向国际化的一大步。Unicode编码其每个字符都占两个字节。用\u****的形式表示。Unicode的字符可以等价于其他编码的字符(例如:从\u0020到\u007E的字符等价于ASCII和ISO8859-1字符的0x20到0x7E)。

     本文主要是对用户界面地方化,由于我使用的是资源束!所以有必要对资源束作一下解释。

     为定义一束地方化的资源,你需要生成一个ResourceBundle(资源束)的子类并且提供handleGetObject()和getKeys()方法的定义。为了在程序中使用来自ResourceBundle的地方化资源,就需要先调用静态的getBundle()方法,用getBundle()获得一个ResourceBundle对象,然后再用getObject()方法去按照名字来查找资源。当然也可以使用getString()简单的把getObject()的返回值分配给一个String对象。GetBundle()方法采用basename_language_country_variait----没找到的话->basename_language_country----没找到的话->basename_language----没找到的话->basename(默认资源文件)的算法寻找合适的资源。如果以上都没找到的话,则会抛出一个MissingResourceException异常。

     现在我们来看一个简单的例子,如何使Java程序用户界面地方化的。

     首先我们的程序需要查找特定Locale对象关联的资源包,所以应该定义一个Local对象,来获取本地默认的地区!然后可以调用ResourceBundle的getBundle方法,并将locale对象作为参数传入。

     清单一:   

Locale locale = Locale.getDefault(); //获取地区:默认
  //获取资源束。如未发现则会抛出MissingResourceException异常
  ResourceBundle bundle = ResourceBundle.getBundle("Properties.Dorian",locale);

    

  清单一中的”Properties.Dorian”代表Properties包下以Dorian命名的默认资源文件。这样就可以使用资源文件了!让我们来看看资源文件是如何定义的。

  

  清单二:

  

  # Dorian.properties是默认的"Dorian"资源束文件。

  # 作为中国人,我用自己的地区作为默认

  

Title=\u4e2d\u56fd;
  red.label=\u7ea2\u8272;
  green.label=\u7eff\u8272;
  blue.label=\u84dd\u8272;
  

  

  清单三:

  

  # 文件Dorian_en_US.properties,是美国地区的资源束
  # 它覆盖了默认资源束
  
  Title=America;
  red.label=Red;
  green.label=Green;
  blue.label=Blue ;

  

  清单一和二定义了一个默认资源文件,和美国地区的资源文件。其中等号左边的字符串表示主键,它们是唯一的。为了获得主键对应的值,你可以调用ResourceBundle类的getString方法,并将主键作为参数。此外,文件中以“#”号开头的行表示注释行。需要注意的是清单二中的“\u4e2d\u56fd”,它是字符“中国”的Unicode字符码。是使用Java自带的native2ascii工具转换的(native2ascii in.properties out.properties),这是为了不在程序界面中产生乱码。

  

  清单四:

  

cmdRed.setText(bundle.getString("red.label"));
  cmdBlue.setText (bundle.getString("blue.label"));
  cmdGreen.setText (bundle.getString("green.label"));

    

  清单二中的cmdRed、cmdBlue、cmdGreen 为按钮。bundle.getString("red.label")为得到资源文件中主键是red.label的值。

  

  好了到此为止Java程序用户界面的本地化就是这么简单。不过,要提醒你的是在为用户界面事件编写事件监听器代码时,要格外小心。请看下面这段代码。

  

  清单五:

  

public class MyApplet extends Japplet implements ActionListener{
  public void init(){
  JButton cancelButton=new JButton(“Cancel”);
  CancelButton.addActionListener(this);
  ...
  }
  
  public void actionPerformed(ActionEvent e){
  String s=e.getActionCommand();
  if(arg.equals(“Cancel”);
  doCancel();
  else ……
  }
  }

    

  如果你对清单五的代码不进行本地化,她就可能会运行的很好。但当你的按钮被本地化为中文时,“Cancel”变为了“取消”。这时就会出现你不愿意看到的问题。下面有三个方法可以消除这个潜在的问题!

  

  1> 使用内部类而不使用独立的actionPerformed程序。

  

  2> 使用引号而不使用标签来标识组件。

  

  3> 使用name属性来标识组件

  

  本例稍后的代码就是采用第一种方法来消除这个问题的。

  

  清单六:完整的代码

  

//:MyNative.java
  
  /**
  Copyright (c) 2003 Dorian. All rights reserved
  @(#)MyNative.java 2003-12-21
  @author Dorian
  @version 1.0.0
  visit http://www.Dorian.com/Java/
  */
  
  import java.awt.*;
  import java.awt.event.*;
  import javax.swing.*;
  import java.util.*;
  
  /**
  这是一个将Java程序界面地方化的例子本例采用读取属性文件来达到目的
  @see java.util.Locale;
  @see java.util.ResourceBundle;
  @see java.util.MissingResourceException;
  */
  
  public class MyNative{
  public static void main(String[] args){
  JFrame frame = new MyNativeFrame();
  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  frame.setResizable(false);
  frame.setVisible(true); // Pop the window up.
  }
  }
  
  class MyNativeFrame extends JFrame{
  public MyNativeFrame(){
  Locale locale = Locale.getDefault();//获取地区:默认
  //获取资源束。如未发现则会抛出MissingResourceException异常
  //"Properties.Dorian"为在Properties下以Dorian为文件名的默认属性文件
  ResourceBundle bundle = ResourceBundle.getBundle("Properties.Dorian",locale);
  setTitle(bundle.getString("Title"));//通过getString()的返回值来设置Title
  setSize(WIDTH,HEIGHT); // Set the window size.
  panel=new MyNativePanel();
  Container contentPane=getContentPane();
  contentPane.add(panel);
  
  //通过获取资源束中*.label的值对三个按钮设置其Label
  
  panel.setCmdRed(bundle.getString("red.label"));
  panel.setCmdBlue(bundle.getString("blue.label"));
  panel.setCmdGreen(bundle.getString("green.label"));
  }
  
  private MyNativePanel panel;
  private static final int WIDTH=400;
  private static final int HEIGHT=100;
  }
  
  class MyNativePanel extends JPanel{
  public MyNativePanel(){
  layout=new BorderLayout();
  setLayout(layout);
  
  txt=new JTextField(50);
  add(txt,layout.CENTER);
  cmdRed=new JButton();
  cmdBlue=new JButton();
  cmdGreen=new JButton();
  panel.add(cmdRed);
  panel.add(cmdBlue);
  panel.add(cmdGreen);
  add(panel,layout.SOUTH);
  cmdRed.addActionListener(new ActionListener(){
  public void actionPerformed(ActionEvent e){
  String s = e.getActionCommand();
  txt.setBackground(Color.red);
  txt.setText(s);
  }
  });
  
  cmdBlue.addActionListener(new ActionListener(){
  public void actionPerformed(ActionEvent e){
  String s = e.getActionCommand();
  txt.setBackground(Color.blue);
  txt.setText(s);
  }
  });
  
  cmdGreen.addActionListener(new ActionListener(){
  public void actionPerformed(ActionEvent e){
  String s = e.getActionCommand();
  txt.setBackground(Color.green);
  txt.setText(s);
  }
  });
  }
  
  public void setCmdRed(String s){
  cmdRed.setText(s);
  }
  
  public void setCmdBlue(String s){
  cmdBlue.setText(s);
  }
  
  public void setCmdGreen(String s){
  cmdGreen.setText(s);
  }
  
  JPanel panel=new JPanel();
  BorderLayout layout;
  private JTextField txt;
  private JButton cmdRed,cmdBlue,cmdGreen;
  }
  //~
  
  资源文件:
  
  # Dorian.properties是默认的"Dorian"资源束文件。
  # 作为中国人,我用自己的地区作为默认
  
  Title=\u4e2d\u56fd
  red.label=\u7ea2\u8272
  green.label=\u7eff\u8272
  blue.label=\u84dd\u8272
  
  # 文件Dorian_en_US.properties,是美国地区的资源束
  # 它覆盖了默认资源束
  Title=America
  red.label=Red
  green.label=Green
  blue.label=Blue
  # 文件Dorian_zh_CN.properties,是中国大陆地区的资源束
  # 这个文件没有任何资源定义,从默认中国资源束继承

(T112)

  


[ 发表评论 ] 字体[  ] [ 打印 ] [ 进入博客 ] [ 进入论坛 ]  [ 推荐给朋友 ]
  相关文章
· 运用Tomcat5和PostgreSQL配置开发JSP详解 (10-27) · 关于J2EE层次设计架构实例的分析详解 (10-26)
· Java的垃圾回收机制详解和调优大全 (10-25) · 说三道四之:JavaBean与EJB有何不同之处 (10-25)
· 面向Java开发人员的Ajax:Java对象序列化 (10-25) · J2EE中最常用的三种 Frameworks介绍 (10-21)
· 关于J2EE层次设计架构实例的分析详解 (10-20) · BEA发布首个支持所有主要开源框架的J2EE (10-20)
· EJB的核心技术应用总结之得心应手篇 (10-18) · 实战体会Java多线程编程的精要文集 (10-18)
  客户需求反馈表
* 姓  名:
更多资料  了解方案  认识厂商
* 单位名称:
* 联系电话:
* 电子邮件:
  赛迪推荐  
  手机·资费 ·新品·导购·评测·手机资费·宽带
手机搜索  诺基亚 N73 MOTO Z6
  IT产品 ·笔记本·台式机·服务器·打印·投影
IT产品搜索 
  IT技术 ·开发·网管·安全·数据库·操作系统
  信息化 ·热点·专题·访谈·周刊·方案案例
[政务][电信][金融][农业][制造业][中小企业]
[CIO][ERP][协同][IT管理][中间件][电子商务]
[政策][地方][专家][评估][辞典][博客][社区]
· 专题:一路畅通构想曲——让出行不再遭遇堵车
· CIO工作亲历:企业ERP选型不能忽视"选人关"
· 综述:信息化建设给中国监狱带来的各种变化
· 金融业风险管理和法规遵从有五点需考虑的因素
· 保险业CIO关注:该如何建立统一高效的CRM体系
· 调查显示:多数CIO对IT规划仍存在困惑和误解
  博客·论坛 ·曾剑秋·项立刚·Java学习·网管