可以从javascript调用非静态gwt java方法

rau*_*uch 2 javascript java gwt jsni exporter

一般目标:从javascript调用一些非静态java方法

描述:在Java Applet代码中查找DOM上的gwt小部件并调用它的java方法(非静态)


JSObject win = JSObject.getWindow(this);
JSObject doc = (JSObject) win.getMember("document");
JSObject gwtWidget = (JSObject) doc.call("getElementsByName", widgetName);

//todo: have possibility to call `exported` java method over here, smth like:
//Object[] params = new Object[1];
//params[0] = widgetName;
//Object result = gwtWidget.call("exportedJavaMethod", params);

//todo: or just call global ($wnd) static JSNI bridge method:
//Object result = win.call("exportedJavaMethod", params);
//
Run Code Online (Sandbox Code Playgroud)

问题是:我可以通过widget的id找到不是widget,但是它的DivElement没有任何导出的实例化方法.

我的widget类是Exportable(gwt-export):


@Export(value="somewidget")
public class SomeWidget extends SimplePanel implements ..., Exportable {
    private final String id = "id_some_widget_" + count++;
    private static int count = 0;

    public SomeWidget () {
        getElement().setAttribute("name", id);
        getElement().setId(id);
    }
    ...

    public static Element getInstanceById(String elementId) {
        Element someWidget= DOM.getElementById(elementId);
        return someWidget;
    }

    public String getSomeInstancedData() {
        return "useful_inner_data" + this.id;
    }
Run Code Online (Sandbox Code Playgroud)

所以,例如,我想找到添加到DOM的具体小部件,并getSomeInstancedData()在javascript中调用非静态方法.有可能吗?

假设smth像:


var someWidget = document.getElementById(widgetId);
alert(someWidget.getSomeInstancedData());

//or:
var someWidgetExported = com.mypackage.widgets.somewidget.getInstanceById(listenerId);
alert(someWidgetExported.getSomeInstancedData());
Run Code Online (Sandbox Code Playgroud)

在Base模块中我写道:


ExporterUtil.exportAll();
Run Code Online (Sandbox Code Playgroud)

有一个View(ViewWithSomeWidget.ui.xml)包含这个小部件:

...
base:Form
base:SomeWidget ui:field="someWidget" ...
...
/base:SomeWidget
...

当SomeWidget没有实现Exportable时,项目运行良好,但我无法调用找到的widget的DIV元素的非静态方法.

到时候,为了解决问题,SomeWidget实现了Exportable,但是由于使用延迟绑定的ClassCastException,progect没有显示具有SomeWidget的View:


ClassCastException: com.mypackage.widgets.SomeWidgetExporterImpl cannot be cast to com.mypackage.widgets.SomeWidget
Run Code Online (Sandbox Code Playgroud)

那么,可能还有其他方法可以找到widget的javascript对象并调用它的导出java方法?无论如何,任何想法都非常感激.

Lau*_*eld 11

您可以声明一个javascript函数,它将触发非静态方法.

例如:

package com.example;
public class Layout extends VLayout() {
    private String nonStaticVar = "nonStaticVar";
    public Layout() {
        declareMethod(this);
    }

    //Method which declares non-static method in javascript
    public native void declareMethod(Layout layout) /*-{
        var layout = layout;
        $wnd.doSomething = function(someString) {
            layout.@com.example.Layout::doSomething(Ljava/lang/String;)(someString);
        }
    }-*/;

    //Non static method which is being called
    public String doSomething(String someString) {
        //Do something, e.g. set var in this instantiated class, or output stuff
        this.nonStaticVar = someString;
        Window.alert(someString);
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,调用doSomething("bla"); 从javascript将调用您的非静态方法.