{"id":2676,"date":"2014-02-07T16:05:36","date_gmt":"2014-02-07T14:05:36","guid":{"rendered":"http:\/\/www.tutego.de\/blog\/javainsel\/?p=2676"},"modified":"2014-02-07T16:05:36","modified_gmt":"2014-02-07T14:05:36","slug":"java-awt-applet","status":"publish","type":"post","link":"https:\/\/www.tutego.de\/blog\/javainsel\/2014\/02\/java-awt-applet\/","title":{"rendered":"Inselraus: Applets"},"content":{"rendered":"<blockquote><p>\u00bbMode ist, was man selbst tr\u00e4gt. Altmodisch ist, was die anderen tragen.\u00ab\u2013 Oscar Wilde (1854\u20131900)<\/p><\/blockquote>\n<p>Applets sind kleine Java-Programme, die in einem Webbrowser ablaufen. Sie geh\u00f6ren zu den Java-Programmen der ersten Stunde. Referenziert eine Web-Seite ein Applet, so startet der Browser eine virtuelle Maschine und f\u00fchrt das Applet aus.<\/p>\n<h2>Applets in der Wiege von Java<\/h2>\n<p>Haben sich in den Anfangsjahren die Browser-Hersteller selbst darum gek\u00fcmmert, die Applets in ihren Browsern um Laufen zu bringen, hat sich das heute gewandelt. Oracle liefert die Java Plug-In Technology (kurz Java Plug-In) aus, was die Browser bei der Ausf\u00fchrung von Applets auf den gleichen Stand bringt. Das hat den Vorteil, dass\u00a0 die Java-Technologie auch zum Internet Explorer kommt, da ja Microsoft seine JVM nicht mehr aktualisiert. (Microsoft lieferte f\u00fcr Windows XP immerhin noch eine eigene JVM aus, obwohl sie auf dem Stand von Java 1.1 stehen blieb, aber XP ist ja auch nicht mehr Stand der Dinge.) Fr\u00fcher lief die virtuelle Maschine im Browser selbst, in neuen Java-Versionen l\u00e4uft die Java-Anwendung in einem eigenen Prozess.<\/p>\n<h3>Applets heute<\/h3>\n<p>Obwohl Applets Java an die Spitze der Programmiersprachen brachten, sind sie heute nur noch selten zu sehen. Es gibt zwar Ausnahmen, wie den Routenplaner http:\/\/www.de.map24.com\/ oder diverse Aktien-Chart-Analysen, doch im Allgemeinen sind Applets von \u00f6ffentlichen Webseiten weitestgehend verschwunden. Der Grund, warum Java-Applets weniger attraktiv f\u00fcr den Konsumenten sind, liegt nicht darin, dass die clientseitige Darstellung und Logik unwichtig geworden ist, sondern vielmehr an anderen Gr\u00fcnden:<\/p>\n<ul>\n<li>Mit HTML, CSS sowie JavaScript lassen sich heutzutage viele Aufgaben l\u00f6sen, die 1995 unl\u00f6sbar waren. Dagegen wirken compilierte Java-Programme nicht gerade wie Raketentechnik. W\u00e4hrend bei Java-Applets erst eine JVM gestartet werden muss, was nat\u00fcrlich eine gewisse Zeit kostet, sind JavaScript und HTML sofort bereit. Starke JavaScript-Bibliotheken erm\u00f6glichen tolle Effekte und mit performanten JavaScript-Engines wie der quelloffenen V8 von Google oder TraceMonkey der Mozilla Foundation eine schnelle Verarbeitung.<\/li>\n<li>Java ist als allgemeine Programmiersprache entworfen worden, aber nicht als einfache Programmiersprache f\u00fcr grafische Effekte. Hier liegt der Vorteil von Adobe Flash\u00a0oder auch Microsoft Silverlight. Mit starken Tools k\u00f6nnen Designer gro\u00dfartige Oberfl\u00e4chen entwerfen, und die Verbreitung des Flash-Players ist ph\u00e4nomenal.<a title=\"\" href=\"file:\/\/\/C:\/Users\/Christian%20Ullenboom\/Dropbox\/Eigene%20Dokumente\/Insel\/2\/1507_17_Applets.doc#_ftn1\">[1]<\/a> Zudem erweitert Adobe die Multimedia-Technologie Flash, die Programmiersprache ActionScript sowie die Produktpalette zur Entwicklung kontinuierlich. Oracle versucht mit der Plattform JavaFX\u00a0(http:\/\/www.oracle.com\/technetwork\/java\/javafx\/overview\/index.html) dagegenzusetzen, aber JavaFX kann wohl eher Swing f\u00fcr Rich-Clients abl\u00f6sen und wird wohl im Internet ein Exot bleiben.<\/li>\n<li>Ist Java installiert, steht auf den Rechnern eine moderne und schnelle Java-Laufzeitumgebung f\u00fcr Applets \u00fcber ein Browser-Plugin zur Verf\u00fcgung. Das Problem beginnt aber, wenn Anwender Applets nutzen m\u00f6chten (oder m\u00fcssen), aber kein JVM installiert ist. HTML, CSS und JavaScript sind immer Teil des Browsers, und in der Regel ist auch Flash installiert. Dagegen ist der Bezug einer JVM langwierig, und viele Megabyte Daten m\u00fcssen vom Oracle-Server geladen werden. (Microsoft lieferte zwar fr\u00fcher f\u00fcr den IE eine JVM mit, doch wegen immer wieder auftretender Sicherheitsprobleme sollten Anwender Microsofts JVM deinstallieren. Microsoft liefert f\u00fcr Vista kein Java mit aus, und daher muss sowieso Oracles JVM installiert werden.<a title=\"\" href=\"file:\/\/\/C:\/Users\/Christian%20Ullenboom\/Dropbox\/Eigene%20Dokumente\/Insel\/2\/1507_17_Applets.doc#_ftn2\">[2]<\/a>)<\/li>\n<\/ul>\n<p><strong>Hinweis<\/strong>:\u00a0Wir wollen im Folgenden davon ausgehen, dass nicht die Java-Laufzeitumgebung 1.1 von Microsoft installiert ist, sondern ein vollwertiges Java von Oracle. Ist Oracles JVM installiert, ersetzt sie \u2013 falls diese installiert war \u2013 die JVM von Microsoft, und aktuelle Java-Programme lassen sich ausf\u00fchren.<\/p>\n<h3>(J)Applet und Applikationen<\/h3>\n<p>Verf\u00fcgen normale Applikationen, die von der Kommandozeile gestartet werden, \u00fcber eine statische main(String[])-Methode, ist das bei Applets anders. Sie erweitern zwingend die Klasse javax.swing.JApplet oder java.applet.Applet und implementieren Callback-Methoden statt einer main(\u2026)-Methode. (Hybride Programme, die sowohl Applikation als auch Applet sind, sind ebenfalls m\u00f6glich. Diese Sorte Programm erweitert einfach die Klasse (J)Applet und implementiert eine statische main(\u2026)-Methode.)<\/p>\n<p>Ein Applet\u00a0unterliegt hohen Sicherheitsbestimmungen \u2013 eine auf dem Client-Rechner liegende Datei kann zum Beispiel nicht gel\u00f6scht werden, und schon der lesende Zugriff ist unzul\u00e4ssig. Vom Sicherheitsstandpunkt aus betrachtet, kontrolliert der SecurityManager\u00a0die Handlungen der Software.<\/p>\n<h3>Das erste Hallo-Applet<\/h3>\n<p>Ein Programm wird leicht zu einem Applet, wenn es die Klasse Applet erweitert. Als Einstieg soll ein kleines Beispiel-Applet dienen.<\/p>\n<pre>import\u00a0java.applet.Applet;\r\nimport\u00a0java.awt.Graphics;\r\n\r\n public\u00a0class\u00a0HelloWorldApplet\u00a0extends\u00a0Applet {\r\n \u00a0\u00a0\/*\u00a0@Override\u00a0*\/\u00a0public\u00a0void\u00a0paint(\u00a0Graphics\u00a0g\u00a0)\r\n \u00a0\u00a0{\r\n \u00a0\u00a0\u00a0\u00a0g.drawString(\u00a0\"Hallo\u00a0Welt!\",\u00a050,\u00a025\u00a0);\r\n \u00a0\u00a0}\r\n }<\/pre>\n<p>Die beiden ersten import-Anweisungen binden die notwendigen Informationen \u00fcber Applets und \u00fcber Zeichenmethoden ein. Das HelloWorldApplet erweitert die Klasse Applet, denn so wird ein Applet erzeugt. Eine statische main(String[])-Methode kommt nicht vor, und es muss eine Methode paint(Graphics) \u00fcberschrieben werden, die den Bildschirmaufbau \u00fcbernimmt.<a title=\"\" href=\"file:\/\/\/C:\/Users\/Christian%20Ullenboom\/Dropbox\/Eigene%20Dokumente\/Insel\/2\/1507_17_Applets.doc#_ftn3\">[3]<\/a> Der Webbrowser oder Applet-Viewer ruft diese Methode per Callback auf.<\/p>\n<p>Damit der Viewer wei\u00df, was zu machen ist, gibt der HTML-Code einen Hinweis auf die Klasse, die in die Seite eingebettet wird. Dies wird \u00fcber ein spezielles Tag erreicht.<\/p>\n<pre>&lt;html&gt;&lt;body&gt;\r\n&lt;applet\u00a0code=\"HelloWorldApplet.class\"\u00a0width=\"200\"\u00a0height=\"100\"&gt;&lt;\/applet&gt;\r\n&lt;\/body&gt;&lt;\/html&gt;<\/pre>\n<p>Neben dem Namen der Klasse \u00fcbermittelt das Applet-Tag der virtuellen Maschine auch die Ma\u00dfe des Fensters, in dem das Applet zeichnen kann.<\/p>\n<p>Ab Java 1.1 lassen sich gepackte Dateien im Jar-Format \u00fcbermitteln. Die Angabe der Klasse in der Code-Anweisung sollte keine Leerzeichen beinhalten. Die Endung .class ist nicht in jedem Browser erforderlich, wird aber empfohlen.<\/p>\n<h4>Fehler in Applets finden<\/h4>\n<p>Werden Applets vom Browser nicht ausgef\u00fchrt, weil es Fehler in unserem Programm gibt, so bietet die Java Console (http:\/\/www.java.com\/en\/download\/help\/javaconsole.xml) die M\u00f6glichkeit, Log-Informationen anzusehen und so die Fehler genauer zu studieren.<\/p>\n<h2>Die Applet-API<\/h2>\n<h3>Die Zyklen eines Applets<\/h3>\n<p>Beim Start eines Applets werden unterschiedliche Methoden vom Browser automatisch aufgerufen. Es beginnt mit dem Aufruf der Methode init(). Dort sollten Initialisierungen erfolgen. init() wird nur einmal aufgerufen, wenn die Seite vom Browser geladen wird. Nach der Initialisierung folgt ein Wechsel der Methoden start() und stop() immer dann, wenn ein Applet im Browser sichtbar ist oder von der Seite verschwindet, etwa wenn der Anwender \u00fcber die Schieberegler einen anderen Bereich ausw\u00e4hlt, in dem das Applet nicht liegt. Beim Verlassen der Seite wird abschlie\u00dfend destroy() aufgerufen. Dort k\u00f6nnen Ressourcen freigegeben werden.<\/p>\n<h3>Parameter an das Applet \u00fcbergeben<\/h3>\n<p>Dem Applet k\u00f6nnen Parameter im Applet-Tag \u00fcbergeben werden. Dazu wird im &lt;applet&gt;-Element ein &lt;param&gt;-Element eingebettet. Im Folgenden zeichnet ein Applet einen gr\u00fcnen oder roten Kasten, in Abh\u00e4ngigkeit davon, ob eine URL korrekt aufgebaut ist.<\/p>\n<pre>&lt;html&gt;&lt;body&gt;\r\n &lt;a\u00a0href=\"http:\/\/tutego.com\/index.html\"&gt;Java-Seminare&lt;\/a&gt;\r\n &lt;applet\u00a0code=\"CheckUrlApplet.class\"\u00a0width=\"10\"\u00a0height=\"10\"&gt;\r\n &lt;param\u00a0name=\"url\"\u00a0value=\"http:\/\/tutego.com\/index.html\"&gt;\r\n &lt;\/applet&gt;\r\n &lt;p&gt;\r\n &lt;a\u00a0href=\"tutego.com\/index.html2\"&gt;Java-Seminare\u00a0Falsch&lt;\/a&gt;\r\n &lt;applet\u00a0code=\"CheckUrlApplet.class\"\u00a0width=\"10\"\u00a0height=\"10\"&gt;\r\n &lt;param\u00a0name=\"url\"\u00a0value=\"tutego.com\/index.html2\"&gt;\r\n &lt;\/applet&gt;\r\n&lt;\/body&gt;&lt;\/html&gt;<\/pre>\n<p>Das Applet nimmt den Parameter an und pr\u00fcft den g\u00fcltigen Aufbau der URL \u00fcber eine MalformedURLException.<\/p>\n<pre>import\u00a0java.applet.Applet;\r\nimport\u00a0java.awt.Color;\r\nimport\u00a0java.awt.Graphics;\r\nimport\u00a0java.net.MalformedURLException;\r\nimport\u00a0java.net.URL;\r\n\r\npublic\u00a0class\u00a0CheckUrlApplet\u00a0extends\u00a0Applet {\r\n\u00a0 private\u00a0boolean\u00a0urlOk\u00a0=\u00a0false;\r\n\r\n \u00a0public void init() {\r\n\u00a0 \u00a0\u00a0try {\r\n\u00a0 \u00a0\u00a0\u00a0new URL( getParameter( \"url\" ) );\r\n\u00a0\u00a0\u00a0 \u00a0\u00a0urlOk = true;\r\n\u00a0 \u00a0\u00a0}\r\n\u00a0 \u00a0\u00a0catch ( MalformedURLException e ) { \/* urlOk is false *\/ }\r\n\u00a0 }\r\n\u00a0\u00a0@Override public\u00a0void\u00a0paint(\u00a0Graphics\u00a0g\u00a0) {\r\n \u00a0\u00a0\u00a0\u00a0g.setColor(\u00a0urlOk\u00a0?\u00a0Color.GREEN\u00a0:\u00a0Color.RED\u00a0);\r\n \u00a0\u00a0\u00a0\u00a0g.fillRect(\u00a00,\u00a00,\u00a010,\u00a010\u00a0);\r\n \u00a0\u00a0}\r\n}<\/pre>\n<p>Interessant w\u00e4re nat\u00fcrlich, wenn das Applet gleich die URL auf Erreichbarkeit pr\u00fcfen w\u00fcrde. Relativ einfach ergeben sich dann folgende Zeilen:<\/p>\n<pre>try\u00a0{\r\n urlOk\u00a0=\u00a0((HttpURLConnection)new\u00a0URL(\u00a0getParameter(\"url\"\u00a0)\u00a0).\r\n openConnection()).getResponseCode()\u00a0==\u00a0HttpURLConnection.HTTP_OK;\r\n}\r\ncatch\u00a0(\u00a0IOException\u00a0e\u00a0)\u00a0{\u00a0\/*\u00a0urlOk\u00a0is\u00a0false\u00a0*\/\u00a0}<\/pre>\n<p>Doch bei der Pr\u00fcfung von \u00fcblichen Links kommt es zu einem Fehler! Aus Sicherheitsgr\u00fcnden kann ein Applet nur auf den Rechner zugreifen, von dem es geladen wurde, nicht auf andere. Ohne explizite Sicherheitserweiterungen kann so ein allgemeines Applet zum Pr\u00fcfen eines Links nicht geschrieben werden.<\/p>\n<h3>Wie das Applet den Browser-Inhalt \u00e4ndern kann *<\/h3>\n<p>Das Applet kann mit showDocument(URL [,String]) auf den Inhalt der Seite Einfluss nehmen. So lassen sich Applets bauen, die eine Baumstruktur der Seite anzeigen und dann zum Inhalt verweisen, falls eine Seite ausgew\u00e4hlt wird. Verwendet werden hier die Methoden von AppletContext. In Kurzform:<\/p>\n<pre>getAppletContext().showDocument(\u00a0new\u00a0URL(\"http:\/\/tutego.com\/\")\u00a0);<\/pre>\n<p>Oder, falls ein spezieller Frame mit Namen angesprochen ist:<\/p>\n<pre>getAppletContext().showDocument(\u00a0new\u00a0URL(\"http:\/\/tutego.org\"),\u00a0\"Framename\"\u00a0);<\/pre>\n<div>\n<p>class\u00a0java.applet.Applet\u00a0extends\u00a0Panel<\/p>\n<\/div>\n<ul>\n<li>AppletContext getAppletContext()<br \/>\nLiefert den Kontext des Applets. Dieser Kontext erlaubt es dem Applet herauszufinden, in welcher Umgebung, also auf welcher Web-Seite, es sich bewegt.<\/li>\n<\/ul>\n<div>\n<p>interface\u00a0java.applet.AppletContext<\/p>\n<\/div>\n<ul>\n<li>void showDocument(URL url)<br \/>\nErsetzt den Inhalt auf der aktuellen Seite durch eine neue Seite von der angegebenen URL.<\/li>\n<li>void showDocument(URL url, String target)<br \/>\nErsetzt den Inhalt auf der aktuellen Seite durch eine neue Seite von der angegebenen URL. Dabei wird das Dokument in einem Frame abgelegt, dessen Name zus\u00e4tzlich festgelegt ist. F\u00fcr target sind erlaubt: _self (Seite, die das Applet enth\u00e4lt), _parent (bettet die neue Seite in die Vaterseite des Applets ein; falls diese nicht existiert, verh\u00e4lt es sich wie _self), _top (im Top-Level-Frame anzeigen; falls dieser nicht existiert, wie _self), _blank (erzeugt ein neues Fenster), und wenn der Name nicht mit den Konstanten \u00fcbereinstimmt, wird die Anzeige in einen Frame gelegt, der diesen Namen tr\u00e4gt.<\/li>\n<\/ul>\n<h3>Den Ursprung des Applets erfragen<\/h3>\n<p>Greift ein Applet auf Daten des Servers zu und ist ihm die Adresse nicht bekannt, so kann es nachfragen. Die Applet-Klasse stellt die Methoden getCodeBase() und getDocumentBase() zur Verf\u00fcgung.<\/p>\n<div>\n<p>class\u00a0java.applet.Applet\u00a0extends\u00a0Panel<\/p>\n<\/div>\n<ul>\n<li>URL getCodeBase()<br \/>\nLiefert die Basis-URL des Applets.<\/li>\n<li>URL getDocumentBase()<br \/>\nLiefert die URL der Webseite, die das Applet enth\u00e4lt.<\/li>\n<\/ul>\n<p>Auf dem URL-Objekt liefert getHost() eine String-Repr\u00e4sentation der URL. So kommen wir mit der Methode getCodeBase().getHost() an den Hostnamen und auch an die Daten des Servers.<\/p>\n<p><strong>Beispiel<\/strong>:\u00a0Applets k\u00f6nnen problemlos von Webseiten geklaut werden. Um dem einen Riegel vorzuschieben, k\u00f6nnen wir verlangen, dass die Zeichenkette von getDocumentBase().getHost() immer die Webseite unseres Servers repr\u00e4sentiert.<\/p>\n<pre>String web = getDocumentBase().getHost();\r\nif ( ! \"www.tutego.com\".equals(web) ) {\r\n \/\/ hier meckern, dass was nicht stimmt.\r\n}<\/pre>\n<p>Wir k\u00f6nnten die \u00dcberpr\u00fcfung auch \u00fcber ein InetAddress-Objekt realisieren.<\/p>\n<div>\n<p>class\u00a0java.net.URL\u00a0implements\u00a0Serializable,\u00a0Comparable<\/p>\n<\/div>\n<ul>\n<li>String getHost()<br \/>\nLiefert den Hostnamen des URL-Objekts. Handelt es sich um das \u00bbfile\u00ab-Protokoll, so ist der R\u00fcckgabewert ein leerer String.<\/li>\n<\/ul>\n<p><strong>Beispiel<\/strong>:\u00a0Baue eine URL-Verbindung zu einer Grafikdatei auf. Wir benutzen hier zun\u00e4chst die Methode getDocumentBase(), um an die URL des Servers zu gelangen, und anschlie\u00dfend den URL-Konstruktor, der uns relativ zur Basisadresse eine Pfadangabe erlaubt.<\/p>\n<pre>URL u1 = getDocumentBase();\r\ntry {\r\nURL u2 = new URL( u1, \"image.gif\" );\r\n   ...\r\n}\r\ncatch ( MalformedURLException e ) { ... }<\/pre>\n<h3>Datenaustausch zwischen Applets *<\/h3>\n<p>Sind mehrere Applets auf einer Webseite untergebracht, gibt es F\u00e4lle, in denen die Applets Daten austauschen wollen. Zwei L\u00f6sungen sind popul\u00e4r:<\/p>\n<ul>\n<li>Da alle Applets in einer einzigen JVM laufen, l\u00e4sst sich \u00fcber statische Attribute auf die anderen Elemente zugreifen. Dies spricht jedoch gegen die Datenkapselung und ist sehr unfein. Diese Technik hat einen weiteren Schwachpunkt: Statische Variablen h\u00e4ngen eng mit dem Klassenlader zusammen, und hier traten in der Vergangenheit bei einigen Browsern Probleme auf.<\/li>\n<li>Eleganter ist da schon die M\u00f6glichkeit \u00fcber die Schnittstelle AppletContext, die es erm\u00f6glicht, einen Verweis auf das Applet \u00fcber den Namen zu bekommen.<\/li>\n<\/ul>\n<div>\n<p>class\u00a0java.applet.Applet\u00a0extends\u00a0Panel<\/p>\n<\/div>\n<ul>\n<li>AppletContext getAppletContext()<br \/>\nBestimmt die Umgebung eines Applets.<\/li>\n<\/ul>\n<h4>Applets \u00fcber den AppletContext erfragen<\/h4>\n<p>Mit dem AppletContext gibt es zwei M\u00f6glichkeiten, an das Applet zu gelangen:<\/p>\n<ul>\n<li>das Applet \u00fcber einen Namen ansprechen<\/li>\n<li>eine Aufz\u00e4hlung aller Applets erfragen<\/li>\n<\/ul>\n<p>Um einen Namen zu vergeben, wird das name-Attribut im &lt;applet&gt;-Tag genutzt, etwa so:<\/p>\n<pre>&lt;applet\u00a0code=\"Applet.class\"\u00a0name=\"applet\"\u00a0width=\"10\"\u00a0height=\"10\"&gt;<\/pre>\n<p>Eine Verbindung der Methoden getAppletContext() aus Applet und getApplet(String name) aus AppletContext f\u00fchrt zu folgender Zeile:<\/p>\n<pre>Applet\u00a0anotherApplet\u00a0=\u00a0applet.getAppletContext().getApplet(\u00a0\"applet\"\u00a0);<\/pre>\n<p>Die zweite Variante war, sich mit getApplets() eine Enumeration aller Applets einer Seite zu besorgen:<\/p>\n<pre>Applet\u00a0otherApplet\u00a0=\u00a0null;\r\nEnumeration\u00a0applets\u00a0=\u00a0getAppletContext.getApplets();\r\nwhile\u00a0(\u00a0applets.hasMoreElements()\u00a0) {\r\n otherApplet\u00a0=\u00a0(Applet)\u00a0applets.nextElement();\r\n if\u00a0(\u00a0otherApplet\u00a0!=\u00a0this\u00a0)\r\n  break;\r\n \/\/\u00a0Jetzt\u00a0k\u00f6nnen\u00a0wir\u00a0etwas\u00a0mit\u00a0dem\u00a0anderen\u00a0Applet\u00a0machen\r\n \/\/\u00a0if\u00a0(\u00a0otherApplet\u00a0instanceof\u00a0Applet2\u00a0)\r\n \/\/\u00a0 \u00a0...\r\n}<\/pre>\n<div>\n<p>interface\u00a0java.applet.AppletContext<\/p>\n<\/div>\n<ul>\n<li>Applet getApplet(String name)<br \/>\nSucht das Applet namens name in dem Dokument, das durch den AppletContext gegeben ist. Der Name kann durch das HTML-Tag gesetzt sein. Falls kein Applet dieses Namens existiert, liefert die Methode null.<\/li>\n<li>Enumeration&lt;Applet&gt; getApplets()<br \/>\nFindet alle Applets, die durch AppletContext angegeben sind.<\/li>\n<\/ul>\n<h4>Praktische Kommunikation<\/h4>\n<p>Das Applet k\u00f6nnen wir gegebenenfalls in eine Unterklasse casten. Dann lassen sich alle Methoden aufrufen und die Variablen auslesen. Leider funktionieren beide vorgestellten Methoden nur, wenn die Applets in dem gleichen Frame liegen. Liegen sie in verschiedenen Frames, findet zumindest die Netscape-Methode getApplet(String) das Applet leider nicht. Hier bleibt aber noch die Variante \u00fcber statische Variablen \u00fcbrig. Eine weitere M\u00f6glichkeit, Applets \u00fcber verschiedene Frames kommunizieren zu lassen, f\u00fchrt \u00fcber eine JavaScript-Funktion. Sie fungiert als Br\u00fccke, was etwa so aussieht: top.frames[1].document.applet[&#8222;applet&#8220;].method().<\/p>\n<p>Das folgende Beispiel zeigt zwei Applets, Applet1 und Applet2, auf einer Webseite. Zun\u00e4chst der HTML-Code:<\/p>\n<pre>&lt;html&gt;&lt;body&gt;\r\n&lt;applet\u00a0code=\"Applet1.class\"\u00a0name=\"applet1\"\u00a0height=\"200\"\u00a0width=\"200\"&gt;&lt;\/applet&gt;&lt;applet\u00a0code=\"Applet2.class\"\u00a0name=\"applet2\"\u00a0height=\"200\"\u00a0width=\"400\"&gt;&lt;\/applet&gt;\r\n&lt;\/body&gt;&lt;\/html&gt;<\/pre>\n<p>Es folgen die Implementierungen f\u00fcr die beiden Applets:<\/p>\n<pre>import\u00a0java.applet.Applet;\r\nimport\u00a0java.awt.*;\r\n\r\npublic\u00a0class\u00a0Applet1\u00a0extends\u00a0Applet {\r\n\u00a0\u00a0 private\u00a0TextField\u00a0inputText\u00a0=\u00a0new\u00a0TextField(\u00a0\"\",\u00a010\u00a0);\r\n \u00a0\u00a0public\u00a0void\u00a0init() {\r\n \u00a0\u00a0\u00a0\u00a0add(\u00a0inputText\u00a0);\r\n \u00a0\u00a0\u00a0\u00a0add(\u00a0new\u00a0Button(\u00a0\"Sende\u00a0an\u00a0Applet2\"\u00a0)\u00a0);\r\n \u00a0\u00a0}\r\n\r\n \u00a0\u00a0public\u00a0boolean\u00a0action(\u00a0Event\u00a0ev,\u00a0Object\u00a0arg\u00a0) {\r\n \u00a0\u00a0\u00a0\u00a0if\u00a0(\u00a0ev.target\u00a0instanceof\u00a0Button\u00a0) {\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Applet2\u00a0applet2\u00a0=\u00a0(Applet2)\u00a0getAppletContext().getApplet(\u00a0\"applet2\"\u00a0);\r\n\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if\u00a0(\u00a0applet2\u00a0!=\u00a0null\u00a0) \u00a0\u00a0\u00a0 {\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0applet2.appendTheText(\u00a0inputText.getText().trim()\u00a0);\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return\u00a0true;\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n \u00a0\u00a0\u00a0\u00a0}\r\n\r\n \u00a0\u00a0\u00a0\u00a0return\u00a0false;\r\n \u00a0\u00a0}\r\n }\r\n\r\nimport\u00a0java.applet.Applet;\r\nimport\u00a0java.awt.TextArea;\r\n\r\npublic\u00a0class\u00a0Applet2\u00a0extends\u00a0Applet {\r\n \u00a0\u00a0private\u00a0TextArea\u00a0textBox\u00a0=\u00a0new\u00a0TextArea(\u00a05,\u00a040\u00a0);\r\n\r\n \u00a0\u00a0public\u00a0void\u00a0init() {\r\n \u00a0\u00a0\u00a0\u00a0add(\u00a0textBox\u00a0);\r\n \u00a0\u00a0}\r\n\r\n \u00a0\u00a0public\u00a0void\u00a0appendTheText(\u00a0String\u00a0s\u00a0) {\r\n \u00a0\u00a0\u00a0\u00a0textBox.append(\u00a0s\u00a0+\u00a0\"\\n\"\u00a0);\r\n \u00a0\u00a0}\r\n }<\/pre>\n<p>Da bei verschiedenen Frames getAppletContext() jedoch das andere Applet nicht zur\u00fcckgeben muss, bleibt nur noch die Variante \u00fcber die statische Variable. Gl\u00fccklicherweise lassen sich mit Beobachtermustern aus auch elegante Benachrichtigungen realisieren.<\/p>\n<h3>Reiseverbot f\u00fcr Daten: Was ein Applet alles darf *<\/h3>\n<p>Ein Applet unterliegt bestimmten Sicherheitsbeschr\u00e4nkungen, die eine Java-Security-Einheit \u00fcberpr\u00fcft.<\/p>\n<p>Viele der bekannten Fehler in Java, die potenzielle Sicherheitsl\u00fccken darstellen, sind mittlerweile behoben. Schon das Auffinden setzt eine gr\u00fcndliche Kenntnis der Java-Quelltexte voraus, beispielsweise der Fehler mit der Host-Adresse: Wenn ein Benutzer ein Applet von tutego.com liest, darf dieses Applet nur mit diesem Host eine Verbindung aufbauen und mit keinem anderen. Doch leider gab es in den Quelltexten von Java einen Fehler, sodass das Applet nur den Rechnernamen des Hosts vergleicht, nicht aber die IP-Adresse. Ein b\u00f6sartiges Applet kann nun dem DNS (Domain Name Server) eine falsche Zuordnung von Rechnername und IP-Adresse vorspielen, und nun verh\u00e4lt sich tutego.com wie www.ganz-boese.com.<\/p>\n<h3>Ist Java im Browser aktiviert? *<\/h3>\n<p>Wenn unser Browser Java-Applets ausf\u00fchren soll, aber Java gar nicht aktiviert ist, dann lassen sich einige interaktive Benutzeraktionen nicht durchf\u00fchren. Wir sollten daher zumindest eine Meldung anbieten, dass der Browser Java gerade nicht aktiviert hat. Dies kann beabsichtigt oder nicht beabsichtigt sein. Nat\u00fcrlich kommt Java daf\u00fcr nicht infrage, aber eine Skript-Sprache mit einem \u00e4hnlichen Namen: JavaScript. Ab JavaScript-Version 1.1 bietet uns der Interpreter die Funktion javaEnabled() an, sodass wir eine Weiterschaltung vornehmen k\u00f6nnen:<\/p>\n<pre>if\u00a0(\u00a0! navigator.javaEnabled()\u00a0) {\r\n self.location.href\u00a0=\u00a0\"nix_mit_java.html\";\r\n}<\/pre>\n<p>F\u00fcr diese L\u00f6sung muss nat\u00fcrlich JavaScript aktiviert sein. F\u00fcr einige Surfer ist selbst dies schon eine Sicherheitsl\u00fccke, und wenn JavaScript deaktiviert ist, l\u00e4sst sich hier nichts mehr machen. Falls JavaScript aktiviert ist, kommen wir dem Benutzer einen Schritt entgegen, sodass er nicht mehr manuell angeben muss, ob Java aktiv ist oder nicht. Von dieser Technik sollten wir auch Gebrauch machen, denn nicht immer hat der Benutzer bewusst Java abgeschaltet. Im Beispiel oben haben wir eine Seite angesteuert, wobei nat\u00fcrlich andere Anweisungen denkbar sind. Doch diese Form ist sinnvoll, denn wir k\u00f6nnen Benutzern eine Kurzbeschreibung dar\u00fcber liefern, wie Java im Browser aktiviert wird. Zusammen mit der Browservariante ist eine browsergenaue Beschreibung einsetzbar.<\/p>\n<h3>Applet unter Firefox (Netscape) oder Microsoft Internet Explorer? *<\/h3>\n<p>Kann der Browser ein Applet aus irgendwelchen Gr\u00fcnden nicht ausf\u00fchren, so sind die Meldungen an den Benutzer meist mager. Oft beschr\u00e4nken sie sich auf eine Exception-Angabe in der Statuszeile. Dies mag keiner mehr sehen. Doch leider versch\u00e4rfen inkompatible Browser die Situation. Was hier Abhilfe schafft, ist ein kleines Programm, das zun\u00e4chst herausfindet, auf welchem Browser das Applet l\u00e4uft. Dann k\u00f6nnen unter Umst\u00e4nden browser- und versionsabh\u00e4ngige Varianten ausgef\u00fchrt werden.<\/p>\n<p>Wir verwenden einen Trick, der auch beim Erkennen von Prozessortypen angewendet wird: Wir versuchen, Klassen zu laden oder Methoden aufzurufen, die es f\u00fcr den jeweils anderen Browser nicht gibt. Der Internet Explorer hat zum Beispiel eine private Klasse com.ms. applet.GenericAppletContext, und Mozilla hat eine Klasse netscape.applet.MozillaAppletContext. L\u00f6st die JVM beim Laden der Klasse eine Exception aus, wissen wir Bescheid, um welchen Browser es sich handelt.<\/p>\n<p>Versuchen wir, \u00fcber die selbst gebastelten Methoden isNetscape() und isMicrosoft() etwas \u00fcber unsere Laufzeitumgebung herauszufinden.<\/p>\n<pre>import\u00a0java.applet.Applet;\r\n\r\npublic\u00a0class\u00a0BrowserDetector\u00a0extends\u00a0Applet {\r\n\r\n\u00a0public\u00a0void\u00a0init() {\r\n \u00a0\u00a0\u00a0\u00a0if\u00a0(\u00a0isNetscape()\u00a0)\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0System.out.println(\u00a0\"Netscape,\u00a0Firefox,\u00a0...\u00a0Browser.\"\u00a0);\r\n\r\n \u00a0\u00a0\u00a0\u00a0if\u00a0(\u00a0isMicrosoft()\u00a0)\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0System.out.println(\u00a0\"Microsoft\u00a0Browser.\"\u00a0);\r\n \u00a0\u00a0}\r\n\r\n \u00a0\u00a0public\u00a0static\u00a0boolean\u00a0isNetscape() {\r\n \u00a0\u00a0\u00a0\u00a0try\u00a0{\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Class.forName(\u00a0\"netscape.applet.MozillaAppletContext\"\u00a0);\r\n \u00a0\u00a0\u00a0\u00a0}\r\n \u00a0\u00a0\u00a0\u00a0catch\u00a0(\u00a0ClassNotFoundException\u00a0e\u00a0)\u00a0{\u00a0return\u00a0false;\u00a0}\r\n \u00a0\u00a0\u00a0\u00a0return\u00a0true;\r\n \u00a0\u00a0}\r\n\r\n \u00a0\u00a0public\u00a0static\u00a0boolean\u00a0isMicrosoft() {\r\n \u00a0\u00a0\u00a0\u00a0try\u00a0{\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Class.forName(\u00a0\"com.ms.applet.GenericAppletContext\"\u00a0);\r\n \u00a0\u00a0\u00a0\u00a0}\r\n \u00a0\u00a0\u00a0\u00a0catch\u00a0(\u00a0ClassNotFoundException\u00a0e\u00a0)\u00a0{\u00a0return\u00a0false;\u00a0}\r\n \u00a0\u00a0\u00a0\u00a0return\u00a0true;\r\n \u00a0\u00a0}\r\n }<\/pre>\n<p>Die Idee l\u00e4sst sich nat\u00fcrlich auch anwenden, um Java-Versionen zu testen; es wird einfach eine Klasse erfragt, die bei einer neuen Java-Version hinzugekommen ist, bei Java 2 etwa Point2D.<\/p>\n<p><strong>Tipp:\u00a0<\/strong>Da nicht immer sichergestellt sein kann, dass Java in einer vern\u00fcnftigen Version (&gt;= 1.2)\u00a0auf dem Client-Rechner der Benutzer installiert ist, l\u00e4sst sich ein Test-Applet vorschalten,\u00a0das zun\u00e4chst die Java-Version pr\u00fcft. Anschlie\u00dfend kann dieses Eingangs-Applet \u00fcber getAppletContext().showDocument() auf eine andere Seite mit einem Applet verweisen. F\u00fcr unterschiedliche Browser und Java-Installationen k\u00f6nnen somit unterschiedliche Applets auf die Situation eingehen.<\/p>\n<h2>Webstart<\/h2>\n<p>Bevor Software auf dem Rechner l\u00e4uft, wird sie in der Regel installiert. Dazu legen die Hersteller der Software ein spezielles Installationsprogramm bei \u2013 unter Windows oft die InstallShields. Das Installationsprogramm legt passende Verzeichnisse an und initialisiert etwa die Registrierdatenbank unter Windows. Etwas anders sieht das bei Java-Programmen aus. Die Installation erfordert zuerst eine Java-Laufzeitumgebung. Anschlie\u00dfend kann das Programm entpackt und gestartet werden. W\u00fcnschenswert ist jedoch eine Art Umgebung, wie sie bei Java-Applets definiert ist. Ein Java-Applet l\u00e4uft innerhalb eines Browsers in einem speziellen Sicherheitsmodus, und es w\u00e4re g\u00fcnstig, wenn dies auch f\u00fcr alle anderen Applikationen m\u00f6glich w\u00e4re. Das bedeutet: Eine beliebige Applikation kann von einer Webseite geladen und auf dem lokalen Rechner ausgef\u00fchrt werden. Die Applikation soll sich nicht von anderen Applikationen unterscheiden, die lokal installiert sind.<\/p>\n<p>Damit der Start m\u00f6glich ist, ist die Oracle-Technologie Webstart n\u00f6tig. Webstart deckt die Bereiche Installation, Start und Update durch ein eigenes Protokoll ab, das Java Network Launcher Protocol\u00a0(JNLP). Die Technologie wurde auf der JavaOne 2000 erstmals vorgestellt. Neben der offiziellen Webseite widmet sich auch die (nicht mehr ganz so frische) Unofficial Java Web Start\/JNLP FAQ unter http:\/\/lopica.sourceforge.net\/faq.html dem Thema.<\/p>\n<h2>Zum Weiterlesen<\/h2>\n<p>Die API rund um Applets blieb lange Zeit stabil und unaufregend. Mit einer neuen Browser-Implementierung und Ann\u00e4herung an WebStart passiert aber doch noch das ein oder andere. So k\u00f6nnen Applets\u00a0mittlerweile aus Web-Seiten herausgezogen werden, und Applets k\u00f6nnen problemlos den DOM-Baum der Seite modifizieren, in der sie laufen. Mehr Informationen zu diesen Themen gibt es in Oracles Java-Tutorial unter http:\/\/download.oracle.com\/javase\/tutorial\/deployment\/applet\/index.html. Es gibt auch von Oracle eine JavaScript-API, die das korrekte HTML f\u00fcr ein Applet generiert, sodass Entwickler nicht das eigentlich veraltete &lt;applet&gt; nutzen m\u00fcssen \u2013 Weiteres dazu unter http:\/\/download.oracle.com\/javase\/7\/docs\/technotes\/guides\/jweb\/deployment_advice.html#deplToolkit.<\/p>\n<div>\n<hr align=\"left\" size=\"1\" width=\"33%\" \/>\n<div>\n<p><a title=\"\" href=\"file:\/\/\/C:\/Users\/Christian%20Ullenboom\/Dropbox\/Eigene%20Dokumente\/Insel\/2\/1507_17_Applets.doc#_ftnref1\">[1]<\/a>\u00a0\u00a0\u00a0 <i>http:\/\/www.adobe.com\/products\/player_census\/flashplayer\/version_penetration.html<\/i><\/p>\n<\/div>\n<div>\n<p><a title=\"\" href=\"file:\/\/\/C:\/Users\/Christian%20Ullenboom\/Dropbox\/Eigene%20Dokumente\/Insel\/2\/1507_17_Applets.doc#_ftnref2\">[2]<\/a>\u00a0\u00a0\u00a0 <i>http:\/\/windowshelp.microsoft.com\/Windows\/en-US\/Help\/59c3a93d-1342-43a6-a01a-f720c7a17ffc1033.mspx<\/i><\/p>\n<\/div>\n<div>\n<p><a title=\"\" href=\"file:\/\/\/C:\/Users\/Christian%20Ullenboom\/Dropbox\/Eigene%20Dokumente\/Insel\/2\/1507_17_Applets.doc#_ftnref3\">[3]<\/a>\u00a0\u00a0\u00a0 Das gilt nicht f\u00fcr JApplet. Dort ist das \u00dcberschreiben von paint() oder paintComponent() un\u00fcblich, da im Allgemeinen eine eigene, sich zeichnende Komponente auf das JApplet gesetzt wird.<\/p>\n<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>\u00bbMode ist, was man selbst tr\u00e4gt. Altmodisch ist, was die anderen tragen.\u00ab\u2013 Oscar Wilde (1854\u20131900) Applets sind kleine Java-Programme, die in einem Webbrowser ablaufen. Sie geh\u00f6ren zu den Java-Programmen der ersten Stunde. Referenziert eine Web-Seite ein Applet, so startet der Browser eine virtuelle Maschine und f\u00fchrt das Applet aus. Applets in der Wiege von Java [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":"","_links_to":"","_links_to_target":""},"categories":[1],"tags":[],"class_list":["post-2676","post","type-post","status-publish","format-standard","hentry","category-allgemein"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/2676","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/comments?post=2676"}],"version-history":[{"count":1,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/2676\/revisions"}],"predecessor-version":[{"id":2677,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/2676\/revisions\/2677"}],"wp:attachment":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/media?parent=2676"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/categories?post=2676"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/tags?post=2676"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}