日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

JAVA 国际化基础知识(二)

發(fā)布時(shí)間:2023/12/20 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JAVA 国际化基础知识(二) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

輸入法

實(shí)際上,以上所有討論都涉及操作或顯示數(shù)據(jù)。然而,必須以某種方式輸入數(shù)據(jù)。對(duì)于最終用戶,最常用的是鍵盤。但是,如果鍵盤不支持某種語(yǔ)言輸入所需的字符,您該怎么辦呢?

輸入法(Input method)是允許數(shù)據(jù)輸入的軟件組件的一個(gè)技術(shù)術(shù)語(yǔ)。Java 平臺(tái)既允許使用主機(jī) OS 輸入法也允許使用基于 Java 語(yǔ)言的輸入法。如果您需要實(shí)現(xiàn)輸入法,您可以使用輸入法框架(Input Method Framework)。您可以在 JDK 文檔中?Internationalization?一節(jié)中的?Input Method Framework?(可以從參考資料中訪問該文檔)中找到輸入法客戶機(jī) API(Input Method Client API)及輸入法引擎 SPI(Input Method Engine SPI)的規(guī)范、參考和教程

Unicode 與 Java 字符

Java 字符與 char 數(shù)據(jù)類型

Java 程序員的一個(gè)最知名的抱怨是“我只看到程序輸出是問號(hào)(或方塊),我的數(shù)據(jù)是怎么被破壞的呢?”通常,作為 Java 開發(fā)人員,您應(yīng)該理解實(shí)際發(fā)生了什么以及這一表面問題后面的原因,而這種知識(shí)在處理國(guó)際化問題時(shí)尤為重要。

Java 語(yǔ)言規(guī)范(Java Language Specification)將?char?定義為原始的、數(shù)值型和整型的類型。此外,char?是唯一的無(wú)符號(hào)(unsigned)數(shù)字類型,它允許一些有趣的(或討厭的,這取決于您的觀點(diǎn))竅門。char?在另一方面也十分特殊,因?yàn)閷⑺鼈兯偷街T如顯示器或打印機(jī)的輸出設(shè)備時(shí),會(huì)將其值從字符映射或字體映射成字形。然而,從根本上來說,char?是數(shù)值類型,支持所有整數(shù)運(yùn)算。因此?Unicode支持?注釋道:可以使用字母或 Unicode 轉(zhuǎn)義符設(shè)置?char。因?yàn)?char?是數(shù)值型,所以您也可以使用八進(jìn)制、十進(jìn)制或十六進(jìn)制表示法甚至反轉(zhuǎn)位來賦值。

假設(shè)出現(xiàn)上述情況并假定沒有程序錯(cuò)誤,上面問題的答案是:字符映射或字體不支持該字符,顯示問號(hào)或方塊來作為替代。該?char?本身的值仍然有效。但是,這樣您就不能可視地驗(yàn)證數(shù)據(jù);您不得不核對(duì)數(shù)值。下面的示例顯示了這一行為。

這幅圖像顯示了日本象形文字中的“Go”或 5,以 Unicode 表示為‘\u4E94’。該字符導(dǎo)致在下面的?charExample?程序中顯示成問號(hào)和方塊:

import javax.swing.*; ? public class charExample { ? public static void main( String[] args ) ? { ??? boolean bFirst = true;??? ????char aChar[] = { ???????????????????? 'A',???? // character ????????????????????? 65,???? // decimal ????????????????????? 0x41,?? // hex ????????????????????? 0101,?? // octal ???????????????????? '\u0041' // Unicode escape ?????????????????? }; ? ??? char myChar = 256; ??? ????for( int i = 0; i < aChar.length; i++ ) ??? { ????? System.out.print( aChar[i]++ + " " ); ????? if( i == (aChar.length - 1) ) ????? { ??????? System.out.println( "\n---------" ); ??????? if( bFirst ) ??????? { ????????? i = -1; ????????? bFirst = !bFirst;????????? ????????} ????? } ??? } // end for ??? // the result of adding two chars is an int ??? System.out.println( "aChar[0] + aChar[1] equals: " + ????????????????????????(aChar[0] + aChar[1]) ); ??? System.out.println( "myChar at 256: " + myChar ); ??? System.out.println( "myChar at 20116 or \\u4E94: " + ???????????????????????( myChar = 20116 ) ); ??? // show integer value of the char ??? System.out.println( "myChar numeric value: " + ????????????????????(int)myChar ); ? ??? JFrame jf = new JFrame(); ????? JOptionPane.showMessageDialog( jf, ??????? "myChar at 20116 or \\u4E94: " + ????????( myChar = 20116 ) + ????????"\nmyChar numeric value: " + ????????(int)myChar, ????????"charExample", JOptionPane.ERROR_MESSAGE); ? ??? jf.dispose(); ??? System.exit(0); ? ? } // end main ? }? // End class charExample

首先,程序用字母“A”的各種表示法初始化一個(gè)?char?數(shù)組,并將一個(gè)?char?變量設(shè)置成 256(‘\u0100’)。程序在一個(gè)循環(huán)中打印兩次數(shù)組的值。打印之后遞增每個(gè)元素的值(char?是數(shù)值型,記得嗎?)。接下來,將頭兩個(gè)元素加到一起,然后打印其結(jié)果(int)。然后,打印?char?變量,首先用其初始值,然后用值 20116 或‘\u4E94’,它是 5 的日本象形文字“Go”。如預(yù)期的那樣在使用代碼頁(yè) cp1252 的 Windows NT 上,會(huì)在顯示器上將這兩個(gè)值打印成問號(hào)。根據(jù)您的系統(tǒng)使用的代碼頁(yè),顯示可能略微有些不同。要核查其值,接下來將變量作為?int?打印。最后,JOptionPane?顯示其值,對(duì)于不受支持的?char‘\u4E94’,它顯示一個(gè)方塊。

下面是?charExample?的輸出:

A A A A A --------- B B B B B --------- aChar[0] + aChar[1] equals: 134 myChar at 256: ? myChar at 20116 or \u4E94: ? myChar numeric value: 20116

JOptionPane?顯示:

字體、字體特性及 Lucida 字體

Java 平臺(tái)既識(shí)別邏輯字體也識(shí)別物理字體。

邏輯字體是那些被映射到主機(jī)系統(tǒng)字體的字體。比如人們熟悉的 Serif、Sans-serif、Monospaced、Dialog 以及 DialogInput 字體。還有四種邏輯字體樣式:普通、粗體、斜體及粗斜體。使用一個(gè)位于 JRE/lib 目錄下的font.properties 文件來實(shí)現(xiàn)主機(jī)字體到邏輯字體的映射。盡管細(xì)節(jié)因系統(tǒng)而異,但是缺省 font.properties 文件通常設(shè)置成英語(yǔ)環(huán)境,雖然JDK 也有一個(gè)本地化日語(yǔ)版本可用。還提供了另外的font.properties 文件;JDK 1.3.1 Windows 版包含阿拉伯語(yǔ)、希伯來語(yǔ)、日語(yǔ)、韓國(guó)語(yǔ)、俄語(yǔ)、泰國(guó)語(yǔ)字體文件以及中文的幾種版本的字體文件。就象命名約定一樣,搜索適當(dāng)?shù)?font.properties 同用于?ResourceBundle?的方法類似(但不全相同)。如果特定于語(yǔ)言的 font.properties 文件同您的系統(tǒng)的語(yǔ)言環(huán)境相匹配,并且安裝了期望的字體(通常隨 OS 的那一版本一起提供),那么就會(huì)對(duì)該語(yǔ)言進(jìn)行自動(dòng)映射。否則,就使用缺省的(通常是英語(yǔ))文件映射。

如果您安裝了適當(dāng)?shù)淖煮w并且在調(diào)用 Java 應(yīng)用程序時(shí)傳入了相應(yīng)的語(yǔ)言及國(guó)家或地區(qū)代碼,那么也會(huì)進(jìn)行自動(dòng)映射。如果期望的 font.properties 文件存在,那么這種行為對(duì)開發(fā)非常有用。也可以將最初的缺省 font.properties 文件拷貝到別的地方,然后將特定文件重命名為“font.properties”,通過這樣來將該語(yǔ)言/字體有效地設(shè)置成缺省情況。雖然對(duì)于開發(fā)人員來說很容易,但這顯然不是最終用戶非得做的事情。

如果您必須親自定制或創(chuàng)建一個(gè)新的font.properties 文件,那就完全是另一回事,而且更難。可以在JDK 文檔?Internationalization?一節(jié)中的?Font Properties?中找到處理 font.properties 文件的指示信息。

物理字體是我們始終在使用的正常字體。基于ASCII 和 ISO 8859-1 的字體不會(huì)有問題。然而,一旦超出這一范圍,主機(jī)平臺(tái)顯然必須理解它們,并且必須對(duì)它們進(jìn)行 Unicode 編碼以使之能夠用于您的 Java程序。找到這些字體不象以前那么難了。例如,Windows MS MinchoTrueType 字體(主要是日語(yǔ))是 Unicode 編碼的,可以以標(biāo)準(zhǔn)方式立即投入使用。當(dāng)在系統(tǒng)上裝入了適當(dāng)?shù)奈锢碜煮w時(shí),您可以讓用戶選擇他們想要的字體并保存他們的首選項(xiàng),或者將該字體設(shè)置成整個(gè)軟件包的標(biāo)準(zhǔn)字體,而不用進(jìn)入 font.properties 文件。

Java 2 SDK 還提供三種物理字體系列:Lucida Sans、Lucida Bright 和 Lucida Sans Typewriter。每一系列都含有四種字體 ― 分別用于普通、斜體、粗體以及粗斜體樣式 ― 總計(jì) 12 種字體。雖然關(guān)于這些字體的確切功能的信息極為稀少,但 Lucida Sans 字體處理大多數(shù)歐洲和中東語(yǔ)言。不包括亞洲語(yǔ)言。由于該字體隨 JDK 一起提供,因此教程中的所有圖形應(yīng)用程序示例都使用Lucida Sans 字體。更多信息,請(qǐng)參閱 JDK 文檔?Internationalization?一節(jié)中的?Physical Fonts?(可以從參考資料訪問)。

提供本地化的資源

創(chuàng)建語(yǔ)言環(huán)境

提供任何類型的本地化資源時(shí),您應(yīng)該做的第一件事情是創(chuàng)建一個(gè)適當(dāng)?shù)恼Z(yǔ)言環(huán)境(參閱語(yǔ)言環(huán)境)。雖然有一個(gè)包含平臺(tái)/瀏覽器變體的構(gòu)造器,但通常您將使用

Locale l = new Locale(String language, String country);

其中,language?是由 ISO-639 定義的小寫、兩字母代碼,country?是一個(gè)由 ISO-3166 定義的大寫、兩字母代碼。

下面是用于特定于德國(guó)的德語(yǔ)語(yǔ)言環(huán)境:

Locale l = new Locale( "de", "DE");

?

Locale?有一個(gè)返回受支持的語(yǔ)言環(huán)境數(shù)組的?static getAvailableLocales()?方法。實(shí)際上,所有與語(yǔ)言環(huán)境相關(guān)的 Java 2 Platform API 都有一個(gè)?getAvailableLocales()?方法,您可以期望它返回一致的值。其它有用的方法是?static getDefault(),它返回缺省的語(yǔ)言環(huán)境,以及?getDisplayName()?和?getDisplayName(Locale inLocale)?方法,它們分別用缺省或所請(qǐng)求的語(yǔ)言環(huán)境語(yǔ)言來返回適于顯示的名稱。您也可以獲取國(guó)家或地區(qū)以及語(yǔ)言的代碼和名稱。這些方法允許沒有特定語(yǔ)言知識(shí)的程序員為最終用戶提供讀、選擇以及返回本地化的語(yǔ)言環(huán)境信息的能力。

使用資源束

ResourceBundle?包含鍵/值結(jié)合。鍵總是?String,而值總是?PropertyResourceBundle?中的?String,但可以是?ListResourceBundle?中的任何對(duì)象或定制子類。如果沒有找到請(qǐng)求的資源,那么?ResourceBundle?訪問方法會(huì)拋出一個(gè)MissingResourceException。

參閱本地化的資源以獲得更多常規(guī)信息。本教程將集中于?PropertyResourceBundle,因?yàn)樗鼈冞m合于大多數(shù)情形,并且易于生成和修改而無(wú)須編寫任何新代碼。

ResourceBundle.getBundle(StringbaseName)?和?ResourceBundle.getBundle(StringbaseName, Locale locale)?提供一種內(nèi)置的搜索機(jī)制,當(dāng)這些束的結(jié)構(gòu)恰當(dāng)時(shí),這種機(jī)制工作得非常好。正常的搜索從 base_language_country_variant 到 base_language_country,再到base_language,最后到 base。注:如果請(qǐng)求一個(gè)特定的、非缺省的語(yǔ)言環(huán)境,并且同資源一起存在一個(gè)缺省的語(yǔ)言環(huán)境束,那么搜索將會(huì)停在那兒而不是繼續(xù)搜索到基礎(chǔ)束。我們的示例程序(參閱?PropertyResourceBundle代碼示例)支持英語(yǔ)、法語(yǔ)、德語(yǔ)和俄語(yǔ)并使用?PropertyResourceBundle。支持的 .properties 文件被命名為:

·????????ByTheNumbersrb.properties

·????????ByTheNumbersrb_de.properties

·????????ByTheNumbersrb_en.properties

·????????ByTheNumbersrb_fr.properties

·????????ByTheNumbersrb_ru.properties

所有文件都含有全部所需資源。英語(yǔ)用作缺省值,ByTheNumbersrb.properties和 ByTheNumbersrb_en.properties 是相同的。這種做法略微有些偏離傳統(tǒng)認(rèn)知,即:對(duì)于基礎(chǔ)缺省語(yǔ)言,不需要專門命名的 .properties 文件,因此我們不需要ByTheNumbersrb_en.properties。然而,當(dāng)一段特定信息使用非缺省語(yǔ)言環(huán)境時(shí),這種設(shè)置卻是必需的,我們的示例程序就是這種情形。假定一個(gè)英語(yǔ)語(yǔ)言環(huán)境將被用來在一臺(tái)法語(yǔ)為缺省語(yǔ)言環(huán)境機(jī)器上顯示某項(xiàng)。如果 _fr 束中存在相同的鍵,_en 搜索失敗時(shí),將會(huì)選擇該值。這完全不是所請(qǐng)求的或所期待的那樣。如果在程序的任意一次給定運(yùn)行中只使用一種語(yǔ)言環(huán)境,那么專門命名的副本就不是必需的。但無(wú)論如何,在任何情況下這種做法都不需要新的代碼并且起作用。

如果我們需要更特定的語(yǔ)言環(huán)境支持,例如奧地利語(yǔ)、瑞士語(yǔ)和德語(yǔ)(分別是 _de_AT、_de_CH 和 _de_DE),那么只將國(guó)家或地區(qū)細(xì)節(jié)置于以適當(dāng)?shù)膰?guó)家或地區(qū)命名的特性文件(例如,myprops_de_CH.properties)中,而將更一般的元素置于 _de 束級(jí)別,這樣做會(huì)很有意義。在那種情形下,需要其它元素時(shí),將總能找到 _de 束。

您也應(yīng)該為束實(shí)現(xiàn)幾種命名約定。我們的示例使用這種通用格式:Object.getClass().getName() + "rb"。主要規(guī)則是:對(duì)于 .properties 文件,不要只使用類名稱作為其基礎(chǔ)名稱。忽視該規(guī)則在有些平臺(tái)上照樣能行,但在其它一些平臺(tái)上您會(huì)大吃一驚。記入文檔的準(zhǔn)則是:如果類和具有相同名稱的 .properties 文件同時(shí)存在,那么被選中和裝入的將是類。就是這樣。這一行為的一個(gè)好結(jié)果是:使用適當(dāng)命名的束,您可以在?ListResourceBundle?和PropertyResourceBundle?之間轉(zhuǎn)換,而不用更改代碼;只要將期望的類型移到類路徑即可。

您可能會(huì)發(fā)現(xiàn)讓不同的信息類型具有多個(gè)?ResourceBundle?更加合適。它們可以為許多不同的程序提供資源。特定的前綴或后綴約定對(duì)于避免類名沖突仍然有用。

使用 PropertyResourceBundle

PropertyResourceBundle?的語(yǔ)義同其父束?ResourceBundle?的語(yǔ)義相同。不同之處在于數(shù)據(jù)存儲(chǔ)的位置。PropertyResourceBundle?由符合?Properties?約定的 .properties 文件支持。下面是創(chuàng)建文件所要知道的內(nèi)容:

·????????文件被格式化為 ISO8859-1 編碼的基本文本,因此您可以使用任何編輯器來創(chuàng)建和編輯文件。

·????????以 # 開頭的行是注釋。

·????????每個(gè)資源以?key=value?的形式被設(shè)置成鍵/值對(duì)。

·????????文件擴(kuò)展名必須是.properties。名稱必須遵守下列格式,其中?language?由 ISO-639 定義,country?由 ISO-3166 定義(參閱創(chuàng)建語(yǔ)言環(huán)境):

1.?????? baseName.properties

2.?????? baseName_language.properties

3.?????? baseName_language_country.properties

4.?????? baseName_language_country_variant.properties

下面是ByTheNumbersrb_en.properties 的一個(gè)示例項(xiàng):

1=One:

下面是ByTheNumbersrb_ru.properties 的一個(gè)示例項(xiàng):

1=\u041E\u0434\u0438\u043D:

上面兩個(gè)示例中的冒號(hào)實(shí)際上是值的一部分而不是所需的項(xiàng)。注:一旦我們超越了 ISO 8859-1 而進(jìn)入其它 Unicode 范圍,我們必須使用 Java Unicode 轉(zhuǎn)義。您可以使用 JDKnative2ascii 工具來從不同編碼進(jìn)行轉(zhuǎn)換。

Property ResourceBundle 代碼示例

顯示在右側(cè)的?ByTheNumbers?示例使用俄語(yǔ)語(yǔ)言環(huán)境 ― ru_RU。

ByTheNumbers.java(參閱?ByTheNumbers.java:PropertyResourceBundle 示例)以幾種不同的語(yǔ)言顯示數(shù)字 0 到 10 的名稱。進(jìn)入時(shí),將缺省的語(yǔ)言環(huán)境同支持的語(yǔ)言環(huán)境(英語(yǔ)、法語(yǔ)、德語(yǔ)和俄語(yǔ))相比較。如果缺省語(yǔ)言環(huán)境與其中的某一種不匹配,那么就將英語(yǔ)選做缺省,將基礎(chǔ)?ResourceBundle?用于資源;否則,使用缺省語(yǔ)言環(huán)境?ResourceBundle。通過使用缺省語(yǔ)言環(huán)境獲得支持的語(yǔ)言的語(yǔ)言環(huán)境顯示名稱(Locale Display Name),并將其裝入?JComboBox。用戶可以鍵入適當(dāng)名稱的號(hào)碼然后按 OK。程序驗(yàn)證這些輸入項(xiàng)并顯示祝賀消息或重試消息。我們提供一個(gè)按鈕以隨機(jī)順序顯示號(hào)碼名稱。用戶可以從?JComboBox?選擇任何語(yǔ)言,并且字段初始將以數(shù)值順序顯示選中的語(yǔ)言。程序使用 Lucida Sans 字體,因此可以正確地顯示所有受支持的語(yǔ)言。遺憾的是,我們的翻譯還沒有返回我們對(duì)標(biāo)題翻譯的請(qǐng)求,因此“title=Key in numbers to match the words:”鍵/值對(duì)僅僅出現(xiàn)在基礎(chǔ)名稱文件中,它給了我們一個(gè)機(jī)會(huì),讓我們明白不位于層次結(jié)構(gòu)較低位置的鍵可以在祖先文件中找到。

要運(yùn)行該程序,使用下列任意一條命令:

l?? java ByTheNumbers?// 如果支持缺省語(yǔ)言環(huán)境,就使用它,否則,就使用英語(yǔ)。

l?? java -Duser.language=de -Duser.region=DE ByTheNumbers?// 德語(yǔ)

l?? java -Duser.language=en -Duser.region=US ByTheNumbers?// 英語(yǔ)

l?? java -Duser.language=fr -Duser.region=FR ByTheNumbers?// 法語(yǔ)

l?? java -Duser.language=ru -Duser.region=RU ByTheNumbers?// 俄語(yǔ)

下面顯示了五個(gè) .properties 文件中的兩個(gè):

ByTheNumbersrb.properties?(與 ByTheNumbersrb_en.properties相同)

# Default properties in English

0=Zero:

1=One:

2=Two:

3=Three:

4=Four:

5=Five:

6=Six:

7=Seven:

8=Eight:

9=Nine:

10=Ten:

random=Random

title=Key in numbers to match the words:

ByTheNumbersrb_ru.properties

# Default properties in Russian

0=\u041D\u0443\u043B\u044C:

1=\u041E\u0434\u0438\u043D:

2=\u0414\u0432\u0430:

3=\u0422\u0440\u0438:

4=\u0427\u0435\u0442\u044B\u0440\u0435:

5=\u041F\u044F\u0442\u044C:

6=\u0428\u0435\u0441\u0442\u044C:

7=\u0441\u0435\u043C\u044C:

8=\u0412\u043E\u0441\u0435\u043C\u044C:

9=\u0414\u0435\u0432\u044F\u0442\u044C:

10=\u0414\u0435\u0441\u044F\u0442\u044C:

random=\u041D\u0430\u0443\u0433\u0430\u0434

Property ResourceBundle 代碼示例:I18N 詳細(xì)信息

讓我們看一看同 I18N 有關(guān)的代碼部分。首先,建立支持的語(yǔ)言環(huán)境和?ResourceBundle?基礎(chǔ)名稱。

? Locale[]?? alSupported = {

??????????????? Locale.US,

??????????????? Locale.FRANCE,

??????????????? Locale.GERMANY,

??????????????? new Locale( "ru", "RU" )

?????????????????????????? };

...

?

? String sRBName = getClass().getName() + "rb";

?

接下來,使用與 OK 按鈕的字體相同的樣式和大小創(chuàng)建 Lucida Sans 字體,然后獲得缺省語(yǔ)言環(huán)境語(yǔ)言所支持的語(yǔ)言的顯示名稱(Display Names)。此外,對(duì)缺省語(yǔ)言環(huán)境進(jìn)行比較以確定是否支持它。如果不支持,英語(yǔ)數(shù)字將是首先被顯示的集合。

??? Font fJB = jbOK.getFont();

??? fLucida = new Font("Lucida Sans",

??????????????????????? fJB.getStyle(),

??????????????????????? fJB.getSize() );

?

??? ...

?

??? asDNames = new String[ alSupported.length ];

??? Locale lDefault = Locale.getDefault();

??? for( i = 0; i < alSupported.length; i++ )

??? {

????? asDNames[i] =

???????? alSupported[i].getDisplayName();

?

????? if( iSelIndex == 0 &&

????????? lDefault.equals( alSupported[i] ) )

????? { iSelIndex = i; }

??? } // end for

?

接下來,在一個(gè)循環(huán)中創(chuàng)建?JLabel?和?JTextField?并將它們裝入數(shù)組。設(shè)置每個(gè)?JLabel?的?Font?和?Name。一旦構(gòu)建了數(shù)組,就調(diào)用?loadFromResourceBundle()?來設(shè)置每個(gè)?JLabel?的文本值。接下來設(shè)置本地化jbRandom 按鈕和標(biāo)題文本。請(qǐng)注意,這兩個(gè)組件的屬性只設(shè)置了一次,這是典型程序中所有組件的正常情況,在那里,語(yǔ)言環(huán)境在給定的運(yùn)行期間不會(huì)改變。

????? jlTemp.setFont( fLucida );

????? jlTemp.setName( i +? "" ); // set Name

????? ...

??? loadFromResourceBundle(); // get localized labels

????? ...

??? jbRandom.setFont( fLucida );

??? jbRandom.setText( rb.getString( "random" ) );

????? ...

??? jlTemp = new JLabel( rb.getString( "title" ) );

??? jlTemp.setFont( fLucida );

?

下面是?loadFromResourceBundle()?方法,它使用選中的語(yǔ)言環(huán)境訪問適當(dāng)?shù)?ResourceBundle。使用?JLabel.Name?屬性作為?getString(String key)?的鍵來設(shè)置?JLabel?的文本。如果沒有找到特別的資源,就顯示一個(gè)錯(cuò)誤對(duì)話框。從JComboBox?選擇語(yǔ)言時(shí),也會(huì)調(diào)用這一方法。

? public void loadFromResourceBundle()

? {

??? try

??? { // get the PropertyResourceBundle

????? rb = ResourceBundle.getBundle(

????????????? sRBName,

????????????? alSupported[iSelIndex] );

????? // get data associated with keys

????? for( int i = 0; i < sfiSIZE; i++ )

????? {

??????? aiOrder[i] = i;

??????? ajl[i].setText( rb.getString( ajl[i].getName() ) );

????? }

????? bRandomize = false;

??? } // end try

??? catch( MissingResourceException mre )

??? {

????? JOptionPane.showMessageDialog( this,

??????? "ResourceBundle problem;\n" +

??????? "Specific error: " + mre.getMessage(),

??????? "", JOptionPane.ERROR_MESSAGE);

??? }

? } // end loadFromResourceBundle

?

同樣,有關(guān)完整的程序清單及所有.properties 文件的內(nèi)容,請(qǐng)參閱?ByTheNumbers.java:PropertyResourceBundle 示例。

使用日期、數(shù)字和貨幣

日期、數(shù)字和貨幣

對(duì)于任何那些從未出過國(guó),或從未接觸過日期、數(shù)字和貨幣的“外國(guó)”用法的人來說,格式化和解析日期、數(shù)字和貨幣顯得很簡(jiǎn)單。畢竟,所有人都能理解 lundi 1 avril 2002 或至少 4.1.02 的月和日部分,對(duì)嗎?雖然我們極少有人能實(shí)際以 150,75??購(gòu)買 32 1500,7 項(xiàng)東西,但我們能夠很容易地理解以歐元表示的價(jià)格有多少項(xiàng)。或者可能不是這樣。這些示例看起來可能不典型,但他們確實(shí)發(fā)生了,并且表示了為什么非本國(guó)人在理解本國(guó)的日期、數(shù)字和貨幣格式方面經(jīng)常會(huì)有問題。

結(jié)果是,全世界使用的日期有各種各樣的順序和符號(hào)。數(shù)字和貨幣也是如此。此外,貨幣符號(hào)可能不止一個(gè)字符,它可能出現(xiàn)在值的前面或后面,和值之間有或沒有空格。在大多數(shù)編程語(yǔ)言中,您幾乎總是靠自己來處理這些情形。但 Java API 卻能夠處理每個(gè)受支持語(yǔ)言環(huán)境的所有的不同格式。而且,通過使用?DateFormatSymbols?和?DecimalFormatSymbols?類,您可以獲得諸如這樣的信息:本地化的長(zhǎng)短月日名稱、十進(jìn)制與貨幣分隔符以及貨幣與百分比符號(hào)。

API 文檔鼓勵(lì)您為 I18N 應(yīng)用程序使用抽象父類?DateFormat?和?NumberFormat?的?getInstance()?和?getXXXInstance()?方法。從 1.3(和 1.4)參考實(shí)現(xiàn)起,分別返回?SimpleDateFormat?和?DecimalFormat?的實(shí)例。兩個(gè)類都有缺省的模式與符號(hào)用于格式化和解析,并且還允許定制。

下面幾頁(yè)中的示例程序都使用缺省模式來幫助您理解它們是怎樣工作的。您將看到:由于 API 設(shè)計(jì)的緣故,三個(gè)示例中的代碼都非常相似。從最終用戶的觀點(diǎn),它們也非常相似:以本機(jī)語(yǔ)言環(huán)境提供一個(gè)輸入域。當(dāng)用戶按下 OK 按鈕時(shí),就在表示用戶選擇的語(yǔ)言環(huán)境和標(biāo)準(zhǔn)解析的“原始”值的單獨(dú)域中顯示值。這三個(gè)示例都將處理由 JDKAPI 支持的所有語(yǔ)言環(huán)境。Lucida Sans 字體用于所有顯示。“Toggle Display Names”按鈕將語(yǔ)言環(huán)境名稱的顯示從用戶的本機(jī)語(yǔ)言切換為特定語(yǔ)言環(huán)境的本機(jī)語(yǔ)言。當(dāng)字體中沒有用于本地化顯示名稱的第一個(gè)字符的字形時(shí),“ - font can't display.”就被附加到下拉框中的語(yǔ)言環(huán)境名稱上。程序仍然會(huì)工作,但在那種情況下,您可能會(huì)看到輸出的某些部分是您熟悉的方框或問號(hào)。

使用下面的命令調(diào)用程序:

java AppName

?

由于支持所有 API 語(yǔ)言環(huán)境,您也可以使用下列命令調(diào)用它們

java -Duser.language=lc -Duser.region=cc AppName

?

其?lc?是 API 支持的語(yǔ)言環(huán)境的 ISO-639 語(yǔ)言代碼,cc?是 API 支持的語(yǔ)言環(huán)境的 ISO-3166 國(guó)家或地區(qū)代碼,以使輸入格式化成該語(yǔ)言環(huán)境的樣式。

注:由于要訪問整個(gè)語(yǔ)言環(huán)境顯示名稱集,這些應(yīng)用程序?qū)⒈日G闆r要花費(fèi)更長(zhǎng)的時(shí)間來啟動(dòng)。

日期格式化示例

這個(gè)?JIBDateGUI?示例使用德語(yǔ)作為缺省語(yǔ)言環(huán)境 ― de_DE。

JIBDateGUI(參閱?JIBDateGUI.java:DateFormat 示例)允許用戶以其本地的格式輸入日期。輸入時(shí)確定本地語(yǔ)言環(huán)境,并且該語(yǔ)言環(huán)境顯示在 OK 按鈕的旁邊。當(dāng)用戶按下 OK 時(shí),則解析輸入數(shù)字并以選中的語(yǔ)言環(huán)境顯示該數(shù)字。還以 ISO 格式對(duì)該值進(jìn)行單獨(dú)解析和顯示。可能使用參數(shù)“full”、“l(fā)ong”、“medium”或“short”調(diào)用程序。如果沒有發(fā)送參數(shù)或者發(fā)送了這四個(gè)參數(shù)之外的其它參數(shù),那么就使用“short”。這些值對(duì)應(yīng)于DateFormat.FULL、DateFormat.LONG、DateFormat.MEDIUM?和?DateFormat.SHORT,并且被用來以選中的樣式創(chuàng)建?DateFormats。

程序通過定義缺省和選中的?DateFormats?和?locales?開始。java.sql.Date?被初始化成顯示標(biāo)準(zhǔn) ISO 日期值的當(dāng)前日期(注:沒有為該示例對(duì)日期進(jìn)行標(biāo)準(zhǔn)化),然后定義 Lucida 字體、缺省語(yǔ)言環(huán)境、支持的語(yǔ)言環(huán)境的數(shù)組以及本機(jī)和本地化的語(yǔ)言環(huán)境顯示名稱。

? DateFormat dfLocal,

???????????? dfSelected;

?

? java.sql.Date jsqlDate = new java.sql.Date(

???? System.currentTimeMillis() );

?

? Font fLucida;

? ...

? Locale???? lDefault = Locale.getDefault();

? Locale[]?? alSupported;

?

? String[]?? asDNames,

???????????? asLDNames;

?

在構(gòu)造器中,創(chuàng)建了 Lucida Sans 字體并將其賦給顯示域。捕獲請(qǐng)求的樣式并創(chuàng)建缺省?DateFormat。接下來,同時(shí)以缺省和本地化格式收集所有可用的顯示名稱。由?Font.canDisplay()?檢查每個(gè)本地化顯示名稱的第一個(gè)字符;如果返回 false,那么“ - font can'tdisplay.”就被附加到該名稱后面。如果 Java API 支持缺省語(yǔ)言環(huán)境,那么相應(yīng)的顯示名稱就會(huì)被選中;否則就選中第零行。此外,使用?java.sql.Date?的值設(shè)置和格式化輸入域。DateFormat.setLenient(false)?被應(yīng)用到缺省?DateFormat?并且獲取缺省顯示名稱以供顯示。

??? Font fJCB = jbToggle.getFont();

??? fLucida = new Font("Lucida Sans",

??????????????????????? fJCB.getStyle(),

??????????? ????????????fJCB.getSize() );

?

??? iFormat = argiFormat;

??? dfLocal = DateFormat.getDateInstance(

???? iFormat );

???

??? alSupported = Locale.getAvailableLocales();

??? asDNames = new String[ alSupported.length ];

??? asLDNames = new String[ alSupported.length ];

??? for( int i = 0; i < alSupported.length; i++ )

??? {

????? asDNames[i] =

???????? alSupported[i].getDisplayName();

?

????? s1 =

???????? alSupported[i].getDisplayName( alSupported[i] );

????? if( fLucida.canDisplay( s1.charAt( 0 ) ) )

????? { asLDNames[i] = s1; }

????? else

????? { asLDNames[i] = s1 + " - font can't display."; }

?

????? if( iSelIndex == 0 &&

????????? lDefault.equals( alSupported[i] ) )

????? { iSelIndex = i; }

??? } // end for

??? ...

??? jtI.setText( dfLocal.format( jsqlDate ) );

??? ...

??? dfLocal.setLenient( false );

??? ...

??? JLabel jlTemp = new JLabel("Default = " +

??????????? lDefault.getDisplayName() );

??? jlTemp.setFont( fLucida );

?

在?ActionListener(actionPerformed()?方法)中為顯示名稱?JComboBox(jcb)處理所有其它 I18N 功能:根據(jù)選擇項(xiàng),創(chuàng)建新的?DateFormat?并清空顯示域。如果在下一節(jié)中出現(xiàn)了任何錯(cuò)誤,對(duì)話框?qū)@示?ParseException?消息。代碼試圖從輸入解析?java.util.Date?并使用缺省?DateFormat?對(duì)其重新進(jìn)行格式化以供輸出。接下來,格式化選中的?DateFormat?的顯示。最后,解析該值并用它來創(chuàng)建?java.sql.Date,java.sql.Date?被用來顯示 ISO 值。

??? if( oSource == jcb )

??? {

????? dfSelected = DateFormat.getDateInstance(

???????? iFormat,

???????? alSupported[ jcb.getSelectedIndex() ] );

??? }? // end if jcb, continue on

???

??? jtD.setText( "" );

??? jtP.setText( "" );

???

??? try

??? {

????? java.util.Date d = dfLocal.parse(

???????? jtI.getText() );

????? jtI.setText( dfLocal.format( d ) );

????? jtI.setCaretPosition(0);

????? jtD.setText( dfSelected.format( d ) );

????? jtD.setCaretPosition(0);

????? d = dfSelected.parse( jtD.getText() );

????? // get new java.sql.Date

???? ?jsqlDate = new java.sql.Date( d.getTime() );

?????

????? jtP.setText( jsqlDate.toString() );

??? }

??? catch( ParseException pe )

??? {

????? JOptionPane.showMessageDialog( this,

????? pe.getMessage(), "", JOptionPane.ERROR_MESSAGE);

??? }

?

同樣,JIBDateGUI.java:DateFormat 示例上列出了完整的程序。

總結(jié)

以上是生活随笔為你收集整理的JAVA 国际化基础知识(二)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。