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){ 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}); }-*/;Result
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