2012-09-29

Rhino1.7R4向けに、単一の関数をJavaイベントリスナに変換する関数を作ってみた

Rhino1.7R4で単一の関数をWindowLisenerの実装に使うとエラーが発生する件で、 対策案としてWindowLisenerの全てのメソッドを実装する例を挙げた。
が、7つもあるメソッドのうち主に使用するのはwindowClosingくらいなので、これは面倒くさい。
そこで、過去のRhinoと似た動きをさせるための関数を作ってみた。

1-1. 単一の関数をJavaイベントリスナに変換する関数(function-as-listener.js前半):
function newListener(listenerInterface, handlerFunc) {
    function getDispatcher(methodName) {
        return function(args) {
            var actualArgs = [];
            for (var i = 0; i < arguments.length; i++) {
                actualArgs.push(arguments[i]);
            }
            actualArgs.push(methodName);
            return handlerFunc.apply(this, actualArgs);
        };
    };
    var clazz = listenerInterface.__javaObject__;
    var methods = clazz.getMethods();
    var handlerObj = {};
    for (var i = 0; i < methods.length; i++) {
        var method = methods[i];
        handlerObj[method.getName()] = getDispatcher(String(method.getName()));
    }
    return new listenerInterface(handlerObj);
}

1-2. 使用例(function-as-listener.js後半):
var gui = new java.awt.Frame("function-as-listener");
gui.addWindowListener(newListener(
    java.awt.event.WindowListener,
    function(event, methodName){
        if (methodName === "windowClosing") {
            event.getWindow().setVisible(false);
            return;
        }
        java.lang.System.out.println(methodName);
    }
));
gui.setSize(200, 100);
gui.setVisible(true);
java.lang.Thread.currentThread().sleep(1000);
gui.dispose();
java.lang.System.out.println("ok");

2. Rhino1.7R4で実行する:
>java -classpath .;js.jar org.mozilla.javascript.tools.shell.Main -w -debug function-as-listener.js
windowActivated
windowOpened
ok
windowDeactivated
windowClosed

3. jrunscript(Java1.7)で実行する:
>jrunscript function-as-listener.js
windowActivated
windowOpened
windowDeactivated
windowClosed
ok

0 件のコメント:

コメントを投稿