如何在Java小程序中注册JavaScript回调?
我正在开发一个不可见的Java小程序,它将完全由JavaScript控制 我可以轻松地调用小程序的Java方法,也可以使用如何在Java小程序中注册JavaScript回调?,java,javascript,applet,callback,methods,Java,Javascript,Applet,Callback,Methods,我正在开发一个不可见的Java小程序,它将完全由JavaScript控制 我可以轻松地调用小程序的Java方法,也可以使用netscape.JavaScript.JSObject.getWindow(this.call())从小程序内部调用JavaScript方法 但是为了在applet中注册JavaScript回调,我想我需要某种JavaScript函数对象 我想: public void registerCallback( SomeJavascriptFunction func ) { ..
netscape.JavaScript.JSObject.getWindow(this.call()
)从小程序内部调用JavaScript方法
但是为了在applet中注册JavaScript回调,我想我需要某种JavaScript函数对象
我想:
public void registerCallback( SomeJavascriptFunction func ) { ... }
我可以从Javascript调用它:
myapplet.registerCallback(function(){ alert("called back"); });
所以我可以在以后的代码中调用此函数:
func.call( ... );
这样的东西存在吗?我该怎么做
现在,我正考虑创建一些Javascript来处理这个回调机制,而不是从applet中创建。我对Java Javascript通信是全新的,因为我计划在本周探索它。这是一个很好的机会…:-)
经过一些测试后,您似乎无法将JS函数传递给Java小程序。除非我做得不对
我试过:
function CallJava()
{
document.Applet.Call("Does it work?");
document.Applet.Call(function () { alert("It works!"); });
document.Applet.Call(DoSomething); // A simple parameterless JS function
document.Applet.Call(window.location);
}
function DumbTest(message, value)
{
alert("This is a dumb test with a message:\n" + message + "\n" + value);
}
其中调用定义为:
public void Call(String message)
{
JSObject win = (JSObject) JSObject.getWindow(this);
String[] arguments = { "Call with String", message };
win.call("DumbTest", arguments);
}
public void Call(JSObject jso)
{
JSObject win = (JSObject) JSObject.getWindow(this);
String[] arguments = { "Call with JSObject", jso.toString() };
win.call("DumbTest", arguments);
}
当我传递一个JS函数(FF3中的所有测试)时,我在Java端得到一个空值
注意,下面的Java例程允许显示DumberTest函数的JS代码
public int Do()
{
JSObject win = (JSObject) JSObject.getWindow(this);
JSObject doc = (JSObject) win.getMember("document");
JSObject fun = (JSObject) win.getMember("DumberTest");
JSObject loc = (JSObject) doc.getMember("location");
String href = (String) loc.getMember("href");
String[] arguments = { href, fun.toString() };
win.call("DumbTest", arguments);
return fun.toString().length();
}
要点:我制作了一个JS函数:
function RegisterCallback(cbFunction)
{
var callback = cbFunction.toString(); // We get JS code
var callbackName = /^function (\w+)\(/.exec(callback);
document.Applet.RegisterCallback(callbackName[1]);
}
我从toString结果中提取JS函数的名称,并将其传递给Java小程序。我认为我们不能处理匿名函数,因为Java按名称调用JS函数
Java方面:
String callbackFunction;
public void RegisterCallback(String functionName)
{
callbackFunction = functionName;
}
void UseCallbackFunction()
{
if (callbackFunction == null) return;
JSObject win = (JSObject) JSObject.getWindow(this);
win.call(callbackFunction, null);
}
eval()将调用预定义的javascript
String callbackFunction;
public void RegisterCallback(String functionName)
{
callbackFunction = functionName;
}
void UseCallbackFunction()
{
if (callbackFunction == null) return;
JSObject win = (JSObject) JSObject.getWindow(this);
win.eval(callbackFunction);
}
我意识到这是一个非常古老的问题,但在我搜索其他东西时,它排名第二,我认为下面的内容可能会帮助其他人找到这个问题
我最近做了类似的事情,Java小程序在完成任务时需要回调JavaScript,在成功或出错时调用不同的函数。正如最近的趋势一样,我的需求是调用被定义为传递给其他函数的参数的匿名函数。这是客户端的javascript:
applet.DoProcessing({
success: function(param) {
alert('Success: ' + param);
},
error: function(param) {
alert('Failed: ' + param);
}
});
正如其他答案中提到的,Java只能按名称调用JavaScript方法。这意味着您需要一个全局回调方法,然后可以根据需要调用其他方法:
function ProcessingCallback(isSuccessful, cbParam, jsObject) {
if (isSuccessful && jsObject.success)
jsObject.success(cbParam);
else if (!isSuccessful && jsObject.error)
jsObject.error(cbParam);
}
此函数直接从Java小程序中调用:
public void DoProcessing(final Object callbacks) {
//do processing....
JSObject w = JSObject.getWindow(this);
//Call our named callback, note how we pass the callbacks parameter straight
//back out again - it will be unchanged in javascript.
w.call("ProcessingCallback", new Object[]{successful, output, callbacks});
}
如果希望将参数对象的引用用作某种形式的注册回调,而不是一次性回调(如果需要等),则可以无限期地保留传入的参数对象的引用
在我们的例子中,处理过程可能是时间密集型的,因此我们实际上启动了另一个线程-回调在这里仍然有效:
public void DoProcessing(final Object callbacks) {
//hold a reference for use in the thread
final Applet app = this;
//Create a new Thread object to run our request asynchronously
//so we can return back to single threaded javascript immediately
Thread async = new Thread() {
//Thread objects need a run method
public void run() {
//do processing....
JSObject w = JSObject.getWindow(app);
//Call our named callback, note how we pass the callbacks parameter
//straight back out again - it will be unchanged in javascript.
w.call("ProcessingCallback", new Object[]{successful, output, callbacks});
}
}
//start the thread
async.start();
}
eval更为通用,因此对于这个精确的任务来说,它的效率比call低,而且将参数传递给JS函数更为复杂。似乎您只能按名称将函数传递给Java,因此,您需要做的是创建一个façade对象,该对象将封装applet,并获取函数引用,并为它们提供临时名称。