+ (JAVASCRIPT) - Ich seh den Wald vor lauter Bäumen nicht
Alexander Foken
- java
Moin Moin !
Ich habe:
* ein Java-Applet, daß die Methode "public String getJavaInfo()" implementiert
* eine Test-HTML-Seite, die dieses Applet einbindet
* Javascript in der Seite, das diese Methode aufruft
... und ein Timing-Problem:
Der Browser (diverse aus den letzten paar Jahren, Minimum IE4/NN4/Opera6) lädt die Seite, führt dabei den eingebetteten Javascript-Code aus, irgendwann davor oder danach wird das Java-Applet geladen, und irgendwann ist das Applet auch initialisiert. Die getJavaInfo()-Methode funktioniert, sobald alles geladen ist. Ein Klick auf den Button zeigt den erwarteten String in einer alert-Box an.
Blöderweise ist das Applet erst "lange" nach dem Ausführen des Javascript-Code zur Zusammenarbeit bereit, selbst im onLoad-Handler des Bodys ist das Applet noch nicht fertig. So lange ist document.applets[0].getJavaInfo nicht vorhanden.
Die Klasse netscape.javascript.JSObject kommt aus zwei Gründen nicht in Frage:
1. Das Applet muß in *jeden* Java-fähigen Browser laufen, und nicht jeder bringt diese Klasse mit.
2. Wenn das Applet geladen ist, ist das Dokument schon "fertig" und ich kann es nicht mehr ändern.
Ich möchte aber gerne, daß das Ergebnis der getJavaInfo()-Methode als preformatierter Text mitten im Dokument auftaucht, damit es ein unbedarfter User ("Was ist eine Maus?") mir einen Ausdruck der Seite aus seinem Browser zukommen lassen kann. Das Ergebnis der getJavaInfo()-Methode ist ein viele Zeilen langer String, der ohne Scrollen nie ins Applet-Fenster passen und deswegen beim Ausdruck verstümmelt werden würde.
So, irgendwo ist in meinem Gedankengang der Wurm drin. Nur wo?
Aktueller HTML-Quelltext:
<html>
<head>
<title>Java Testgebiet</title>
</head>
<body>
<applet scriptable mayscript name="infoapplet" code="JavaInfo.class" codebase="current.cgi/2003/07/21/18/57/48/" width="300" height="200">
<param name="invokedVia" value="applet">
<param name="mode" value="">
Doesn't work
</applet>
<br>
<pre>2003/07/21/18/57/48
<script language="Javascript" type="text/javascript"><!--
if (document.applets) {
if (document.applets[0]) {
if (document.applets[0].getJavaInfo) {
document.write(document.applets[0].getJavaInfo());
} else {
document.write('missing getJavaInfo()');
}
} else {
document.write('missing document.applets[0]');
}
} else {
document.write("Missing document.applets");
}
//--></script></pre>
<form>
<input type="button" value="click me" onclick="alert(document.applets[0].getJavaInfo())">
</form>
</body>
</html>
Alexander
Hi,
Blöderweise ist das Applet erst "lange" nach dem Ausführen des Javascript-Code zur Zusammenarbeit bereit, selbst im onLoad-Handler des Bodys ist das Applet noch nicht fertig. So lange ist document.applets[0].getJavaInfo nicht vorhanden.
hast Du mal daran gedacht, die Prüfung in einer Funktion zu kapseln, die sich onNotGetJavaInfo ;-) in einem Timeout selbst aufruft?
if (document.applets) {
if (document.applets[0]) {
if (document.applets[0].getJavaInfo) {
Der Operator zur boole'schen UND-Verknüpfung lautet übrigens "&&" *g*
document.write('missing getJavaInfo()');
document.write('missing document.applets[0]');
document.write("Missing document.applets");
Diese Unterscheidung fehlt dann natürlich.
<form>
ERROR: Required attribute "action" missing.
Cheatah
Moin Moin !
Blöderweise ist das Applet erst "lange" nach dem Ausführen des Javascript-Code zur Zusammenarbeit bereit, selbst im onLoad-Handler des Bodys ist das Applet noch nicht fertig. So lange ist document.applets[0].getJavaInfo nicht vorhanden.
hast Du mal daran gedacht, die Prüfung in einer Funktion zu kapseln, die sich onNotGetJavaInfo ;-) in einem Timeout selbst aufruft?
Aaargh! Eigentlich bin ich auf Java ausgewichen, weil ich *solche* Workarounds loswerden wollte!
Die Idee ist nicht schlecht, nur werde ich dann nicht mehr mitten in mein Dokument reinschreiben können - außer mir DOM und roher Gewalt für alte Browser.
if (document.applets) {
if (document.applets[0]) {
if (document.applets[0].getJavaInfo) {Der Operator zur boole'schen UND-Verknüpfung lautet übrigens "&&" *g*
ach ...
document.write('missing getJavaInfo()');
document.write('missing document.applets[0]');
document.write("Missing document.applets");Diese Unterscheidung fehlt dann natürlich.
Eben. Sowas bastel' ich nicht aus Langeweile, eher aus Verzweiflung.
<form>
ERROR: Required attribute "action" missing.
Ich hab nie behauptet, daß das valides HTML sei. Außerdem fehlen noch DOCTYPE und die Zeichensatzangabe, die Schachtelung von <pre> und <script> ist auch nicht ganz sauber, und selbst dann dürfte der Validator noch nicht zufrieden sein. (Und Du glaubst gar nicht, wie egal mir das für diese Test-Seite ist.)
Alexander
Hi,
hast Du mal daran gedacht, die Prüfung in einer Funktion zu kapseln, die sich onNotGetJavaInfo ;-) in einem Timeout selbst aufruft?
Aaargh! Eigentlich bin ich auf Java ausgewichen, weil ich *solche* Workarounds loswerden wollte!
hm, wieso Workaround? window.setTimeout ist JavaScript/1.0, die von Dir verwendete Art der Prüfung ebenfalls.
Die Idee ist nicht schlecht, nur werde ich dann nicht mehr mitten in mein Dokument reinschreiben können - außer mir DOM und roher Gewalt für alte Browser.
Da es sich beim Applet um eine externe Ressource handelt, die asynchron geladen wird, _darfst_ Du nicht davon ausgehen, dass sie während des Renderns der Seite bereits verfügbar ist. Die Java-Methode ist garantiert erst später zur Verfügung, als Dir lieb ist.
Ich hab nie behauptet, daß das valides HTML sei. [...] (Und Du glaubst gar nicht, wie egal mir das für diese Test-Seite ist.)
Du verstehst sicher, dass ich der Form halber wenigestens diesen einen Fehler nicht unkommentiert lassen konnte :-)
Cheatah
Moin Moin !
hast Du mal daran gedacht, die Prüfung in einer Funktion zu kapseln, die sich onNotGetJavaInfo ;-) in einem Timeout selbst aufruft?
Aaargh! Eigentlich bin ich auf Java ausgewichen, weil ich *solche* Workarounds loswerden wollte!
hm, wieso Workaround?
Workaround, weil es auf Polling statt auf Benachrichtigung hinausläuft.
window.setTimeout ist JavaScript/1.0, die von Dir verwendete Art der Prüfung ebenfalls.
Ja. Aber frei nach Murphy ist der Timeout immer so kurz, daß das erwartete Ereignis unmittelbar nach dem Timeout auftritt.
Sicher, es gbit eine vernünftige Obergrenze im Bereich einiger Sekunden bis zu etwa einer Minute, bis ein normaler User die Geduld verliert.
Die Idee ist nicht schlecht, nur werde ich dann nicht mehr mitten in mein Dokument reinschreiben können - außer mir DOM und roher Gewalt für alte Browser.
Da es sich beim Applet um eine externe Ressource handelt, die asynchron geladen wird, _darfst_ Du nicht davon ausgehen, dass sie während des Renderns der Seite bereits verfügbar ist. Die Java-Methode ist garantiert erst später zur Verfügung, als Dir lieb ist.
Ja, leider. Genau das ist ja mein Problem. Selbst ein (nicht vorhandener?) onload-Event für das <applet>-Tag (und <embed> und <object>) würde nicht viel helfen, weil das Applet ja auch noch initialisiert werden will.
Sauber wäre eigentlich nur, innerhalb der init()-Methode des Applets einen Javascript-Event (bzw. einen Funktionsaufruf) auszulösen. Damit wäre ich das Polling los.
Jetzt muß ich dem Applet nur noch beibringen, netscape.javascript.JSObject nur dann zu verwenden, wenn der Browser die entsprechende Library mitbringt.
Gut, daß ich überhaupt keine Ahnung von Java habe. ;-/
http://www.rgagnon.com/ce/java-js.html sieht ganz gut aus, nicht nur verschiedene Ansätze für Javascript-Aufrufe aus Java, sondern auch ein etwas intelligenteres Polling mit isActive() (http://www.rgagnon.com/ce/java-js.html#link10). Nur leider kein Sterbenswörtchen über Weder-IE-noch-NN-Browser.
Ich hab nie behauptet, daß das valides HTML sei. [...] (Und Du glaubst gar nicht, wie egal mir das für diese Test-Seite ist.)
Du verstehst sicher, dass ich der Form halber wenigestens diesen einen Fehler nicht unkommentiert lassen konnte :-)
Klaro. Ich hack da ja genauso drauf rum.
Alexander
Hallo Alexander,
Jetzt muß ich dem Applet nur noch beibringen, netscape.javascript.JSObject nur dann zu verwenden, wenn der Browser die entsprechende Library mitbringt.
try {
//code in dem du netscape.javascript.JSObject verwendest
}
catch(ClassNotFoundException e) {
//...
}
Das sollte funktionieren.
Grüße
Daniel
Moin Moin !
Hallo Alexander,
Jetzt muß ich dem Applet nur noch beibringen, netscape.javascript.JSObject nur dann zu verwenden, wenn der Browser die entsprechende Library mitbringt.
try {
//code in dem du netscape.javascript.JSObject verwendest
}
catch(ClassNotFoundException e) {
//...
}
Das sollte funktionieren.
Das werde ich morgen testen. Für heute habe ich lange genug vor der Kiste gehockt.
Was ist mit import netscape.javascript.JSObject;?
Macht das irgendwelche Zicken, wenn java40.jar fehlt?
Danke!
Alexander
Hallo Alexander,
Was ist mit import netscape.javascript.JSObject;?
Imports interessieren nur den Compiler, nicht die VM.
Zu der Sache mit dem IE. Wenn das Problem ist, dass nur manchmal diese Klasse fehlt, kannst Du die auch aus der jar-Datei extrahieren und mit dem Applet mitliefern.
Grüße
Daniel
Hi,
window.setTimeout ist JavaScript/1.0, die von Dir verwendete Art der Prüfung ebenfalls.
Ja. Aber frei nach Murphy ist der Timeout immer so kurz, daß das erwartete Ereignis unmittelbar nach dem Timeout auftritt.
dann tritt es hinreichend lange vor dem nächsten Timeout auf.
Sicher, es gbit eine vernünftige Obergrenze im Bereich einiger Sekunden bis zu etwa einer Minute, bis ein normaler User die Geduld verliert.
Wenn Du immer z.B. 0.5 Sekunden wartest, solange bis die Methode existiert, wartest Du höchstens 0.4999... Sekunden zu lange.
Sauber wäre eigentlich nur, innerhalb der init()-Methode des Applets einen Javascript-Event (bzw. einen Funktionsaufruf) auszulösen. Damit wäre ich das Polling los.
Ja. Da kann ich aber leider auch nichts zu sagen.
Gut, daß ich überhaupt keine Ahnung von Java habe. ;-/
*g*
Cheatah
Hi,
* ein Java-Applet, daß die Methode "public String getJavaInfo()" implementiert
* eine Test-HTML-Seite, die dieses Applet einbindet
* Javascript in der Seite, das diese Methode aufruft
Mach es andersrum. Ruf vom Applet aus die Javascript-Funktion auf.
cu,
Andreas
Moin Moin !
Mach es andersrum. Ruf vom Applet aus die Javascript-Funktion auf.
Würde ich ja gerne. Nur gibt es navigator.javascript.JSObject nicht überall. Siehe [pref:t=53022&m=293148].
Alexander
Hi,
Würde ich ja gerne. Nur gibt es navigator.javascript.JSObject nicht überall. Siehe [pref:t=53022&m=293148].
Dann stellst Du halt die 2 oder 3 Klassen auch mit auf den Webspace...
cu,
Andreas
Hallo Alexander,
- Das Applet muß in *jedem* Java-fähigen Browser laufen, und nicht jeder bringt diese Klasse mit.
Gibt es tatsächlich javafähige Browser, die den Zugriff von JavaScript auf Java erlauben, aber den Zugriff von Java auf JavaScript nicht?
Die Existens der Klasse kannst Du in Java ja vorher überprüfen bzw die RuntimeException abfangen, wenn sie nicht da ist.
- Wenn das Applet geladen ist, ist das Dokument schon "fertig" und ich kann es nicht mehr ändern.
Über DOM schon. Wie von Cheatah schon erwähnt hat, kannst Du Dich sowieso nicht darauf verlassen, dass das Applet beim Laden der Seite schon gestartet ist. Es ist sogar äußerst unwahrscheinlich.
Grüße
Daniel
Moin Moin !
Hallo Alexander,
- Das Applet muß in *jedem* Java-fähigen Browser laufen, und nicht jeder bringt diese Klasse mit.
Gibt es tatsächlich javafähige Browser, die den Zugriff von JavaScript auf Java erlauben, aber den Zugriff von Java auf JavaScript nicht?
Der IE hat die java40.jar (oder so) normalerweise nicht dabei, deswegen mag der mein Applet dann auch nicht wirklich ausführen.
Die Existens der Klasse kannst Du in Java ja vorher überprüfen bzw die RuntimeException abfangen, wenn sie nicht da ist.
Die Exception abzufangen ist allerdings noch eine Idee. Nur: wie? Das Applet lädt die Klasse doch automatisch, da ist also nichts mit try-catch. Kann ich die Klasse irgendwie zur Laufzeit von hand in try-catch laden?
http://www.rgagnon.com/ce/java-js.html#link3 baut etwas mit Class c = class.forName("netscape.javascript.JSObject"); , sagt aber auch, daß das die Reflection-API ist. Die hat mein IE (und auch einige andere) aber wohl nicht, oder?
java.version="1.1.4"
java.vendor="Microsoft Corp."
- Wenn das Applet geladen ist, ist das Dokument schon "fertig" und ich kann es nicht mehr ändern.
Über DOM schon.
Ich habe das zweifelhafte Vergnügen, daß auch dem NN4 beizubiegen. Unsere Kunden setzen diesen Dinosaurier leider immer noch ein.
Wie von Cheatah schon erwähnt hat, kannst Du Dich sowieso nicht darauf verlassen, dass das Applet beim Laden der Seite schon gestartet ist. Es ist sogar äußerst unwahrscheinlich.
Das ist mir klar, und genau das ist ja mein Problem.
Alexander
Hallo Alexander,
Der IE hat die java40.jar (oder so) normalerweise nicht dabei, deswegen mag der mein Applet dann auch nicht wirklich ausführen.
Der IE unterstüzt diese Schnittstelle eigentlich. Jedenfalls hat er es getan, als ich das mal ausprobiert habe. Würde mich etwas wundern, wenn sie das mittlerweile gestrichen hätten.
Grüße
Daniel
Moin Moin !
Der IE hat die java40.jar (oder so) normalerweise nicht dabei, deswegen mag der mein Applet dann auch nicht wirklich ausführen.
Der IE unterstüzt diese Schnittstelle eigentlich. Jedenfalls hat er es getan, als ich das mal ausprobiert habe. Würde mich etwas wundern, wenn sie das mittlerweile gestrichen hätten.
Mag sein, daß mir die Wärme etwas zusetzt. Aber soweit ich mich an die Suchergebnisse der letzten Tage erinnere, hat der IE die java40.jar wohl nicht immer dabei (z.B. http://mapserver.gis.umn.edu/data2/wilma/mapserver-users/0105/msg00232.html und http://forum.java.sun.com/thread.jsp?forum=30&thread=34394&tstart=0&trange=15), obwohl netscpae.javascript.JSObject prinzipiell unterstützt wird.
Alexander
Hallo Alexander,
Ich habe das zweifelhafte Vergnügen, daß auch dem NN4 beizubiegen.
Ganze Seite nochmals generieren mit document.open(); document.write(...); document.close();? (und damit meine ich _keine_ Layer!) Funktioniert auch garantiert mit Browsern, die keine Ahnung von DOM haben.
Viele Grüße,
Christian
Moin Moin !
Ganze Seite nochmals generieren mit document.open(); document.write(...); document.close();? (und damit meine ich _keine_ Layer!) Funktioniert auch garantiert mit Browsern, die keine Ahnung von DOM haben.
Ja schon ...
Aber irgendwann wird das Ganze echt Overkill. Es soll ja nur eine Diagnoseseite werden, um Probleme mit dem Browser des Kunden auszuschließen. Ich mach jetzt ein Popup-Fenster auf ("Jehova, Jehova"), und schreib per Javascript-Callback meine Infos ins Popup-Fenster. Da gibt es dann auch gleich noch einen DAU-freundlichen "Print"-Button. Es ist nicht ganz das, was ich mir anfangs vorgestellt habe, aber es sollte ausreichen.
Alexander