2013-10-15 6 views
3

Сценарий: у меня есть веб-приложение GWT, работающее в JavaFX WebView/WebEngine. Я могу передавать строки из GWT на JavaScript в JavaFX без каких-либо проблем.Передача Java-массива в JavaScript (через JSNI) и возвращение в Java приводит к нулевому значению

Проблема: При передаче массива пользовательских объектов, таких как Data [], таким же образом, результат на стороне JavaFX равен нулю.

примера того, что выглядит данные, как:

public class Data extends Serializable 
{ 
    char[] name; 
    int code; 
    short bar; 
} 

Вот код для отправки данных на JavaScript:

public static native void doNativeStuff(String id, Data[] data) /*-{ 
    $wnd.javaInterface.doStuff(id, data); 
}-*/; 

Я проверял в отладчике, что объект Java передается в заполняется данными и выглядит хорошо.

Теперь на стороне JavaFX, я следующий код для добавления javaInterface на страницу:

JSObject win = (JSObject) engine.executeScript("window"); 
win.setMember("javaInterface", new JavaInterface()); 

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

public void doStuff(String id, Data[] data) 
{ 
    // Right here, id == "validId" and data == null 
    if (data != null) 
    { 
    ... do what is needed ... 
    } 
} 

Обратите внимание, что объект Data определен и доступен с обеих сторон.

Из документации GWT:

Incoming Java type How it appears to JavaScript code 
Java array   opaque value that can only be passed back into Java code 

Я не прикасаясь к нему в JavaScript на всех, и я только пропуская его через из Java-> JavaScript-> Java, но последний шаг, как представляется, что не удается.

Я провел последние несколько часов, просматривая переполнение стека, Google, группы GWT, gwtproject.org и т. Д. Но большинство примеров демонстрируют только один передаваемый аргумент, и почти никто из них не показывает Java-массив быть использованным.

Я бы скорее просто передал объект, а не отправился в --- из JSON, но я действительно дал попробовать попробовать отчаяние. Я пытался использовать GSON, но он не работает на стороне клиента GWT. Я попытался использовать GWT AutoBean Framework, но мой объект Data не является действительным компонентом (я думаю, из-за конструктора по умолчанию), и я не могу изменить это в это время.

Я не использую никаких длинных или длинных значений.

Я видел примеры, как это:

@com.google.gwt.examples.JSNIExample::staticFoo(Ljava/lang/String;)(s); 

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

Я уверен, что здесь есть только незначительная настройка, которую мне не хватает, но пока я не смог ее выяснить. Пожалуйста, дайте мне знать, если вы увидите что-то, что мне здесь не хватает.

+1

Первые вещи первое: это JavaFX позволяет передать эти объекты таким образом? Сначала попробуйте простой JS. –

+0

Спасибо Томас. Попытка этого привела меня к следующему ответу: http://stackoverflow.com/questions/13194326/javafx-2-2-bidirectional-communication-in-javascript-and-webview?rq=1. Похоже, мне нужно будет сериализовать данные на сервере перед отправкой в ​​GWT, а затем передать этот сериализованный JSON (String) в JavaFX. Наконец, JavaFX нужно будет десериализовать. – Splaktar

ответ

2

непрозрачное значение, которое может быть передано только обратно в Java код

Я думаю, что это означает, что вы не можете передать массив Java в код JavaScript.

Согласен с jat. Я использовал для поддержки подобных потребностей, и мне пришлось сериализовать объекты самостоятельно. И вы можете передать несколько аргументов, как это (типы аргументов приведены только для примера):

private native void doJSAction(MyClass handler)/*-{ 
    // do smth in JS 

    // then call external non-static method 
    [email protected]::doMyAction(Lcom/google/gwt/core/client/JavaScriptObject;Ljava/lang/String;Lcom/myclient/helper/MyClass;II)(jsNativeSmth, myString, handler, intA, intB); 
}-*/; 

где doMyAction что-то вроде следующего:

void doMyAction(JavaScriptObject jsObject, String s, MyClass instance, int a, int b) 
+0

Большое спасибо. Сериализация действительно работала. Также спасибо за ответ на мой другой вопрос о формате нескольких непримитивных аргументов. – Splaktar

2

Я не играл с JavaFX, но поскольку он работает в другой виртуальной машине и ничего не знает о протоколе GWT DevMode (например, объект Java обернут в объект JS, который в основном заставляет RPC-вызовы манипулировать им) , Я уверен, что вам придется сериализовать все между GWT и JavaFX как строки и примитивы.