因為最近在 GWT 遇到很多坑,所以在此紀錄一下
使用 JS Code
根據 GWT 官方 Blog 的範例,要使用 JS Code 的話,如下:native String flipName(String name) /*-{
// ...implemented with JavaScript
var re = /(\w+)\s(\w+)/;
return name.replace(re, '$2, $1');
}-*/;
藉由native
關鍵字、/*-{}*/;
的語法來引用其他語言的程式碼。
JS 使用 Java code
根據官網,使用 Java method ,得以這種方式撰寫:@{Class Name With Path}::{Method Name}(L{java/lang/String};)({Value});
例如使用 new org.example.foo.Flipper.onFlip(Object obj)
,則寫成
@org.example.foo.Flipper::onFlip(L{java/lang/Object};)(obj);
在同一 Class
這個在官網已經有範例了:package org.example.foo;
public class Flipper {
public native void flipName(String name) /*-{
this.@org.example.foo.Flipper::onFlip(Ljava/lang/String;)(s);
}-*/;
private void onFlip(String flippedName) {
// do something useful with the flipped name
}
}
使用其他 class 的 method
假設有以下的 classpackage org.example.client;
public class Bar {
public void onLoad(Object data){
// ...
}
}
我要使用 Bar 的 onLoad 要這樣處理
public native void barLoadData(Bar b) /*-{
var o = {}
b.@org.example.client.Bar::onLoad(Ljava/lang/Object;)(result);
}*-/;
native method 使用其他 native method code
如果你認為 native 用 native 可以像這樣子
package org.example.foo;
public class Flipper {
public native void flipName(String name) /*-{
}-*/;
public native void loadName(String name) /*-{
this.flipName(name);
}-*/;
}
抱歉,你只會得到 error
因為 GWT 將 Flipper 轉換成 javascript code 時, method 也會變更名稱,所以 Flipper 轉成 JS 不是
{
flipName: function(name){/* ... */},
loadName: function(name){
this.flipName(name);
},
}
而可能是
{
Ab: function(name){/* ... */},
Cd: function(name){
this.flipName(name);
},
}
要正確地讓其使用 flipName function 還是得用
@{Class Name With Path}::{Method Name}(L{java/lang/String};)({Value});
即是
package org.example.foo;
public class Flipper {
public native void flipName(String name) /*-{
}-*/;
public native void loadName(String name) /*-{
this.@org.example.foo.Flipper::flipName(Ljava/lang/String;)(name);
}-*/;
}
使用其他 JS 變數、function
如果要使用全域變數、function,例如我有以下 function
function foo(){
// ...
}
要使用 foo()
,可能會認為 foo()
或者 window.foo()
吧。
但事實上,在 GWT 沒法這樣取得 window object,所以這兩種寫法都是錯的。在 GWT 中要使用 window object 得用變數 $wnd
所以 GWT code 應為
native void sayHelloInJava(String name) /*-{
$wnd.sayHello(name); // $wnd is a JSNI synonym for 'window'
}-*/;
其他
關於在 HTML 頁中使用 GWT 的 method,這種狀況我還沒遇到。所以跳過
不過在官網上其實有寫,在Getting to really know GWT, Part 1: JSNI的«Using JSNI to access external JavaScript code»段落中。
參考資料
Getting to really know GWT, Part 1: JSNI. (2008, August 17). Google Web Toolkit Blog. https://webtoolkit.googleblog.com/2008/07/getting-to-really-know-gwt-part-1-jsni.html
What is the native keyword in Java for? (2020, June 10). Stack Overflow. https://stackoverflow.com/a/30635871
C. (2014, April 22). GXT – JavaScript Native Interface (JSNI callable javascript). My Blog. https://codefollow.wordpress.com/2014/04/22/gxt-javascript-native-interface-jsni/
沒有留言:
張貼留言