Friday, May 4, 2012

Exploring JavaFX 2 - アプリケーションパラメタへのアクセス

JavaFXはApplicationクラスオブジェクトからアプリケーションパラメタにアクセスする方法としてApplication.getParameters()を提供します。例えば、ユーザがGNU形式でオプション(名前付きパラメタ)に幅と高さ、引数(名前なしパラメタ)にメッセージを指定すれば:
java AccessApplicationParametersDemo --width=200 --height=100 hello
アプリケーションは次のようにパラメタを受け取れます:
public class AccessApplicationParametersDemo {

    public static void main(String[] args) {
        Application.launch(UsingGetParametersApplication.class, args);
    }

}
public class UsingGetParametersApplication extends Application {

    @Override
    public void start(Stage stage) throws Exception {
        Map opts = getParameters().getNamed();
        System.out.println("width=" + opts.get("width"));
        System.out.println("height=" + opts.get("height"));
        
        List args = getParameters().getUnnamed(); 
        System.out.println("message=" + args.get(0));
    }

}
但しgetParameters()は今のところ(v2.2-b06)オプションのパーサが貧弱で使い勝手がよくありません。省略オプションやPOSIX形式に対応してなく、次の形式のどれも扱えません:
-w=200 -h=100
--width 200 --height 100
-w 200 -h 100
getParemters()をカスタマイズすればいいでしょうか?しかし実装クラスへのアクセスが中でハードコードされていて、メソッドがfinalだと聞いたらどうでしょう?つまりgetParameters()から直接オプションや引数を取得するのは今のところ良い選択ではありません。getParameters()には運搬役に徹してもらい、主な作業はApache Commons CLIに任せるのがお勧めです:
public class UsingCommonsCliApplication extends Application {

    @Override
    public void start(Stage stage) throws Exception {
        Options options = new Options();
        options.addOption("w", "width", true, "");
        options.addOption("h", "height", true, "");
        CommandLineParser parser = new PosixParser();
        CommandLine cmd = parser.parse(
            options, 
            getParameters().getRaw().toArray(
                new String[getParameters().getRaw().size()]
            )
        );
        System.out.println("width=" + cmd.getOptionValue("width")); 
        System.out.println("height=" + cmd.getOptionValue("height")); 
        System.out.println("message=" + cmd.getArgList().get(0));
    }

}
この問題に対するJavaFXチームからの回答は"将来のバージョンでは検討可能"ということなのでそのうち解消されるかもしれません。そもそもこのような機能はパラメタを固定された形式で受けとるAppletやJWSでのみ必要とされるはずなので、JavaFXはAppletApplicationやJWSApplicationのような各環境用のクラスを持ち、それらにのみこの機能を持たせる方が良さそうです。

3 comments:

  1. getParametersメソッドはJavaFXをデスクトップアプリケーション、Applet、Java Web Startのいずれで動作させた時でも、同じようにパラメータを取得できるようにするための機能なので、オプションの解析は必要最低限ですね。
    というか、AppletのパラメータのKey-Value形式に合わせてあるだけで、デスクトップアプリの場合のオプション解析はほとんど想定していないような気がします。

    ReplyDelete
    Replies
    1. そうなんですよね。おっしゃるとおりパラメタ渡し部分の抽象化ということでこうなっているわけで、現時点では仕方ないかな、とは理解しています。そのあたりも触れるべきでしたね、ありがとうございます :-)

      Delete
  2. Applet/JWSとの絡みを少し追記しました。

    ReplyDelete