Как вызвать с помощью метода Java объекта экземпляра GWT из рукописного JavaScript? - PullRequest
0 голосов
/ 02 октября 2018

Я хотел бы вызвать метод объекта GWT (чтобы открыть всплывающее окно GWT, обновить экран или отправить событие объекту GWT).И я хотел бы знать, как я могу получить экземпляр объекта GWT в свой код JavaScript.

Я использую GWT 2.8 с JSInterop.Я знаю, как создать новый экземпляр, но я хотел бы получить экземпляр, который уже создан.

Ответы [ 2 ]

0 голосов
/ 04 октября 2018
  1. GWT не создает ссылки типа DOM Element -> GWT Widget, только GWT Widget -> DOM Element и GWT Widget -> GWT Widget.
  2. Также нет возможности прямого создания GWT Widget в коде JavaScript.Если вы хотите, вы должны создать класс-оболочку с 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, чтобы показатьэти способы.Проект состоит из тестов, которые запускаются в процессе сборки и вызывают javascript с использованием HtmlUnit.

Структура проекта:

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;
}

Примечание: namespace равно JsPackage.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>
0 голосов
/ 02 октября 2018

В вашем Java-коде храните метод вашего экземпляра в общедоступном месте, например $wnd.myInstance.Позже в JavaScript-коде вы можете получить к нему доступ, используя window.myInstance().

. В официальных документах GWT для статических методов есть полный пример .Если вам это нужно для нестатических методов, оно должно работать с небольшими изменениями.

...