2009-02-20 14 views
12

Mam aplet java uruchomiony w przeglądarce, która wywołuje niektóre funkcje javascript i spodziewa się wyniku z tych funkcji. Jest to praca z następujących konfiguracji:Czy aplety Java nie mogą komunikować się z javascript w Firefoksie w systemie Mac OS?

  • Internet Explorer
  • FireFox/Windows
  • Safari/Mac

ale to nie działa w Firefoksie na Mac OS

Źródłem problem wydaje się być wywołania win.eval, które zawsze zwracają wartość null. testowałem to z Firefox 3.0.6 na Mac OS X 10.4.11

Trochę kodu:

JSObject win = (JSObject) JSObject.getWindow(this); 
Object exp = win.eval("testfunc()"); 
System.out.println("exp = " + exp.toString()); 

To wyzwala java.lang.NullPointerException (exp.toString()) oświadczenie) . Funkcja javascript testfunc po prostu zwraca wartość true.

Próbowałem z win.call i otrzymałem taki sam wynik.

Mój znacznik apletu zawiera atrybuty mayscript i scriptable.


Znalazłem odpowiedź dzięki Tristan. Testując jego rozwiązanie stworzyłem naprawdę prosty test, który mógł zadziałać i wypracował moją drogę do znalezienia sprawcy. Byłem pewien, że zrobiłem moje testy z pustym testfunc(), który właśnie zwrócił prawdę, ale prawdopodobnie nie, ponieważ w tym przypadku działa. Prawdziwy problem polegał na tym, że funkcja nazywała się publiczną metodą apletu. Liveconnect nie wydaje się być w stanie obsłużyć tego przypadku w Firefox Mac.

Podam przykład: Klasa

Java:

public class MyApplet extends Applet { 
    public int getMyValue() { 
     return 5; 
    } 

    public void somefunction() { 
     JSObject win = (JSObject) JSObject.getWindow(this); 
     Object exp = win.eval("jsfunc()"); 
     System.out.println("exp = " + exp.toString()); 
    } 
} 

a kod javascript:

function jsfunc() { 
    var myApplet = document.getElementById("applet_id"); 
    return myApplet.getMyValue() + 5; 
} 

exp będzie null w someFunction PONIEWAŻ jsfunc wywołuje getMyValue() metoda apletu. Jeśli usuniesz wszystkie połączenia z właściwościami apletu, jesteś spokojny.
Aby rozwiązać mój problem, postanowiłem podać wszystkie wartości apletu, który uważałem za parametry funkcji javascript i jestem teraz dobry.
To może nie być tak zawsze, jeśli javascript zmienia stan apletu ... Miałem szczęście :)

Odpowiedz

3

Czy zadziałałby poprzez dostęp do jednego z globalnych obiektów na ekranie? Ergo,

W JavaScript:

window.testfunc = function() { //... } 

W apletu:

win.eval("window.testfunc()") // or maybe just win.eval("testfunc()") 

To byłby mój eksperyment. Ale nazywam "window.close()" na FF na Mac OS X, i to nadal działa.

+0

Wywołanie funkcji nie jest problemem, uzyskanie wyniku z powrotem jest. Z instrukcjami debugowania jasno widzę, że funkcja jest wykonywana, ale w jakiś sposób wartość zwracana zostaje utracona, a ja dostaję tylko "null". –

4

Nie użyłem api apletu przez pewien czas, ale jeśli dobrze pamiętam, aby umożliwić Apletowi na kod JS cann, powinieneś włączyć atrybut mayscript w swoim znaczniku apletu lub param mayscript w notacji znacznika obiektu.

Do komunikacji w inny sposób JS do apletu należy również używać Scriptable atrybut lub parametr, na przykład:

<applet code="..." mayscript="true" /> 

Pozwala aplet do korzystania z funkcji skryptowych.

<applet code="..." scriptable="true" /> 
+0

Istotnie konieczne są atrybuty mayscript i scriptable. Ale już uwzględniłem je w moim znaczniku apletu, w przeciwnym razie nie działałby on wcale z innymi przeglądarkami. –

0

Jeśli usuniesz wszystkie połączenia do właściwości apletu jesteś cool.

Może się to zdarzyć w innych sytuacjach. Znalazłem tę stronę po Googlingu podobnego problemu, więc pomyślałem, że dodaję datapunkt. Jedyna różnica polega na tym, że używam win.call() zamiast win.eval().

Miałem wywołanie alert() w skrypcie JavaScript, aby upewnić się, że połączenie było przez to przechodzące, i widziałem, co wydaje się być dokładnie tym samym zablokowaniem w Firefox 3.0.9, OS X 10.5.6, Java 1.5.0_16. 100% powtarzalne w Firefoksie, bez problemu w Safari (nie mam zainstalowanego Windowsa na tym pudełku).

Kiedy pozbyłem się alertu() i po prostu zwróciłem wartość, problem zniknął.

Sooooo ... może dzwoni do czasu JavaScript po pewnym czasie i po prostu rzuca null?