Calling JavaScript from Java
– Format of methods
– The $wnd variable
– Argument types
Calling Java from JavaScript
– Format of method types
– Designating overloaded methods
– Argument types
IDEA
- Write Java methods that call JavaScript
– Enclose JavaScript code in comments
•Use $wnd variable to access window object
•Use $doc variable to access document object
– Pass primitives, strings, and arrays only - JavaScript code can call Java
– Use JNI-like format to refer to methods and fields - Notes
– JSNI can be used only for pure client-side code
• Method bodies ignored when used in server-side classes
– JSNI should be used sparingly
• Most normal JavaScript functionality available in GWT
• Mostly used to wrap external JavaScript libraries
- Declare method native
– Can be private or public, static or instance - Use special comments for method body
– Start method with /*-{
– End method with }-*/;
• private native void foo(...) /*-{ JavaScript-Code }-*/; - Argument and return types
– String, numeric primitive, boolean
• Treated normally as argument or return type
– Array
• Argument: only used to be passed back to Java
• Return: only if array came from Java code
– Object
• Argument: special syntax for accessing (see later slide)
• Return: only if Object came from Java code
– JavaScriptObject
• Argument: only if JavaScriptObject came from JavaScript code
• Return: can only be used to pass to another JSNI method
- Basic Syntax: Example (Core Code Adapted from Events Lecture)
public class GwtJsniApp implements EntryPoint {
private TextBox textfield;
private HTML resultArea;
public void onModuleLoad() {
textfield = new TextBox();
textfield.addKeyboardListener(new WowListener());
resultArea = new HTML("<i>Result will go here</i>");
RootPanel.get("textfieldID").add(textfield);
RootPanel.get("resultID").add(resultArea);
}
private class WowListener extends KeyboardListenerAdapter {
public void onKeyUp(Widget sender, char keyCode,
int modifiers) {
String text = textfield.getText();
resultArea.setHTML(text);
if(text.equalsIgnoreCase("test1")) {
alert1(text);
} else if(text.equalsIgnoreCase("test2")) {
highlight1("resultID");
} else if(text.equalsIgnoreCase("test3")) {
highlight2("resultID", text);
}
}
}
private native void alert1(String message) /*-{
$wnd.alert(message);
}-*/;
- Using External JavaScript Libraries
• Load the library
– Put <script> tag in head of HTML page, or
– Put <script> tag in AppName.gwt.xml file - Define JSNI method
– As shown previously - Access objects and functions via $wnd
– $wnd.someFunction(args)
– new $wnd.SomeObject(args)
– var $wnd.newFunction = function(args) { body } - Access document via $doc
– $doc.title = "New Title";
HTML
<HTML>
<head><title>JSNI</title>
<link rel="stylesheet" href="./css/styles.css" type="text/css"/>
<!------ scripts folder installed in src/mainPackage/public
(Same place you put images and css files) --->
<script src="./scripts/prototype.js" type="text/javascript"></script>
<script src="./scripts/scriptaculous/scriptaculous.js?
load=effects" type="text/javascript"></script>
<script language='javascript' src='coreservlets.GwtJsniApp.nocache.js'>
</script>
</head>
JAVA
private class WowListener extends KeyboardListenerAdapter {
public void onKeyUp(Widget sender, char keyCode,
int modifiers) {
String text = textfield.getText();
resultArea.setHTML(text);
if(text.equalsIgnoreCase("test1")) {
alert1(text);
} else if(text.equalsIgnoreCase("test2")) {
highlight1("resultID");
} else if(text.equalsIgnoreCase("test3")) {
highlight2("resultID", text);
}
}
}
private native void highlight1(String id) /*-{
new $wnd.Effect.Highlight(id);
new $wnd.Effect.Shake(id);
}-*/;
WEB MODE
Calling Java from JavaScript
- Follows Java Native Interface (JNI) format
– Summary here. Details: see JNI reference or GWT docs. - Format for static methods
– @className::methodName(paramSignature)(args)
• className: fully qualified name
• methodName: normal name
• paramSignature: JNI parameter signature (see next page)
• args: argument names - Format for instance methods
– this.@className::methodName(paramSignature)(args)
– obj.@className::methodName(paramSignature)(args)
• obj must be passed in from Java - Format for field access
– obj.@className::fieldName
- Separated by semicolons, not commas
- Special format for types (copied from JNI)
- Example
– Real method (class is test.client.SomeClass)
• public double foo(double d, String s) { ...}
– JSNI call
• var value =
this.@test.client.SomeClass::foo(D; Ljava/lang/String)(2.5, "hi");
private class WowListener extends KeyboardListenerAdapter {
public void onKeyUp(Widget sender, char keyCode,
int modifiers) {
String text = textfield.getText();
resultArea.setHTML(text);
if(text.equalsIgnoreCase("test1")) {
alert1(text);
} else if(text.equalsIgnoreCase("test2")) {
highlight1("resultID");
} else if(text.equalsIgnoreCase("test3")) {
highlight2("resultID", text);
}
}
}
private double randomTime(double n){Result
return(Math.random() * n);
}
private void alert2(String text) {
Window.alert("Value: " + text);
}
private native void highlight2(String id, String text) /*-{
var time =
this.@coreservlets.client.GwtJsniApp::randomTime(D)(10);
this.@coreservlets.client.GwtJsniApp::alert2
(Ljava/lang/String;)(text);
new $wnd.Effect.Highlight(id, { duration: time});
new $wnd.Effect.Shake(id, { duration: time});
}-*/;
Summary
- Approach
– Declare native
– Enclose body in /*-{ ... }-*/;
– Use $wnd to access window object
– Use JNI format to call Java from JavaScript - Purpose
– Mostly for wrapping existing JavaScript libraries
– Most standard tasks can be done directly in GWT
Exampleprivate native void alert1(String message) /*-{
$wnd.alert(message);
}-*/;
0 comments:
Post a Comment