ついにベールを脱いだJavaFX

第12回 国際化

この記事を読むのに必要な時間:およそ 5.5 分

埋め込み文字列のフォーマット

JavaFX Scriptでは文字列中に{ }を記述することで,オブジェクトを埋め込むことができます。これは読者のみなさんはすでにご存じのはずです。

今までは単にオブジェクトを記述していましたが,フォーマットを指定することもできるのです。たとえば,次のような表記を行うことができます。

リスト10

var x: Number = 10.0;
 
println("x = {%f x}");
println("x = {%6.2f x}");
println("x = {%4.0f x}");
println("x = {%+08.2f x}");
println("x = {%g x}");

%で始まる部分がフォーマット文字列です。ここで使用できるフォーマット文字列は,java.util.Formatterクラスで使用できるフォーマット文字列と同じです。

このスクリプトを実行した結果を図6に示します。

図6 数値のフォーマット

x = 10.000000
x =  10.00
x =   10
x = +0010.00
x = 10.0000

フォーマット文字列を指定しなかった場合は,文字列表記である%sを指定した場合と同じ結果になります。

%dや%fなどの数値フォーマットや%sはロケールに応じて変更することはありませんが,日付/時間はロケールによって変化することがあります。

日付/時間に関するフォーマット文字列はjava.util.Formatterクラスで使えるものだけでなく,POSIXのstrftimeに対応するように拡充されています。表1に拡張されたフォーマット文字列を示します。出力例は日本時間の2009年2月9日(月) 2時56分35秒をフォーマットした場合を示します。

表1 日付/時間に関する拡張フォーマット

フォーマット文字列 説明 出力例
%tx ローカライズされた日付表現 2009年2月9日
%tX ローカライズされた時間表現 2時56分35秒 JST
%tG ISO8601形式の4桁の西暦年。ISO8601で表した週数に対応している 2009
%tg ISO8601形式の2桁の西暦年。ISO8601で表した週数に対応している 09
%tu 曜日の数値表現。月曜が1,日曜が7 1
%tU 週数。1月の第1日曜を第1週とする 06
%tV ISO8601で表した週数。その年に少なくとも4日以上含まれる最初の週を第1週とする 07
%tw 曜日の数値表現。日曜日が0,土曜日が6 1
%tW 週数。1月の第1月曜日を第1週とする 06
%tEc 代替カレンダの日付と時間表現 平成21年2月9日 2時56分35秒 JST
%tEC 代替カレンダの基準年の名前 平成
%tEx 代替カレンダの日付表現 平成21年2月9日
%tEX 代替カレンダの時間表現 2時56分35秒 JST
%Ey 代替カレンダの年 21

代替カレンダというのは,西暦以外の地域に特有のカレンダのことを指します。日本では和暦が代替カレンダとなります。

Javaでは和暦を扱うためにja_JP_JPという特殊なロケールを使う必要がありました。それに比べるとJavaFXでは和暦でもシンプルに表すことができます。

たとえば,先ほどの世界時計で代替カレンダを使用してみましょう。%tEcで時間をフォーマットするとデフォルトでは図7になり,日本語ロケールでは図8となります。

図7 %tEcでフォーマットした世界時計(英語ロケール)

図7 %tEcでフォーマットした世界時計(英語ロケール)

図8 %tEcでフォーマットした世界時計(日本語ロケール)

図8 %tEcでフォーマットした世界時計(日本語ロケール)

英語ロケールでは代替カレンダがないため西暦で表され,日本語ロケールでは和暦で表されました。

しかし,ちょっと違和感があります。たとえば,英語ロケールでは12時間表記で表されているのが,日本語表記では24時間表記で表されている点や,タイムゾーンが日本語ロケールだけ表示されている点などです。そこで,フォーマットをカスタマイズしてみましたリスト11⁠。

リスト11

Text {
    font: Font {
        size: 20
    }
    x: 20 y: 70

    // 時間表示
    content: bind "{%ta time} {%tx time} {%tl time}:{%tM time}:{%tS time} {%Tp time
}

英語ロケールで表示すると,図9のようになります。

図9 カスタマイズ後の時間表記(英語ロケール)

図9 カスタマイズ後の時間表記(英語ロケール)

英語ではこの順番ですが,日本語では曜日は日付の後に表記するなど順番がことなります。そこで,この文字列もロケールによって切り替えてしまいましょう。

つまり,文字列の前に##を付加して記述してしまいます。

リスト12

    // 時間表示
    content: bind ##"{%ta time} {%tx time} {%tl time}:{%tM time}:{%tS time} {%Tp time}"

そして,リソースファイルにリスト13にある行を追加します。

リスト13

"%ta %tx %tl:%tM:%tS %Tp" = "%2$tx(%1$ta) %6$Tp %3$tl:%4$tM:%5$tS"

キーの部分はスクリプトでの文字列から{ }と変数を除いた文字列とします。値には見慣れない数字と$が入っています。これはフォーマット文字列の順番を表しています。最初の%2$txはキーの2番目のフォーマット文字列である%txに対応しています。

これを図示したのが図10です。このように,$の前の数字で表している要素を指定できます。これはFormatterクラスと同じです。

図10 フォーマット文字列の対応

図10 フォーマット文字列の対応

では,これで実行してみましょう。図11に日本語ロケールで実行した結果を示します。

図11 カスタマイズ後の時間表記(日本語ロケール)

図11 カスタマイズ後の時間表記(日本語ロケール)

今回示したようにJavaFXの国際化は,とても簡単に扱うことができます。

残念ながら,現状のJavaFXではデフォルトロケールしか扱うことができません。デフォルトロケールを切り替えることは可能ですが,アプリケーション中で複数のロケールを使用することはできないようです。今後の拡充に期待したいところですね。

また,通貨のフォーマッティングや,アラビア語のように右から左に記述する文字列のサポートなどが,今後行われる予定だそうです。

なお,JavaFX 1.0および1.1では,AppletやJava Web Startでリソースファイルの読み込みを行う場合,JARファイルに署名が必要です。しかし,次のバージョンから署名が不必要になるようです。

著者プロフィール

櫻庭祐一(さくらばゆういち)

横河電機に勤務するかたわらJava in the Boxにて新しい技術を追い続けています。JavaOneは今年で11年目。名実共にJavaOneフリークと化しています。