今回はアプリケーションを作成する上で見過ごされがちではあるのですが、
もう読者の皆さんにはおわかりのはずですね。そう、
アプリケーションを動作させることを、
そのため、
Javaで国際化を行う場合、
これに対し、
そこで、
- ロケールによる文字列の切り替え
- 埋め込み文字列のフォーマット
今回使用したサンプルのソースを含めたNetBeansのプロジェクトは下記のリンクよりダウンロードすることができます。
- NetBeansのプロジェクト
(javafx12. zip)
なお、
ロケールによる文字列の切り替え
国際化を行うに当たって、
コンボボックスで都市を選択すると、
// 都市名
var cities = ["New York", "Paris", "Tokyo"];
// タイムゾーン
var timezones = [
TimeZone.getTimeZone("America/New_York"),
TimeZone.getTimeZone("Europe/Paris"),
TimeZone.getTimeZone("Asia/Tokyo")
];
// 選択項目が変更したら、デフォルトタイムゾーンを変更する
var selectedIndex: Integer = 0 on replace {
TimeZone.setDefault(timezones[selectedIndex]);
}
// 時間を表す変数
var time = new Date();
// 1秒ごとに時間を更新するためのタイムライン
Timeline {
repeatCount: Timeline.INDEFINITE
keyFrames: [
KeyFrame {
time: 0s
action: function() {
time = new Date();
}
},
KeyFrame {
time: 1s
}
]
}.play();
Stage {
title: "World Clock"
scene: Scene {
width: 350 height: 100
content: [
SwingLabel {
translateX: 20 translateY: 13
text: "City:"
},
SwingComboBox {
translateX: 70 translateY: 7
width: 250
// 選択項目はselectedIndexに双方向バインドさせる
selectedIndex:
bind selectedIndex with inverse
items: for (city in cities) {
SwingComboBoxItem {
text: city
}
}
},
Text {
font: Font {
size: 20
}
x: 20 y: 70
// 時間表示
content: bind "{time}"
}
]
}
}
コンボボックスで都市名を選択すると、
タイムゾーンにはJavaのjava.
図1に動作例を示します。Tokyoを選択しているので、

では、
JavaFXではロケールに応じた文字列の変更はとても簡単に行うことができます。たとえば、
text: ##"City:"
文字列の前にシャープを2つ付け足すだけです。
Javaのリソースバンドルではキーに対応した文字列をロケールによって変更させますが、
次に行うのが、
リソースファイルはデフォルトではスクリプトのファイル名に言語を付け加え、
作成したリソースファイルはスクリプトファイルと同じディレクトリに配置します。したがって、

worldClock_
@charset "Shift_JIS";
"City:" = "都市:"
先ほど##を付けた文字列をキーとし、
また、
では、

図1では
他の文字列に関しても日本語のリソースを記述してみましょう。スクリプトで##を付加する文字列として、
// 都市名
var cities = [##"New York", ##"Paris", ##"Tokyo"];
...
Stage {
title: ##"World Clock"
...
これに対応して、
@charset "Shift_JIS";
"City:" = "都市:"
"World Clock" = "世界時計"
"New York" = "ニューヨーク"
"Paris" = "パリ"
"Tokyo" = "東京"
これだけで日本語に対応することができました。さっそく実行してみましょう。

ここでは通常の文字列しか扱いませんでしたが、
このように簡単に各国語に対応できることはわかりました。しかし、
また、
このような場合、
ここでは、
// 都市名
var cities = [
##[NY]"New York",
##[PR]"Paris",
##[TK]"Tokyo"
];
"New York"の文字列に対応するキーは"NY"とし、
リソースファイルはリスト7のようになります。
@charset "Shift_JIS";
"City:" = "都市:"
"World Clock" = "世界時計"
"NY" = "ニューヨーク"
"PR" = "パリ"
"TK" = "東京"
実行結果は図4と同じなので示しませんが、
スクリプトとリソースファイルの結びつけ
デフォルトでは1つのスクリプトファイルにつき、
そこで、
StringLocalizerクラスにはassociate関数とdissociate関数が定義されています。associate関数がスクリプトとリソースファイルの結びつけ、
associate関数はオーバロードされており、
ここでは、

この変更に伴うスクリプトの変更は、
// スクリプトファイルとリソースファイルを結びつける
StringLocalizer.associate("resources/worldClock", "", "worldClock.fx");
associate関数の第1引数がリソースファイルの場所を示しています。実際のリソースファイル名はresources/
また、
var cities = ["New York", "Paris", "Tokyo"];
var localizer = StringLocalizer { key: cities[0] }
println("New York: {localizer.localizedString}");
localizer.key = cities[1];
println("Paris: {localizer.localizedString}");
localizer.key = cities[2];
println("Tokyo: {localizer.localizedString}");
StringLocalizerオブジェクトのkeyアトリビュートにキーとなる文字列を指定すると、
埋め込み文字列のフォーマット
JavaFX Scriptでは文字列中に{ }を記述することで、
今までは単にオブジェクトを記述していましたが、
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}");
%で始まる部分がフォーマット文字列です。ここで使用できるフォーマット文字列は、
このスクリプトを実行した結果を図6に示します。
x = 10.000000 x = 10.00 x = 10 x = +0010.00 x = 10.0000
フォーマット文字列を指定しなかった場合は、
%dや%fなどの数値フォーマットや%sはロケールに応じて変更することはありませんが、
日付/
フォーマット文字列 | 説明 | 出力例 |
---|---|---|
%tx | ローカライズされた日付表現 | 2009年2月9日 |
%tX | ローカライズされた時間表現 | 2時56分35秒 JST |
%tG | ISO8601形式の4桁の西暦年。ISO8601で表した週数に対応している | 2009 |
%tg | ISO8601形式の2桁の西暦年。ISO8601で表した週数に対応している | 09 |
%tu | 曜日の数値表現。月曜が1、 |
1 |
%tU | 週数。1月の第1日曜を第1週とする | 06 |
%tV | ISO8601で表した週数。その年に少なくとも4日以上含まれる最初の週を第1週とする | 07 |
%tw | 曜日の数値表現。日曜日が0、 |
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_
たとえば、


英語ロケールでは代替カレンダがないため西暦で表され、
しかし、
Text {
font: Font {
size: 20
}
x: 20 y: 70
// 時間表示
content: bind "{%ta time} {%tx time} {%tl time}:{%tM time}:{%tS time} {%Tp time
}
英語ロケールで表示すると、

英語ではこの順番ですが、
つまり、
// 時間表示
content: bind ##"{%ta time} {%tx time} {%tl time}:{%tM time}:{%tS time} {%Tp time}"
そして、
"%ta %tx %tl:%tM:%tS %Tp" = "%2$tx(%1$ta) %6$Tp %3$tl:%4$tM:%5$tS"
キーの部分はスクリプトでの文字列から{ }と変数を除いた文字列とします。値には見慣れない数字と$が入っています。これはフォーマット文字列の順番を表しています。最初の%2$txはキーの2番目のフォーマット文字列である%txに対応しています。
これを図示したのが図10です。このように、

では、

今回示したようにJavaFXの国際化は、
残念ながら、
また、
なお、