Tuesday Feb 12, 2008

JavaFX Scriptの「より簡単な」ローカリゼーション機能

前回のエントリーで、JavaFX Script言語の文字列リテラルの簡単なローカリゼーションの提案について説明しました。現時点でその実装が OpenJFXコンパイラリポジトリにコミットされたので、実際にどう動いているかをみてみることができます。例としてこのリポジトリにあるJavaFXBallsというデモを日本語にローカライズしてみました(このローカリゼーション自体もリポジトリに入っています)。

左下のボタンのテキスト、「ストップ」がソースコード上どうなっているかというと、ボタンのオブジェクトリテラルを作っているところのコードは:

text: bind if (not test._is_running) then ##"Start" else ##"Stop"

で、それに対応するJavaFXプロパティファイルのエントリーは:

"Stop" = "ストップ"

これだけ、です。

さて、今現在考えているのは、この機能をソースコードの文字列リテラルのローカリゼーションだけではなく、より一般的なローカリゼーション機能として使えないかということ。例えばJavaFXのランタイムライブラリとして、javafx.util.StringLocalizerというクラスを作り、その APIで、

package javafx.util;

public class StringLocalizer {

    public attribute key: String;
    public attribute locale: java.util.Locale;
    public attribute packageName: String;
    public attribute propertiesName: String;
    public attribute defaultString: String;

    // this is lazily bound to the above attributes.
    public function localizedString(): String;

    public static function associate(packageName: String,
                                     scriptFileName: String,
                                     properties: String): Void;
}

としたらどうでしょう。これらのAPIを使うことにより、次のようなことが可能になるはずです。

// ローカリゼーションオブジェクトの作成。
var localizer = StringLocalizer{ key: "Hello, World!" };

// "Hello, World!"のデフォルトロケール用の翻訳を出力。
System.out.println(localizer.localizedString());

// "Duke"のデフォルトロケール用の翻訳を出力。
localizer.key = "Duke";
System.out.println(localizer.localizedString());

// "Duke"のフランス語の翻訳を出力。
localizer.locale = Locale.FRENCH;
System.out.println(localizer.localizedString());

// "Duke"のフランス語の翻訳を、"foo/bar/MyBundle_fr.fxproperties"
// から探してきて出力。
localizer.packageName = "foo.bar";
localizer.propertiesName = "MyBundle";
System.out.println(localizer.localizedString());

また、"associate()"スタティック関数を使うことにより、JavaFX Scriptのソースファイル(またはJavaFXのパッケージごと)をJavaFXプロパティにマップすることができます。これにより文字列リテラルのローカリゼーションを探すプロパティファイルを指定できるようになります(デフォルトではソースのJavaFX Scriptファイルと同じ名前・場所のJavaFXプロパティファイルから探します)。このスタティック関数を使うことで、アプリケーションのプロパティファイルをどのようにパッケージするかを柔軟に指定できるようになるのです。一つのプロパティファイルで全アプリケーションのローカリゼーションを保持するか、ソースファイルごとにプロパティファイルを持つか、あるいはその中間か、など。

これはまだまだアイディアの段階で、実際にコミットするときにはもっと洗練されていると思いますが、この機能によって「より簡単に」JavaFX Scriptのローカリゼーションが可能になれば、と思っています。

\*Easier\* localization in JavaFX Script

In the last blog entry, I explained the proposal for an easy way to localize string literals in JavaFX Script language. Now the implementation for it is in the OpenJFX Compiler's repository, let's take a look at this feature in action. As an example, I localized the JavaFXBalls demo into Japanese (it's in the repository as well):

You see the text in the button at the bottom left corner reading "ストップ", which means "Stop". In this button's object literal creation, the source code looks like:

text: bind if (not test._is_running) then ##"Start" else ##"Stop"

And it's JavaFX properties file entry is simply:

"Stop" = "ストップ"

Now, we are planning to extend this string literal localization proposal into a generic string localization runtime library function. Suppose that there is a JavaFX runtime library class, e.g., javafx.util.StringLocalizer, and it has the following APIs:

package javafx.util;

public class StringLocalizer {

    public attribute key: String;
    public attribute locale: java.util.Locale;
    public attribute packageName: String;
    public attribute propertiesName: String;
    public attribute defaultString: String;

    // this is lazily bound to the above attributes.
    public function localizedString(): String;

    public static function associate(packageName: String, 
                                     scriptFileName: String,
                                     properties: String): Void;
}

With these utility APIs, you could do something like:

// Object creation
var localizer = StringLocalizer{ key: "Hello, World!" };

// This prints localized text for "Hello, World!" for the default locale
System.out.println(localizer.localizedString()); 

// This prints localized text for "Duke" for the default locale
localizer.key = "Duke";
System.out.println(localizer.localizedString()); 

// This prints localized text for "Duke" for the French locale
localizer.locale = Locale.FRENCH;
System.out.println(localizer.localizedString()); 

// This prints localized text for "Duke", from 
// the FX properties file "foo/bar/MyBundle_fr.fxproperties
localizer.packageName = "foo.bar";
localizer.propertiesName = "MyBundle";
System.out.println(localizer.localizedString()); 

Also, with the "associate()" static function, you could associate a JavaFX Script source file (or a javafx package) to a JavaFX properties file so that the string literal localization consults the associated JavaFX properties file for searching the localized text. (By default, the JavaFX properties file with the same name/location as the source file is searched). This static function would provide developers with the granularity of how the JavaFX properties files are packaged. You could provide one single JavaFX properties for your entire application, or one properties file for each source script file, or in between.

This is still a rough idea and needs to be refined. But I'd hope this would contribute to an \*easier\* localization in JavaFX.

About

naotoj

Search

Categories
Archives
« February 2008 »
SunMonTueWedThuFriSat
     
1
2
3
4
5
6
7
8
9
10
11
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 
       
Today
News

No bookmarks in folder

Blogroll