10

JavaScript から完全に制御される、目に見えない Java アプレットを開発しています。

アプレットの Java メソッドを簡単に呼び出すことができますnetscape.javascript.JSObject.getWindow(this).call()

しかし、JavaScript コールバックをアプレットに登録するには、ある種の JavaScript 関数オブジェクトが必要になると思います。

私はやりたい:

public void registerCallback( SomeJavascriptFunction func ) { ... }

Javascriptから呼び出すことができるもの:

myapplet.registerCallback(function(){ alert("called back"); });

したがって、後のコードでこの関数を呼び出すことができます。

func.call( ... );

このようなものは存在しますか?これどうやってするの?

現在、アプレットからではなく、このコールバック メカニズムを処理する Javascript を作成することを考えています。

4

3 に答える 3

4

これは本当に古い質問だと思いますが、他の検索の 1 つで 2 位にランクされました。以下は、これを見つけた他の人に役立つと思います。

私は最近、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();
}
于 2012-08-13T11:24:44.083 に答える
2

今週、Java <-> JavaScript通信を調査する予定だったので、私は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);
}

ここで、Callは次のように定義されます。

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側でnullが発生します。

次の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);
}
于 2008-11-17T18:40:43.350 に答える
1

win.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);
}
于 2008-11-17T21:13:02.217 に答える