In the Display Object class, I have everything wrapped excepted the events. I can't not figure out the pattern and really need an example.
In JavaScript, you create a callback for the object like this:
displayObject.onPress = function(event) {
$wnd.alert("object pressed");
}
I have wrapped the Mouse Event parameter:
public class MouseEventImpl extends JavaScriptObject {
protected MouseEventImpl() {}
public static native MouseEventImpl create(String type, int stageX, int stageY, DisplayObjectImpl target, JavaScriptObject nativeEvent) /*-{
return new $wnd.MouseEvent(type, stageX, stageY, target, nativeEvent);
}-*/;
...other methods excluded...
}
public class MouseEvent {
private MouseEventImpl impl;
public MouseEvent(String type, int stageX, int stageY, DisplayObject target, JavaScriptObject nativeEvent) {
this.impl = MouseEventImpl.create(type, stageX, stageY, target.getOverlay(), nativeEvent);
}
...other methods excluded...
}
The display object uses the same overlay pattern. How am I able to write a callback in java and pass it through to the JSO? Please provide an example if you can. :)
Pre-post edit: I wrote up this answer without actually trying to see why you were trying to do this thing, under the assumption that you were using some non-browser event, which is already wrapped up pretty nicely, and if you want more data from the NativeEvent
instance, you can write JSNI methods in your own classes to get access to it, or further subclass NativeEvent
to add more methods and .cast()
to your class. Add the handler to a widget using the Widget.addDomHandler
method and the appropriate MouseEvent
subclass to get the type instance.
In JavaScript, callbacks are just functions that will be invoked when something happens. Unless specifically specified where they are passed in, they will generally be called on the global context, not on a specific object instance.
var callback = function() { alert("callback called!"); };
// later, in something that consumes that callback:
callback();
To invoke a function on an instance (i.e. make it a method invocation), one can wrap that invocation in a function that doesn't need an instance:
var obj = {};
obj.name = "Me";
obj.whenSomethingHappens = function() {
alert("my name is " + this.name);
};
// wont work, so commented out:
//var callback = obj.whenSomethingHappens;
// instead we wrap in a function
// this is making a closure (by closing over obj)
var callback = function() {
obj.whenSomethingHappens();
};
// later, in something that consumes that callback:
callback();
In Java, one cannot refer specifically to a method (without reflection), but only to object instances. The easiest way to build a simple callback is to implement an interface, and the code that takes the callback takes an instance of the interface, and invokes the defined method.
GWT declares a Command
interface for zero-arg functions, and a generic Callback<T,F>
interface for cases that may pass or fail, with one generic arg for each option. Most event handlers in GWT just define one method, with specific data passed into that method.
We need to use all of this knowledge to pass Java instances, with a function to call, into JavaScript, and make sure they are invoked on the right instance. This example is a function that takes a Callback
instance and using JSNI wraps a call to it JS.
// a callback that has a string for either success or failure
public native void addCallback(Callback<String, String> callback) /*-{
var callbackFunc = function() {
// obviously the params could come from the function params
[email protected]::onSuccess(Ljava/lang/String;)("success!");
};
doSomethingWith(callbackFunc);//something that takes (and presumably calls) the callback
}-*/;
One last piece - to let GWT's error handling and scheduling work correctly, it is important to wrap the call back to java in $entry - that last line should really be
doSomething($entry(callbackFunc));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With