如何从 Handwritten JavaScript 调用 GWT 实例对象的 java 方法?
How to call with a java method of a GWT instance object from Handwritten JavaScript?
我想调用 GWT 对象的方法(打开 GWT 弹出窗口、刷新屏幕或向 GWT 对象发送事件)。
我想知道如何将 GWT 对象的实例放入我的 JavaScript 代码中。
我将 GWT 2.8 与 JSInterop 结合使用。我知道如何创建一个新实例,但我想获得一个已经创建的实例。
在您的 Java 代码中,将实例的方法存储在 public 位置,例如 $wnd.myInstance
。稍后,在 Java 脚本代码中,您可以使用 window.myInstance()
.
访问它
官方 GWT 文档中有一个 complete example 用于静态方法。如果您需要它用于非静态方法,它应该可以进行微小的更改。
- GWT 不创建
DOM Element -> GWT Widget
类型的链接,仅创建 GWT Widget -> DOM Element
和 GWT Widget -> GWT Widget
类型的链接。
也没有机会在 javascript 代码中直接创建 GWT Widget。如果你想要它,你必须用 JsInterop API 创建一个包装器 class。
示例:
package com.Whosebug.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 中使用这个 class:
var popupPanel = new GwtPopupPanel();
popupPanel.show();
popupPanel.hide();
考虑到第 1 项,您必须从 Java 到 Java 编写变量的脚本代码。有几种方法:
- 通过全局状态(全局变量)传输
- 通过方法参数传递
我创建了简单的 gwt maven 项目来展示这些方法。该项目包含在构建过程中运行并使用 HtmlUnit javascript 调用的测试。
项目结构:
JsInterop class MyClass
:
package com.Whosebug.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;
}
}
Class 全局状态 GlobalVariableExtension
package com.Whosebug.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;
}
注意:namespace
是 JsPackage.GLOBAL
而 name
是 "window"
我们的包装器 PopupPanelJsWrapper
:
package com.Whosebug.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();
}
}
测试classMainTestGwt
:
package com.Whosebug.questions52609313.test;
import com.google.gwt.junit.client.GWTTestCase;
import com.Whosebug.questions52609313.client.GlobalVariableExtension;
import com.Whosebug.questions52609313.client.MyJsClass;
public class MainTestGwt extends GWTTestCase {
@Override
public String getModuleName() {
return "com.Whosebug.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.Whosebug.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.Whosebug.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.Whosebug</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>
我想调用 GWT 对象的方法(打开 GWT 弹出窗口、刷新屏幕或向 GWT 对象发送事件)。 我想知道如何将 GWT 对象的实例放入我的 JavaScript 代码中。
我将 GWT 2.8 与 JSInterop 结合使用。我知道如何创建一个新实例,但我想获得一个已经创建的实例。
在您的 Java 代码中,将实例的方法存储在 public 位置,例如 $wnd.myInstance
。稍后,在 Java 脚本代码中,您可以使用 window.myInstance()
.
官方 GWT 文档中有一个 complete example 用于静态方法。如果您需要它用于非静态方法,它应该可以进行微小的更改。
- GWT 不创建
DOM Element -> GWT Widget
类型的链接,仅创建GWT Widget -> DOM Element
和GWT Widget -> GWT Widget
类型的链接。 也没有机会在 javascript 代码中直接创建 GWT Widget。如果你想要它,你必须用 JsInterop API 创建一个包装器 class。 示例:
package com.Whosebug.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 中使用这个 class:
var popupPanel = new GwtPopupPanel(); popupPanel.show(); popupPanel.hide();
考虑到第 1 项,您必须从 Java 到 Java 编写变量的脚本代码。有几种方法:
- 通过全局状态(全局变量)传输
- 通过方法参数传递
我创建了简单的 gwt maven 项目来展示这些方法。该项目包含在构建过程中运行并使用 HtmlUnit javascript 调用的测试。
项目结构:
JsInterop class MyClass
:
package com.Whosebug.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;
}
}
Class 全局状态 GlobalVariableExtension
package com.Whosebug.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;
}
注意:namespace
是 JsPackage.GLOBAL
而 name
是 "window"
我们的包装器 PopupPanelJsWrapper
:
package com.Whosebug.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();
}
}
测试classMainTestGwt
:
package com.Whosebug.questions52609313.test;
import com.google.gwt.junit.client.GWTTestCase;
import com.Whosebug.questions52609313.client.GlobalVariableExtension;
import com.Whosebug.questions52609313.client.MyJsClass;
public class MainTestGwt extends GWTTestCase {
@Override
public String getModuleName() {
return "com.Whosebug.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.Whosebug.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.Whosebug.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.Whosebug</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>