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));