Java程序的國際化和本地化介紹

本文嘗試用一個簡單的例子來演示在書寫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一樣,而不是通常意義上的菜單條。

通常我們的程序是這樣的:

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",不然界面有中文字符的時候會出現沒有意義的方框。

請看修改過的程序和資源文件。

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);

}

}

 

 

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;

}

}

 

 

 

在運行前,我們再做一個包含中文資源的資源文件

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繼承而來,ListResourceBundle子類必須提供重載getContents方法和一個對象數組,數組裏麪包含了資源的Keys和相應的values。例如鍵"OKText"的值在兩個文件裏面分別是"OK"和"確定"。

 

在通常情況下,應用程序安裝完後一般不需要常常改變Locale,這樣,在我們發佈應用程序時候,在不同的區域中不用提供多個resource文件,只要將用到的資源文件替換成相應locale內容的文件就可以了。例如本例裏,只要一個Res.java的資源文件,當在英語環境中,其內容用Res_en_US.java裏面的資源替換,在中文環境下,替換成Res_zh_CN.java裏面內容就可以了。

 

關於i18n和l10n的進一步討論 本文討論的只是最簡單的關於界面顯示語言的國際化,在實際的應用過程中,情況要複雜的多,一些需要考慮的因素包括:提示信息,GUI組件上的標籤,在線幫助,聲音,顏色,圖形,圖標,日期,貨幣符號.....

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章