如何创建没有成员名称的JavaFX WebBrowser javascript侦听器

时间:2017-05-19 20:19:47

标签: javascript java javafx javafx-2 javafx-webengine

我一直在使用此代码片段在我的javafx浏览器中创建js侦听器:

       engine.getLoadWorker().stateProperty().addListener(
                (observable, oldValue, newValue) -> {
                    if (newValue == Worker.State.SUCCEEDED) {
                        System.out.println("changed event detected");
                        JSObject win = (JSObject) engine.executeScript("window");
                        win.setMember("java", new JavascriptListener());
                    }
                }
        );

但是我希望能够调用我的函数而不用#34; java"作为前缀。

这可能吗?

1 个答案:

答案 0 :(得分:2)

一般来说,没有。

没有(工作)java / javascript函数可以在本机范围内执行此操作。我尝试了javascript Object.assign函数,但它不适用于变量或方法。其他类似的东西也无法在Java对象上正常工作

如果你愿意让自己暴露在Java反思的恐怖之中,那就是我的客人:

public class JavaVariableAssigner {

                                                                 //javascript-stored objects do not appear to the
    private static ArrayList<Object> gcLock = new ArrayList();   //garbadge collector so we need to make sure
                                                                 //they don't get deleted by always keeping
                                                                 //a reference to them from this list


    public static void addAllMembers(WebEngine browser, Object obj) {
        gcLock.add(obj);

        ((JSObject) browser.executeScript("window")).setMember("java", obj);

        for(Method m : obj.getClass().getDeclaredMethods()) {
            ArrayList<String> parameterNames = new ArrayList();
            for(Parameter p : m.getParameters()) parameterNames.add(p.getName());
            String params = String.join(",", parameterNames.toArray(new String[0]));
            browser.executeScript("function "+m.getName()+"("+params+"){ return java."+m.getName()+"("+params+"); };");
        }

        for(Field  f : obj.getClass().getDeclaredFields()) {
            browser.executeScript("var "+f.getName()+" = java."+f.getName()+";");
        }
    }

}

使用&#39; java&#39;的所有代码前缀将继续有效,但现在(希望)只需输入其名称即可直接访问每个方法。

就像我(有点)说的那样,这种方法完全依赖于拼凑javascript和评估它所以我不推荐它。