Java用户界面当地化实例摸索
副标题#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定名的默认资源文件。这样就可以利用资源文件了!让我们来看看资源文件是如何界说的。
清单二:
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"));
#p#副标题#e#
清单二中的cmdRed、cmdBlue、cmdGreen 为按钮。bundle.getString("red.label")为获得资源文件中主键是red.label的值。
#p#分页标题#e#
好了到此为止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;
}
//~
资源文件:
#p#分页标题#e#
# 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,是中国大陆地域的资源束
# 这个文件没有任何资源界说,从默认中国资源束担任
以下是这个措施运行后的截屏!