JavaScript (ECMAScript) から SWT を呼んで、Windows 用のスタンドアロンアプリを作ってみた。
とりあえず Hello World っぽいのはこんな感じ。ボタンを押すとメッセージボックスが出る。
var d = Display.getDefault(); var s = new Shell(d, SWT.TITLE | SWT.CLOSE | SWT.BORDER | SWT.RESIZE); s.text = "Hello Rhino"; s.setLayout(new FillLayout()); s.setSize(100, 70); var b = new Button(s, SWT.NONE); b.text = "button!!"; b.addSelectionListener(function(event) { var m = new MessageBox(s); m.message = "!!!"; m.open(); }); s.open(); while (!s.disposed) { if (!d.readAndDispatch()) { d.sleep(); } } d.dispose();
作り方
実装の仕方はいろいろ考えられるけど、今回は「exe をクリックすると、同じディレクトリで同じ名前の js ファイルが実行される」というスタイルにした。使ったのは、以下のもの。
- JDK or JRE
- http://java.sun.com/
- SWT
- http://www.eclipse.org/swt/
- Rhino
- http://www.mozilla.org/rhino/
- exewrap
- http://www.ne.jp/asahi/web/ryo/exewrap/
あとは、Rhino にスクリプトファイルを読ませる Java クラスがあればいい。基本的にはサンプルの RunScript まんま。
今回は、トップレベルのオブジェクトとして ImporterTopLevel を使用し、Java クラスの側で SWT のパッケージを全部インポートした。上に載せたスクリプトで SWT のクラスをいきなり使えてるのはそのため。
作ってみて
手間はとにかくかからなかった。今回 Java で書いたコードはわずか 85 行 (コメントと空行を含む)。SWT の操作については、Rhino がリフレクションでうまくやってくれる。例外処理についても、exewrap のログ出力機能にお任せ。
上のスクリプトでは、イベントリスナを渡すべきところに Function を渡している。これでできちゃうのは、Rhino にそういう機能があるからだ (Rhino のドキュメントに解説がある)。
一方、オブジェクトのプロパティについては、ちぐはぐになっている部分もある。例えば Shell のプロパティについて
s.text = "Hello Rhino";
はできるのに、
s.layout = new FillLayout();
と書くとエラーになるため、
s.setLayout(new FillLayout());
と書かなければならない。原因は、Shell には layout() というメソッドがあって、Rhino はそちらを優先するから。
他の実装方法
例えば、D 言語で、DScript/DWT という実装ができそう。他の言語で作るなら、SpiderMonkey と適当な GUI ツールキットを組み合わせるのもありだろう。
ただしこれらの場合は、Java のようなリフレクションが使えないので、自前でブリッジを用意する必要がある。
すでにある実装例としては、Mozilla の XULRunner がある。