2008年2月12日火曜日

ResourceBundleを使って国際化する

UIに表示される文字列をソースコードに書き込む(いわゆるハードコーディング)をするのではなく、ソースコードとは別なところに定義しておいて、プログラム的に読み込む方法の話です。 Windowsならリソースを定義するわけなのだが、Javaではどうするのかということです。Javaの場合、Cocoaのそれと同じ感じで、ロケールごとに文字列を定義する方法をとります。

まずは、プログラム側ですが、ResourceBundleを使って表示しようとしているロケールの定義を呼び出します。そこから、定義されている文字列を取得する。

ResourceBundle bundle = ResourceBundle.getBundle(<リソース名>);
bundle.getString(<キー文字列>);

ここで、<リソース名>といっているのは、リソースを定義するファイル名だが、デフォルトは「<リソース名>.properties」というファイル名になり、言語ごとの定義は「<リソース名>_<ロケール名>.properties」となる。ちなみに日本語の場合、「<リソース名>_ja.properties」でよいだろう(「ja」でよいかどうか心配なら、JDKドキュメントの国際化とのころを参照されたし)。あと、パッケージの中に定義ファイルを置くときは、「<パッケージ名>.<リソース名>_<ロケール名>.properties」とすればよい。

リソースの定義ファイルの中身は「<キー文字列>=<リソース文字列>」となる。例えばこんな感じ。

FileMenuItem=ファイル(F)
EditMenuItem=編集(E)

ただし、このファイルを作成するに当たり、気をつけないといけないことは、コード系を「ISO-8859-1」(すなわち、ASCII)で保存しなければならない。日本語のリソースの場合どうすればいいかというと、Unicodeエスケープ(\udddd 表記)で保存する。エスケープされた文字列を手で打ち込んでもかまわないが、あまりにも面倒なので日本語として可視なファイルから変換したほうがよさそうだと思う。

そこで、どうするかというと「native2ascii」というツールがJDKにあるのでこれを使って変換する。

Windowsの場合だと、Windowsネイティブ(Shift_JIS)で書いておいて、ASCIIコードに変換するという手順になるだろう。例としてのコマンド実行は以下にような感じ

> native2ascii -encoding=ShiftJIS myBundle_ja.sjis myBundle_ja.properties

もちろん、この方法でコマンド実行すればよいのだが、いわゆるバッチファイルを使ったり、makeファイルを書いたほうが便利だと思う。ここでは、Eclipseを使っているとして、折角なのでAntで書いてみる。
ちなみにターゲットとなるpropertyiesファイルと同じ名前で、どこかのフォルダに入れておいて、そのフォルダのパスを"src"に設定する。

<project name="MyProject" default="bundle">
<target name="bundle">
<native2ascii src="<入力パス>" dest="<出力パス>" encoding="Shift_JIS" includes="**/*.properties" />
</target>
</project>

というような内容のファイルを「build.xml」という名前で保存して、実行する(パッケージエクスプローラーで「build.xml」のコンテキストメニューからRun(実行)をメニューから「Ant」を選択)。

0 件のコメント: