本文嘗試用一個簡單的例子來演示在書寫Java應用程序時候,怎樣使之符合國際化標準,然后對其進行本地化有多么簡單。
當一個軟件產品需要在全球范圍應用的時候,得考慮在不同的地域和語言環境下面的使用情況,最簡單的要求就是UI上的信息上能用本地化語言來顯示,當然一個優秀的全球化軟件產品關于國際化和本地化的要求遠遠不止于此,本文只是涉及了國際化和本地化的關于界面顯示語言的一小部分。Java語言內核基于Unicode2.1提供了對不同國家和不同語言文字的內部支持,由于先天的原因,Java對于國際化的支持遠遠要比C/C++來的優越。
在開始具體介紹之前,需要先介紹幾個術語:
i18n: 就是internationalization, 國際化,由于首字母"i"和末尾字母"n"間有18個字符,所以簡稱i18n. internationalization指為了使應用程序能適應不同的語言和地區間的變化而不作系統性的變化所采取的設計措施。
l10n: 就是localization, 本地化,由于首字母"l"和末尾字母"n"間有10個字母,所以簡稱l10n. localization指為了使應用軟件能夠在某一特定語言環境或地區使用而加入本地特殊化部件和翻譯后文本的過程。
locale: 簡單來說是指語言和區域進行特殊組合的一個標志。
我們的例子,顯示一個有一個按鈕和一個菜單的Dialog窗,在不改動程序的前提下使應用程能夠顯示英文文字的或者中文文字的界面。 注:因為僅僅作為演示用,我們的菜單欄也作為一個部件加入對話框,好象是一個Button一樣,而不是通常意義上的菜單條。
通常我們的程序是這樣的:
/**
* File name: i18nDemo.java
* Author ID: Jack, at http://bbs.whnet.edu.cn, Java discuss board.
* Description: Shows a Dialog with a "OK" button and "File"/"Exit" menu.
*/
import javax.swing.*;
import java.awt.*;
import java.util.*;
public class i18nDemo {
public static void main(String args[]) throws Exception{
JDialog dialog=new JDialog();
JButton btOK=new JButton();
JMenuBar menuBar=new JMenuBar();
JMenu menuFile=new JMenu();
JMenuItem menuExit=new JMenuItem();
btOK.setText("OK");
menuFile.setText("File");
menuExit.setText("Exit");
dialog.setTitle("i18n Demo");
menuBar.add(menuFile);
menuFile.add(menuExit);
dialog.getContentPane().setLayout(new FlowLayout());
dialog.getContentPane().add(btOK);
dialog.getContentPane().add(menuBar);
dialog.setSize(200,100);
dialog.setModal(true);
dialog.show();
System.exit(0);
}
}
我們通過修改程序來達到i18n的要求:將那些和界面顯示有關系的資源單獨提取出來到資源文件里面.Java里面的資源文件叫做ResourceBundle,它分成兩種,一種是ListResourceBundle,另一種是PropertyResourceBundle,我們這里使用ListResourceBundle,關于PropertyREsourceBundle請參閱文后的推薦閱讀。當一個程序需要一些Locale相關的資源,例如字符串資源的時候,它可以從resource bundle里面將需要的本地化資源裝入。
需要注意的是:為了能夠正確顯示中文字符,程序里的部件需要選擇指定字體,例如在顯示中文的時候使用"MS Song",不然界面有中文字符的時候會出現沒有意義的方框。
請看修改過的程序和資源文件。
/**
* File name: i18nDemo.java
* Author: Jack, at http://bbs.whnet.edu.cn, Java discuss board.
* Email: greatjava@sina.com
* Description: Shows a Dialog with a "OK" button and "File"/"Exit" menu.
* This program made some modifications to fit the requestion of i18n
*/
import javax.swing.*;
import java.awt.*;
import java.util.*;
public class i18nDemo {
public static void main(String args[]) throws Exception{
ResourceBundle res;
if (args.length<1) {
//use current locale at machine to get the resource bundle.
res = ResourceBundle.getBundle("Res");
}else {
res = ResourceBundle.getBundle("Res",new Locale(args[0], args[1]));
}
JDialog dialog=new JDialog();
JButton btOK=new JButton();
JMenuBar menuBar=new JMenuBar();
JMenu menuFile=new JMenu();
JMenuItem menuExit=new JMenuItem();
Font font = new Font(res.getString("FontName"),Font.PLAIN,12);
btOK.setText(res.getString("OKText"));
menuFile.setText(res.getString("FileMenuText"));
menuExit.setText(res.getString("FileExitMenuText"));
dialog.setTitle(res.getString("DialogTitle"));
btOK.setFont(font);
menuFile.setFont(font);
menuExit.setFont(font);
menuBar.add(menuFile);
menuFile.add(menuExit);
dialog.getContentPane().setLayout(new FlowLayout());
dialog.getContentPane().add(btOK);
dialog.getContentPane().add(menuBar);
dialog.setSize(200,100);
dialog.setModal(true);
dialog.show();
System.exit(0);
}
}
/**
* File name: Res_en_US.java
* Author: Jack, at http://bbs.whnet.edu.cn, Java discuss board.
* Email: greatjava@sina.com
* Description: Resource file for i18nDemo.java
*/
import java.util.*;
public class Res_en_US extends java.util.ListResourceBundle {
static final Object[][] contents = new String[][]{
{ "OKText", "OK" },
{ "FontName", "Dialoginput" },
{ "FileMenuText", "File"},
{ "FileExitMenuText", "Exit"},
{ "DialogTitle", "Demo Dialog" }};
public Object[][] getContents() {
return contents;
}
}
在運行前,我們再做一個包含中文資源的資源文件
/**
* File name: Res_zh_CN.java
* Author: Jack, at http://bbs.whnet.edu.cn, Java discuss board.
* Email: greatjava@sina.com
* Description: Resource file for i18nDemo.java
*/
import java.util.*;
public class Res_zh_CN extends java.util.ListResourceBundle {
static final Object[][] contents = new String[][]{
{ "OKText", "確定" },
{ "FontName", "MS Song" },
{ "FileMenuText", "文件"},
{ "FileExitMenuText", "退出"},
{ "DialogTitle", "演示對話框" }};
public Object[][] getContents() {
return contents;
}
}
先運行來看看結果:
//Run next command step by step
javac *.java
java i18nDemo
java i18nDemo zh CN
java i18nDemo en US
可以看到出現了中文界面和英文界面的對話框。
具體的看一下程序:
主程序i18nDemo.java,多了一個ResourceBundle對象,它包含了一個資源文件的信息。然后需要使用本地化資源的時候,都通過res.getString(KEY)來得到相應的Locale的值。通過命令行,我們傳入關于語言和國家的代碼,這樣在生成ResourceBundle對象的時候,可以指向相應的資源文件。如果沒有指定Locale,那么在生成ResourceBundle使用的Locale是當前機器上缺省的區域和語言。在我的機器上(English WindowsNT 4),打開Richwin中文平臺的時候,缺省的locale是中國,關閉RichWin的時候,Locale是U.S..
資源文件Res_en_US.java里面包含了英文的界面資源,文件名里的"en"指英語語言,"US"指國家是美國。Res_zh_CN.java是中文的資源文件,”zh“說明語言是中文,"CN"說明國家是中國。關于語言和國家的完整對照表可以在參考資源里找到鏈接。
Res_xx_XX類是從ListResourceBundle繼承而
原文轉自:http://www.anti-gravitydesign.com