如何通过手写JavaScript用GWT实例对象的java方法调用?

时间:2018-10-02 13:24:52

标签: java gwt jsni

我想调用GWT对象的方法(打开GWT弹出窗口,刷新屏幕或向GWT对象发送事件)。 而且我想知道如何将GWT对象的实例添加到我的JavaScript代码中。

我将GWT 2.8与JSInterop一起使用。我知道如何创建一个新实例,但是我想获得一个已经创建的实例。

2 个答案:

答案 0 :(得分:2)

  1. GWT不会创建类型为DOM Element -> GWT Widget的链接,仅创建GWT Widget -> DOM ElementGWT Widget -> GWT Widget的链接。
  2. 也没有机会直接用JavaScript代码创建GWT窗口小部件。如果需要,必须使用JsInterop API创建包装器类。 示例:

    package com.stackoverflow.questions52609313.client;
    
    import com.google.gwt.user.client.ui.PopupPanel;
    import jsinterop.annotations.JsMethod;
    import jsinterop.annotations.JsPackage;
    import jsinterop.annotations.JsType;
    
    @JsType(namespace = JsPackage.GLOBAL, name = "GwtPopupPanel")
    public class PopupPanelJsWrapper {
       private PopupPanel popupPanel = new PopupPanel();
    
    
       @JsMethod
       public void hide() {
           popupPanel.hide();
       }
    
       @JsMethod
       public void show() {
           popupPanel.show();
       }
    }
    

    在javascript中使用此类:

    var popupPanel = new GwtPopupPanel();
    popupPanel.show();
    popupPanel.hide();
    

在第1项上,您必须从Java到Javascript代码中获取变量。有几种方法:

  • 通过全局状态(全局变量)转移
  • 通过方法参数传输

我创建了一个简单的gwt maven项目来演示这些方法。该项目包含在构建过​​程中运行并使用HtmlUnit调用javascript的测试。

项目结构:

project

JsInterop类MyClass

package com.stackoverflow.questions52609313.client;

import jsinterop.annotations.JsIgnore;
import jsinterop.annotations.JsPackage;
import jsinterop.annotations.JsProperty;
import jsinterop.annotations.JsType;

@JsType(namespace = JsPackage.GLOBAL)
public class MyJsClass {
    @JsProperty
    private String value;
    @JsIgnore
    private int callCounter = 0;

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }


    public String myMethod() {
        callCounter++;
        return "ok";
    }

    public int getCallCounter() {
        return callCounter;
    }
}

全局状态GlobalVariableExtension的类

package com.stackoverflow.questions52609313.client;

import jsinterop.annotations.JsPackage;
import jsinterop.annotations.JsType;

@JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "window")
public class GlobalVariableExtension {
    public static MyJsClass myGlobalVariable;
}

NB:namespaceJsPackage.GLOBAL,而name"window"

我们的包装器PopupPanelJsWrapper

package com.stackoverflow.questions52609313.client;

import com.google.gwt.user.client.ui.PopupPanel;
import jsinterop.annotations.JsMethod;
import jsinterop.annotations.JsPackage;
import jsinterop.annotations.JsType;

@JsType(namespace = JsPackage.GLOBAL, name = "GwtPopupPanel")
public class PopupPanelJsWrapper {
    private PopupPanel popupPanel = new PopupPanel();


    @JsMethod
    public void hide() {
        popupPanel.hide();
    }

    @JsMethod
    public void show() {
        popupPanel.show();
    }
}

测试类MainTestGwt

package com.stackoverflow.questions52609313.test;

import com.google.gwt.junit.client.GWTTestCase;
import com.stackoverflow.questions52609313.client.GlobalVariableExtension;
import com.stackoverflow.questions52609313.client.MyJsClass;


public class MainTestGwt extends GWTTestCase {


    @Override
    public String getModuleName() {
        return "com.stackoverflow.questions52609313.test";
    }


    private native String passToJs(MyJsClass myVar)/*-{
        myVar.value = "random";
        return myVar.myMethod();
    }-*/;

    public void testPassToJs() {
        MyJsClass toJs = new MyJsClass();
        toJs.setValue("start");
        toJs.myMethod();
        assertEquals("start", toJs.getValue());
        assertEquals(1, toJs.getCallCounter());

        String ok = passToJs(toJs);
        assertEquals("ok", ok);

        assertEquals("random", toJs.getValue());
        assertEquals(2, toJs.getCallCounter());
    }

    private native MyJsClass createFromJs()/*-{
        var myVar = new $wnd.MyJsClass();
        myVar.value = "random";
        myVar.myMethod();
        return myVar;
    }-*/;

    public void testCreateFromJs() {
        MyJsClass fromJs = createFromJs();

        assertNotNull(fromJs);
        assertEquals("random", fromJs.getValue());
        assertEquals(1, fromJs.getCallCounter());
    }

    private native MyJsClass extractGlobalVariable()/*-{
        return $wnd.myGlobalVariable;
    }-*/;

    public void testExtensionGlobal() {

        GlobalVariableExtension.myGlobalVariable = null;
        MyJsClass myJsClassResultNull = extractGlobalVariable();

        assertNull(myJsClassResultNull);

        String qwerty = "qwerty";
        MyJsClass myJsClass = new MyJsClass();
        myJsClass.setValue(qwerty);
        GlobalVariableExtension.myGlobalVariable = myJsClass;
        MyJsClass myJsClassResult = extractGlobalVariable();

        assertNotNull(myJsClassResult);
        assertEquals(myJsClass, myJsClassResult);
        assertEquals(qwerty, myJsClassResult.getValue());

    }
    private native void popupPanelAction()/*-{
        var popupPanel = new $wnd.GwtPopupPanel();
        popupPanel.show();
        popupPanel.hide();


    }-*/;
    public void testCreatePopupPanel(){
        //expect without exceptions
        popupPanelAction();
    }

}

GwtMapsTestSuite

package com.stackoverflow.questions52609313.test;

import com.google.gwt.junit.tools.GWTTestSuite;
import junit.framework.Test;
import junit.framework.TestCase;

public class GwtMapsTestSuite extends TestCase {
    public static Test suite() {
        GWTTestSuite suite = new GWTTestSuite("Test for a Maps Application");
        suite.addTestSuite(MainTestGwt.class);
        return suite;
    }
}

client.gwt.xml

<module>
    <source path='client'/>
</module>

test.gwt.xml

<module>
    <inherits name='com.google.gwt.user.User'/>
    <inherits name='com.google.gwt.logging.Logging'/>
    <!-- Logging Configuration -->
    <set-property name="gwt.logging.enabled" value="TRUE"/>
    <set-property name="gwt.logging.logLevel" value="ALL"/>

    <inherits name="com.stackoverflow.questions52609313.client"/>
    <source path='test'/>


</module>

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.stackoverflow</groupId>
    <artifactId>questions52609313</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <gwt.version>2.8.0</gwt.version>
        <junit.version>4.12</junit.version>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>

        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.google.gwt</groupId>
            <artifactId>gwt-dev</artifactId>
            <version>${gwt.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.google.gwt</groupId>
            <artifactId>gwt-user</artifactId>
            <version>${gwt.version}</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>gwt-maven-plugin</artifactId>
                <version>${gwt.version}</version>
                <configuration>
                    <logLevel>INFO</logLevel>
                    <noServer>false</noServer>
                    <extraJvmArgs>-Xmx1024m</extraJvmArgs>
                    <mode>htmlunit</mode>
                    <testTimeOut>300</testTimeOut>
                    <productionMode>true</productionMode>
                    <generateJsInteropExports>true</generateJsInteropExports>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>test</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

答案 1 :(得分:1)

在Java代码中,将实例的方法存储在$wnd.myInstance之类的公共场所。稍后,您可以使用window.myInstance()在JavaScript代码中进行访问。

GWT官方文档中有一个complete example用于静态方法。如果非静态方法需要此方法,则应进行较小的更改。