2008-11-17 32 views
10

Tamamen JavaScript'ten kontrol edilecek görünmez bir Java Uygulaması geliştiriyorum.Java Uygulaması'nda JavaScript geri çağırma nasıl kaydedilir?

Uygulamanın Java yöntemlerini kolayca arayabilirim ve uygulama içinden netscape.javascript.JSObject.getWindow(this).call() kullanarak JavaScript yöntemlerini çağırabilirim.

Ancak, uygulamada bir JavaScript geri çağrısı kaydetmek için, sanırım bir çeşit JavaScript işlev nesnesine ihtiyacım var.

Yapmak istiyorum: Ben Javascript diyebiliriz

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

:

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

Yani sonradan kodunda bu işlevi diyebiliriz:

func.call(...); 

şey yapar Bunun gibi var mı? Bunu nasıl yapabilirim?

Şimdi, uygulamadan bunu yapmak yerine bu geri çağrı mekanizmasını işlemek için bazı Javascript oluşturmayı düşünüyorum.

cevap

2

Bu hafta araştırmayı planladığımdan, Java < -> JavaScript iletişiminde yepyeni biriyim. Burada iyi bir fırsat ... :-)

Bazı testlerden sonra, bir JS işlevini bir Java uygulamasına geçiremezsiniz. Ben yanlış anladı yapıyorum sürece ...

Denedim:

Çağrı olarak tanımlanır (dahil edilmiştir)
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); 
} 

Ben JS işlevini geçmesi

(Tüm testler FF3'te, Java tarafında bir null aldım.

Aşağıdaki Java yordamının, DumberTest işlevinin JS kodunu görüntülemesine izin verdiğini unutmayın! noktaya

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

: Ben toString sonucundan JS işlevin adını ayıklamak ve Java uygulaması için geçmek

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

: Bir JS işlevini yaptı. Adsız işlevleri kaldırabileceğimizi düşünmüyorum çünkü Java, JS işlevlerini isme göre çağırıyor.

Java tarafı:

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

Size sadece ismen Java fonksiyonlarını geçebilir görünüyor, bu nedenle yapmanız gereken yapardım uygulamasını örtecek ve işlev başvuruları alacağını hangi bir cephe nesnesi oluşturmak ve onlar için geçici isimlerle gel. – w00t

1

win.eval() önceden tanımlanmış bir javascript arayacak.

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

değerlendirmesi, bu kesin görev için çağrı yapmaktan daha genel, dolayısıyla daha az etkilidir ve parametreleri JS işlevine iletmek daha karmaşıktır. – PhiLho

4

ben bu gerçekten eski sorudur farkındayım ama başka bir şey için Aramalarımla birinde 2. sırada yer ve aşağıda bu bulur başkası yardımcı olabilir düşünüyorum.

Kısa bir süre önce benzer bir işlem yaptım, böylece bir Java uygulamasının, bir görevin tamamlanmasının ardından başarıya veya hataya farklı işlevler çağrılarak JavaScript'e geri dönmesi gerekiyor. Son zamanlardaki eğilimden de ötürü, ihtiyaçlarm, diğer işlevlere aktarılan parametreler olarak tanımlanan anonim işlevler çağırmaktı.

diğer yanıtlar belirtildiği gibi
applet.DoProcessing({ 
    success: function(param) { 
     alert('Success: ' + param); 
    }, 
    error: function(param) { 
     alert('Failed: ' + param); 
    } 
}); 

Java sadece ismen JavaScript yöntemleri içine çağırabilirsiniz: Bu istemci tarafında javascript.

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

Sen tutunmak olabilir: Bu fonksiyon Java uygulaması içinde doğrudan denir

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

: Bu gerekirse daha sonra da diğer yöntemlerle içine çağırabilir global geri arama yöntemi, gerektiği anlamına gelir Parametre nesnesinin referansı, eğer gerekliyse, atım yerine bir kayıtlı geri çağırma yöntemi olarak kullanmak istediğinizde süresiz olarak iletilir.

Örneğimizde, işlem zaman aldırıcı olabilir; başka bir iş parçacığı - cal lbacks hala da burada işe:

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