2008-11-17 12 views
10

मैं एक अदृश्य जावा ऐप्पल विकसित कर रहा हूं, जिसे पूरी तरह जावास्क्रिप्ट से नियंत्रित किया जाएगा।जावा एप्लेट में जावास्क्रिप्ट कॉलबैक कैसे पंजीकृत करें?

मैं एप्लेट की जावा विधियों को आसानी से कॉल कर सकता हूं, और मैं netscape.javascript.JSObject.getWindow(this).call() का उपयोग करके एप्लेट के भीतर जावास्क्रिप्ट विधियों को कॉल कर सकता हूं।

लेकिन एप्लेट में एक जावास्क्रिप्ट कॉलबैक पंजीकृत करने के लिए, मुझे लगता है कि मुझे किसी प्रकार की जावास्क्रिप्ट फ़ंक्शन ऑब्जेक्ट की आवश्यकता होगी।

मुझे क्या करना चाहते हैं:

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

कौन सा मैं जावास्क्रिप्ट से कह सकते हैं:

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

तो मैं इस समारोह बाद में कोड में कह सकते हैं:

func.call(...); 

कुछ करता है जैसे यह अस्तित्व में है? मैं यह कैसे कर सकता हूँ?

रिगथ अब मैं एप्लेट से ऐसा करने के बजाए इस कॉलबैक तंत्र को संभालने के लिए कुछ जावास्क्रिप्ट बनाने की सोच रहा हूं।

उत्तर

2

मैं जावा < -> जावास्क्रिप्ट संचार के लिए नया ब्रांड हूं, क्योंकि मैंने इस सप्ताह इसे एक्सप्लोर करने की योजना बनाई है। यहां एक अच्छा मौका ... :-)

कुछ परीक्षणों के बाद, ऐसा लगता है कि आप जावा एप्लेट में जेएस फ़ंक्शन पास नहीं कर सकते हैं। जब तक मैं इसे गलत तरीके से कर रहा हूँ ...

मैंने कोशिश की:

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

जब मैं एक जे एस समारोह पारित (सभी परीक्षणों एफएफ 3 में), मुझे जावा पक्ष पर एक शून्य मिलती है।

ध्यान दें कि निम्न जावा रूटीन DumberTest फ़ंक्शन के जेएस कोड को प्रदर्शित करने की अनुमति देता है!

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

बिंदु करने के लिए: मैं एक जे एस समारोह बनाया:

function RegisterCallback(cbFunction) 
{ 
    var callback = cbFunction.toString(); // We get JS code 
    var callbackName = /^function (\w+)\(/.exec(callback); 
    document.Applet.RegisterCallback(callbackName[1]); 
} 

मैं toString परिणाम से जे एस फ़ंक्शन का नाम निकालने और यह जावा एप्लेट के लिए गुजरती हैं। मुझे नहीं लगता कि हम अनाम कार्यों को संभाल सकते हैं क्योंकि जावा कॉल जेएस नाम से काम करता है।

जावा पक्ष:

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); 
} 
+0

ऐसा लगता है कि आप केवल नाम से जावा के लिए काम करता है पारित कर सकते हैं, इसलिए आपको बस इतना करना चाहते हैं क्या एक बहाना वस्तु जो एप्लेट लपेटो जाएगा और जो समारोह संदर्भ ले जाएगा बनाने और उनके लिए अस्थायी नाम के साथ आओ। – w00t

1

win.eval() एक पूर्वनिर्धारित जावास्क्रिप्ट कॉल करेंगे।

String callbackFunction; 
public void RegisterCallback(String functionName) 
{ 
    callbackFunction = functionName; 
} 
void UseCallbackFunction() 
{ 
    if (callbackFunction == null) return; 
    JSObject win = (JSObject) JSObject.getWindow(this); 
    win.eval(callbackFunction); 
} 
+0

eval अधिक सामान्य है, इसलिए इस सटीक कार्य के लिए कॉल से कम कुशल है, और जेएस फ़ंक्शन को पैरामीटर पास करना अधिक जटिल है। – PhiLho

4

मुझे पता है कि यह एक वास्तव में वर्ष सवाल है, लेकिन यह कुछ और के लिए अपनी खोजों में से एक में 2 स्थान पर रहीं, और मैं नीचे है कि इस पाता है किसी और में मदद मिल सकती है।

मैंने हाल ही में ऐसा कुछ किया है जिसके द्वारा जावा एप्लेट को किसी कार्य को पूरा करने पर जावास्क्रिप्ट में वापस कॉल करने की आवश्यकता है, सफलता या त्रुटि पर विभिन्न कार्यों को कॉल करना। जैसा कि हाल के दिनों में प्रवृत्ति रही है, मेरी जरूरतों को परिभाषित अज्ञात कार्यों में कॉल करना था क्योंकि पैरामीटर अन्य कार्यों में पारित किए जा रहे थे। यह क्लाइंट साइड पर जावास्क्रिप्ट है:

applet.DoProcessing({ 
    success: function(param) { 
     alert('Success: ' + param); 
    }, 
    error: function(param) { 
     alert('Failed: ' + param); 
    } 
}); 

जैसा कि अन्य उत्तरों में बताया गया है, जावा केवल नाम से जावास्क्रिप्ट विधियों में कॉल कर सकता है।

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

आप पर पकड़ सकता है:

function ProcessingCallback(isSuccessful, cbParam, jsObject) { 
    if (isSuccessful && jsObject.success) 
     jsObject.success(cbParam); 
    else if (!isSuccessful && jsObject.error) 
     jsObject.error(cbParam); 
} 

इस समारोह जावा एप्लेट के अंदर से सीधे कहा जाता है: यह आपको एक वैश्विक कॉलबैक विधि है, जो तब के रूप में अन्य तरीकों में कॉल कर सकते हैं की जरूरत होने की जरूरत का मतलब है पैरामीटर ऑब्जेक्ट का संदर्भ अनिश्चित काल तक पारित किया जा रहा है यदि आप इसे आवश्यक कॉलबैक के रूप में उपयोग करने के बजाय किसी भी प्रकार के पंजीकृत कॉलबैक के रूप में उपयोग करना चाहते हैं।

हमारे मामले में प्रसंस्करण समय intenstive हो सकता है, तो हम वास्तव में स्पिन एक और थ्रेड - कैल lbacks अभी भी भी यहाँ काम:

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(); 
} 
संबंधित मुद्दे