简体   繁体   English

GWT JSNI-调用特定对象的java方法

[英]GWT JSNI - Call java method of specific object

Consider the following widget. 考虑以下小部件。 I add two of them to my page. 我将其中两个添加到我的页面。 The first one gets the name "widget1", the second one the name "widget2". 第一个名称为“ widget1”,第二个名称为“ widget2”。 It just should give out its own name, but called from javascript. 它只是应该给出自己的名称,但是是从javascript调用的。 (The example makes no sense, but is just a simple example to figure out, how it could be done.) (该示例没有任何意义,但仅仅是一个简单的示例,可以弄清楚如何完成此操作。)

public class MyComponent extends Composite{

    String name;
    public MyComponent(String name) {
        this.name =name;

        Button b = new Button(name);
        b.addClickHandler(new ClickHandler() {

            @Override
            public void onClick(ClickEvent event) {
                myonclick();

            }
        });
        initWidget(b);
        declareMethod(this);
    }

    public native void declareMethod(MyComponent myWidget) /*-{
            $wnd.myWidget = myWidget;

    }-*/;

    public native void myonclick() /*-{
        $wnd.myWidget.@de.jsni.test.client.MyComponent::doSomething()();
    }-*/;

    public void doSomething() {
        Window.alert(name);
    }
}

My problem now is: Both button alert the message "widget2". 我现在的问题是:两个按钮都提示消息“ widget2”。 That's because I override the "myWidget"-variable in the "declareMethod". 那是因为我重写了“ declareMethod”中的“ myWidget”变量。 How can I archieve to call the doSomething()-method of the correct object? 如何归档调用正确对象的doSomething()方法? Can I use some kind of namespacing approach here? 我可以在这里使用某种命名空间方法吗?

The problem you have is when a MyComponent is created, $wnd.myWidget is set to refer to that item. 您遇到的问题是在创建MyComponent时, $wnd.myWidget设置为引用该项目。 So, if you create MyComponent #1, then MyComponent #2, you will always have $wnd.myWidget that equals MyComponent #2. 所以,如果你创建MyComponent #1,然后MyComponent #2,你将永远有$wnd.myWidget ,等于MyComponent 2#。

Rather than defining a method which sets a JS variable, refer to the window directly in the native method, as follows: 与其定义一个设置JS变量的方法,不如直接在本机方法中引用窗口,如下所示:

public native void myonclick(MyComponent comp) /*-{
    comp.@de.jsni.test.client.MyComponent::doSomething()();
}-*/;

Then, in the click handler, call myonclick as follows: 然后,在点击处理程序中,如下调用myonclick

@Override
public void onClick(ClickEvent event) {
     myonclick(MyComponent.this);
}

I think this should work. 我认为这应该有效。 Let me know if there are any issues, I'll try to help. 让我知道是否有任何问题,我会尽力帮助。

update : You could try the following, but honestly, I don't know if it will play well with external javascript. 更新 :您可以尝试以下操作,但是老实说,我不知道它是否可以与外部javascript一起很好地运行。 I've never really had to work through this use case. 我从来没有真正需要通过这个用例。

public native void myonclick() /*-{
    this.@de.jsni.test.client.MyComponent::doSomething()();
}-*/;

I was solving my problem now by sinking the events i'm interested in eg: sinkEvents(Event) in the constructor and handling them in my onBrowserEvent(Event e) method. 我现在通过下沉我感兴趣的事件来解决我的问题,例如:构造函数中的sinkEvents(Event)并在我的onBrowserEvent(Event e)方法中处理它们。 This was a mich more easy and convinient way for my problem. 这是解决我的问题的一种更简单,更方便的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM