Just my 2¢
Naoto Sato's Weblog
All | General | Java | Music
All Languages | English Only | 日本語のみ

20080110 Thursday January 10, 2008

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

またまたしばらく間が空いてしまいましたが、ここ最近はずっとJavaFX Scriptの国際化についての仕事をしています。JavaFX ScriptはJavaをベースにしたスクリプト言語なわけで、もちろんJavaに本来備わっている国際化に関する機能はすべて使えるわけですが、JavaFX ScriptからいちいちJavaの機能を呼び出して国際化関連のことを行うのはスクリプト言語らしくないし、さらにJava言語とJavaFX言語が混在してバグの元になりかねません。そこでJavaFX言語の仕様策定中ということもあり、その中に入れてしまいたいのがリテラル文字列を簡単にローカライズできる仕組みです。ある文字列をローカライズする場合、Javaでは普通、

    import java.util.ResourceBundle;

    static final String GREETINGS_KEY = "HELLO_WORLD";

    String greetings;
    try {
        ResourceBundle rb = ResourceBundle.getBundle("foo.bar.resources.My_Resource");
        greetings = rb.getString(GREETINGS_KEY);
    } catch (MissingResourceException mre) {
        greetings = "Hello, World!";
    }

の様に書くと思いますが、いま模索中なのがGNUのgettext()関数のように、引数となる文字列がそのままデフォルトの翻訳になるような仕組みです。上のコードをそのシンタックスで表記すると、

    var greetings = ##"Hello, World!";

たったの一行。シンプルでしょ?ここで"##"はリテラル文字列に働く単項演算子のような役割をします。この演算子がつくと実行時にこのリテラル文字列"Hello, World!"をキーとして適当な翻訳を探します。お気づきの方もいると思いますが、PropertyResourceBundleはホワイトスペース' 'をデリミタとして解釈するため、実は"Hello, World!"はキーとはなり得ないんです。そこで提案したいのがJavaFX Script用の新しいリソースバンドルのフォーマット。このフォーマットは単純に次のようなフォームを取ります。

    <JavaFX string literal> = <JavaFX string literal>
e.g.,
    "Hello, World!" = "こんにちは、世界!"

さらにボーナスとして考えているのは、このFX propertiesのデフォルトのエンコーディングを"UTF-8"にしようというもの。これで今まで頭を痛めてきた"ISO-8859-1" & native2asciiの呪縛から解放されるでしょう。他のエンコーディングを指定したい場合は、ファイルの頭にCSS形式のエンコーディング宣言(@charset "<IANA defined charset name>";)を入れてあげればそれに従うようにします。

ただこの方式には問題が一つあり、スクリプト内に同じリテラル文字列があり、それぞれ別の翻訳をさせたい場合(例えば2つの"File"というリテラル文字列をそれぞれ名詞、動詞として翻訳したい場合)に困ってしまいます。この問題を解決するためにオプションとしてキーを明示的に指定できるようにしました。#[FILE_NOUN]"File"のように、大括弧でくくって明示的なキーを指定します。

まあこんな所ですが、プロポーザル(英語です)とプロトタイプ実装をPlanet JFX wikiに置いてみたんで、どうぞおためしください。それとコメント、感想もよろしく!

(2008-01-10 15:55:55.0) Permalink Comments [3]


archives
links