Die in Kapitel 2 diskutierten Hypertextsysteme benutzen bereits einige der aktiven Elemente des WWW, allerdings sind alle diese Objekte statisch auf den WWW-Seiten eingebunden. In Kapitel 3.5 werden Kommunikationsmethoden zwischen Objekten auf einer WWW-Seite vorgestellt, die eine sehr weitgehende Interaktion zwischen Browser und Benutzer ermöglichen.
<html>
<head>
<title>Titelangabe</title>
</head>
<body>
...
Text und Bilder
...
</body>
</html>
|
Die in Bild 3.1 abgebildete Grundstruktur einer HTML-Datei besteht nur aus solchen Komponenten, die jedes HTML-Dokument enthalten sollte. Die Anweisungen <html> und </html> umschließen alle Anweisungen in einer HTML-Datei. Die einzelnen Anweisungen heißen Tags und bestehen in der Regel aus einem Start-Tag (z.B. <html>) und einem Ende-Tag (z.B. </html>). Das <title> Tag umschließt den Titel des Dokuments, der auch in der Fensterzeile des verwendeten Web-Browsers erscheint. Das <body> Tag schließt den eigentlichen Inhalt eines Dokuments ein.
<html> <head> <title>VCLab-Verweis</title> </head> <body> Dies ist ein HTML-Dokument mit einem <a href="http://www.esr.ruhr-uni-bochum.de/VCLab">Verweis</a> auf VCLab. </body> </html> |
Die Programmierung der Hypertextverbindungen geschieht über
sogenannte Anchors. Dies sind Tags, die einen Textabschnitt
oder ein Bild umschließen und auf die Adresse eines anderen
Dokuments im WWW verweisen. Bild 3.2 zeigt ein HTML-Dokument mit
einem Verweis auf das VCLab, das in dieser Arbeit entwickelt wurde
und auf einem WWW-Server abgelegt wurde.
HTML umfaßt etwa 100 unterschiedliche Tags, die verschiedene
Schriftauszeichnungen, Listen, Bilder, Objekte, Tabellen, Formulare,
usw. enthalten. Auf eine Aufzählung aller Befehle wird an
dieser Stelle verzichtet. In der Literatur und im WWW selbst finden
sich eine Vielzahl von Anleitungen und Handbüchern zu diesem
Thema, deren Zahl von Tag zu Tag anwächst. Eine gute Einführung
und Übersicht bieten [MuN96] und [Klu96].
Auf die Syntax der Programmiersprache Java wird in dieser Arbeit nicht weiter eingegangen. Eine Einführung in Java bieten z.B. [Cor96] und [Flan96]. Im Folgenden soll lediglich der Zusammenhang zwischen den Angaben im Quelltext der HTML-Datei und den Angaben im Quelltext des Java-Applets verdeutlicht werden.
Bild 3.3 zeigt einen Ausschnitt einer HTML-Datei, in der ein Java-Applet "AnimText" aufgerufen wird.
<applet code=AnimText.class width=400 height=75> <param name=text value="Dieser Text wird animiert!!!!!"> <param name=fgcolor value=white> <param name=style value=bold> <param name=min value=14> <param name=max value=48></applet> |
Mit <applet ... > wird die Referenz eines Java-Applets eingeleitet. Zwischen dem einleitenden Tag und dem abschließenden </applet> werden in vielen Fällen Parameter angegeben, die zur Konfiguration eines Applets benutzt werden können.
Die Objektklasse wird im Quelltext des Java-Applets definiert und von einer allgemeineren Objektklasse der Java-Objekthierarchie abgeleitet. Im Beispiel des oben gewählten Applets heißt die Objektklasse AnimText. Die Objektklasse (bzw. die Java-Klasse) und der Dateiname des Java-Applets müssen identisch sein. Dem Dateinamen wird die Endung .java angehängt. Im zugehörigen Java-Quelltext wird diese Klasse z.B. wie in Bild 3.4 definiert. Der zur Abbildung gehörende Dateiname des Applets lautet "AnimText.java" und die kompilierte Klasse heißt "AnimText.class".
public class AnimText extends Applet implements Runnable
{
...
Definitionen und Methoden des Java-Applets
...
}
|
Mit der Zusatzangabe "width" in Bild 3.3 wird die Breite des Anzeigebereichs, in dem das Java-Applet ablaufen soll, mit "height" die Höhe des Anzeigebereichs festgelegt. Wie bei Bildern, Videos und Plugins erfolgt die Angabe in Pixeln.
Viele Java-Applets erwarten beim Aufruf Parameter, die dem Applet als zusätzliche Eingabe zur Konfiguration dienen. Dieses Verfahren ermöglicht es, mit einem einzigen Java-Applet durch vielfältige Optionen ein breites Anwendungsspektrum zu erzielen, ohne vor jedem Einsatz des Applets den Quellcode neu kompilieren zu müssen.
Welche Parameter ein Java-Applet erwartet, wird im Applet selbst definiert. Wenn ein unbekanntes Java-Applet eingebunden werden soll, muß eine Dokumentation der Parameterliste vorhanden sein. Bild 3.5 zeigt einen Ausschnitt eines Applet-Quelltextes, der den Parameter "text" abfragt und der Variablen s zuweist.
public void init()
{
String s;
s = getParameter("text");
... usw. - andere Java-Anweisungen
}
|
Alle übergebenden Parameter werden mit einem eigenen HTML-Tag, und zwar zwischen <applet...> und </applet> angegeben. Jeder Parameter wird mit <param name="ParameterName" value="Wert"> angegeben. Mit "name" wird der Name und mit "value" der gewünschte Wert des Parameters angeben, dabei können sowohl Zahlen wie auch Zeichenketten gewählt werden. Zahlenwerte als Parameter müssen bei der Implementierung auf das korrekte Zahlenformat hin überprüft werden, eine explizite Konvertierung von String nach int, float oder double ist notwendig.
<html>
<head>
<title>Interactive Root Locus Example</title>
<script language="JavaScript" SRC="script.js">
</script>
<head>
<body onLoad=getUserLevel()>
...
<applet code=slider.class height=50 width=200
name=slider MAYSCRIPT>
</applet>
<script language="JavaScript">
function dispPandZ() {
var p=0;
if (document.control.poles.selectedIndex==0){
document.p1.disable();}
</script>
...
<form>
<input type="button"
value="enable"
onClick="document.slider.enable()">
<input type="button"
value="disable"
onClick="document.slider.disable()">
</form>
<script language="JavaScript">
document.write("<h3>VCLab</h3>");
</script>
...
</body>
</html>
|
In dieser Arbeit wird JavaScript dazu verwendet, um auf "public" deklarierte Methoden in Java-Applets und Plugins zuzugreifen. Außerdem ist es möglich, mit dem JavaScript-Programmcode selbst wieder HTML-Code zu erzeugen. Dies ermöglicht es, daß erst während des Seitenaufbaus einer HTML-Seite entschieden wird, welcher HTML-Code dargestellt wird. Die Erfassung des unterschiedlichen Vorwissens der Lernenden wird dadurch realisiert, daß z.B. einzelnen Lernenden Information vorenthalten wird, die zu weitgehend ist oder dadurch, daß auf einer weiteren HTML-Seite zusätzliche Informationen angegeben werden, die einen Sachverhalt verdeutlichen.
In Bild 3.6 sind alle Varianten zur Einbindung von JavaScript-Code in eine HTML-Datei enthalten. Der JavaScript-Programmcode kann in einer separaten Datei auf einem WWW-Server gespeichert werden. Der Browser wird die dazugehörige Datei mit der Endung ".js" laden, sobald er auf die entsprechende Anweisung stößt. Der Aufbau der HTML-Seite wird für den Ladezeitraum unterbrochen. Dies ermöglicht es, in einer separaten Datei oft benötigte und komplexere Funktionen abzulegen und den HTML-Code für den Entwurf und die nachfolgende Pflege einfacher lesbar zu halten.
Es besteht die Möglichkeit, durch sogenannte "Events" JavaScript-Funktionen aufzurufen. Viele Tags und Objekte können dazu mit entsprechenden "Event Handlern" verbunden werden (siehe "onLoad", "onClick", u.s.w.), die diese Funktionen auslösen.
JavaScript-Funktionen können darüberhinaus wie andere Tags auch direkt in einer HTML-Datei angegeben werden. (z.B.: "<script language="JavaScript"> ... </script>").
Netscape hat die Spezifikation und Implementierung
der JavaScript-Sprache noch nicht vollständig abgeschlossen.
In [Ait97] und [Min96], sowie auf dem Netscape Webserver befinden
sich umfangreiche Sprachbeschreibungen und Beispiele, die den
bisherigen Entwicklungsstand verdeutlichen.
Der Netscape Navigator ist mit einer dokumentierten Softwareschnittstelle ausgestattet, die es ermöglicht, zusammen mit dem sogenannten "PluginSDK" (Plugin Software Development Kit) von Netscape, Plugins unter Visual C++ zu entwickeln. Viele der im Internet verfügbaren Plugins nutzen diese Möglichkeit, um zusätzliche Grafik-, Video- und Animations-Dateien im Browserfenster zu betrachten.
Im Rahmen der vorliegenden Arbeit wurden zwei Plugins entwickelt. Das ClipBoard-Plugin erweitert den Browser um die Möglichkeit zur Darstellung von (Enhanced-) Metafile Grafiken. Dieser Dateityp wird von MATLAB unterstützt. Das zweite Plugin, das MATLAB-Plugin, verbindet den Browser mit der regelungstechnischen Simulationssoftware MATLAB. Dies ermöglicht es, daß vom Browser aus Berechnungen und Simulationen in MATLAB durchgeführt werden können.
<html> <body> ... <embed src=system1.m name="matlab" width=500 height=100> ... </body> </html> |
Zur Einbettung eines Plugins in eine HTML-Datei sind zwei Möglichkeiten vorgesehen. Zum einen kann, wie in Bild 3.7, eine Datei angegeben werden, die von einem Server geladen wird und vom Plugin bearbeitet wird. Die Alternative sieht vor, den MIME-Typ der entsprechenden Anwendung anzugeben (siehe Bild 3.8). Dadurch wird im Gegensatz zur ersten Variante ein Fensterbereich im Browser für Ausgaben des Plugins reserviert. Das Plugin befindet sich dann in einem Wartezustand. Über LiveConnect (siehe Kapitel 3.5), können als "public" deklarierte Methoden und Variablen in Plugins aufgerufen und manipuliert werden.
<html>
<body>
...
<embed type="application/x-matlab" name="matlab"
width=500 height=100>
...
</body>
</html>
|
Plugins sind plattformabhängige Programme. Ein Plugin für Windows95 oder WindowsNT kann nicht für einen UNIX-Rechner verwendet werden. Die Schnittstellen zur Anpassung eines Plugins an Netscape wurden für alle Plattformen identisch vorgegeben, so daß eine Portierung zwischen den Plattformen erleichtert wird. Die softwaretechnische Realisierung eines Plugins für Windows Plattformen besteht aus einer "Dynamic Link Library" ("DLL") und einer optionalen Java-Klasse, die für die Einbindung in die LiveConnect Umgebung zuständig ist und "public" Methoden exportieren kann.
Ausreichende Literatur zur Entwicklung und Programmierung von Netscape Plugins ist bislang nicht vorhanden. Aufgrund der schnellen Entwicklung und permanenten Veränderung der Interfacefunktionen und des Zugriffsverfahren für Plugins, beschränkt sich die Unterstützung des Entwicklers auf vorgegebene Beispiele und die Analyse der in entsprechenden Newsgroups und auf Websites diskutierten Probleme und Anregungen.
Netscape hat diese Einschränkungen sehr frühzeitig erkannt und bot erstmals mit der Version 3.0 des Navigators eine Möglichkeit an, zwischen einzelnen Objekten eine Kommunikationsmöglichkeit zu implementieren. Diese implementierten Verfahren sind so umfassend, daß alle Objekte, die einen eigenen Fensterbereich zugeteilt bekommen, Aktionen ("Events") auslösen und auf Aktionen reagieren können. Zur Beschreibung dieses dynamischen Kommunikationskonzepts wurde der Name "LiveConnect" gewählt. Es gilt allerdings die Einschränkung, daß das Layout, also die Position der Objekte auf der einmal aufgebauten HTML-Seite im Browser, nicht nachträglich verändert werden kann.
LiveConnect bildet alle Objekte (Bilder, Textfelder, Buttons, Check Buttons, Java-Applets, JavaScript Objekte) auf das zentrale Objekt "document" ab, das in Verzweigungen Referenzen auf eben diese Objekte enthält. Die Objekthierarchie (siehe Bild 3.9) wird damit über JavaScript allen anderen Objekten zugänglich gemacht.

Neben der hierarchischen Anordnung der Objekte bietet LiveConnect allen Objekten Verfahren und Methoden, mit denen alle anderen Objekte innerhalb des Browsers referenziert, manipuliert und aufgerufen werden können. Dies umfaßt Formulare, Java-Applets, Plugins, JavaScript und weitere Netscape spezifische Objekte ("history", "location", "frames").
In Bild 3.10 sind die in dieser Arbeit benutzten Kommunikationskanäle der aktiven Objekte (Java-Applets, JavaScript und Plugins) exemplarisch markiert. Die folgenden Kapitel beschreiben die dafür notwendigen Methoden und Objektaufrufe anhand kurzer, abstrahierter Beispiele.

Bild 3.11 enthält den HTML-Code einer WWW-Seite, auf der zwei Applets mit den Namen "gl1" und "gl2" eingebunden werden. Die Angabe der Namen ist erforderlich, um sicherzustellen, daß sich beide Applets gegenseitig referenzieren können. Die Angabe des Schlüsselwortes "MAYSCRIPT" muß aus Sicherheitsgründen zur Genehmigung von Datenzugriffen innerhalb des LiveConnect erfolgen. Es erlaubt den Applets, über LiveConnect auf alle JavaScript Objekte zuzugreifen.
<html>
<head>
<title>HotEqn - Dynamische Gleichungen</title>
</head>
<body>
<h1>Dynamische Gleichungen</h1>
...
Ausgehend von <applet code=HotEqn.class
height=40 width=60 name=gl1 MAYSCRIPT>
<param name="LeftSide" value="x">
<param name="RightSide" value="\sqrt{3*u+4}">
</applet> <br>gilt
<br>
<applet code=HotEqn.class height=80 width=150 name=gl2 MAYSCRIPT>
<param name="equation" value="z=\frac{1}{x-4}">
<param name="prev0" value="gl1">
</applet>.<br>Klicken
Sie auf (gl2), um die dynamische Änderung zu sehen. Benutzen
Sie zunächst die <b>linke</b> und dann die <b>rechte</b>
Mausetaste.
...
</body>
</html>
|
Da Applets Verbindungen mit dem WWW-Server aufnehmen können, von dem sie geladen wurden, wird dem Programmierer einer HTML-Datei verdeutlicht, daß diese Applets unbemerkt Daten aus der HTML-Datei (z.B. Formulareingaben) an den WWW-Server schicken könnten, ohne daß dies von ihm bemerkt würde.
import java.awt.*;
import java.applet.*;
import java.applet.Applet;
import java.applet.AppletContext;
public
class HotEqn extends Applet {
...
public boolean mouseDown(Event ev, int x, int y) {
Applet prevApplet = getAppletContext().getApplet(
getParameter("prev0"));
HotEqn prevHotEqnApplet= (HotEqn)prevApplet;
String prevLeftSideS = prevHotEqnApplet.getLeftSide();
String prevRightSideS = prevHotEqnApplet.getRightSide();
}
...
}
|
Bild 3.12 zeigt einen Auszug aus dem Java-Applet "HotEqn". Nach der Angabe der benutzten Standardklassen, wobei zur Inter Applet Kommunikation zusätzlich die beiden Klassen "java.applet.Applet" und "java.applet.AppeltContext" eingebunden werden müssen, erfolgt die Definition des Applets mit der Klasse "HotEqn". Die Angabe des "public" Schlüsselwortes stellt sicher, daß andere Applets auf diese Klasse zugreifen können.
In der Methode "mouseDown" fragt das Applet "gl2" den Parameter "prev0" ab, der den Namen des zu referenzierenden Applets "gl1" enthält. In "prevHotEqnApplet" ist also eine Referenz auf das Applet "gl1" hinterlegt und es können beliebige "public" Methoden in diesem Applet aufgerufen werden.
Im Netscape Navigator müssen bei der Inter Applet Kommunikation einige zusätzliche Einschränkungen aus Sicherheitsüberlegungen beachtet werden. Siehe dazu Bild 3.13.
Geben sind zwei Applets A und B:
und
und
|
<html>
<head><title>Interactive
Root Locus Example</title><head>
<body>
<h1>Interactive Example</h1>
...
<applet code=slider.class height=15 width=350 name=z1
MAYSCRIPT>
<param name="steps" value="20">
<param name="action" value="rl_examp">
<param name="script" value="dispPandZ()">
</applet>
...
<script language="JavaScript">
function dispPandZ() {
var p=0;
if (document.control.poles.selectedIndex==0){
document.p1.disable();}
</script>
...
</body>
</html>
|
Bild 3.15 zeigt den Aufruf der JavaScript-Funktion innerhalb des Java-Applets. Die JavaScript-Sprache besitzt nicht wie Java-Applets oder Plugins einen eigenen Objektnamen, über den die benutzten Funktionen referenziert werden können. Die Funktion "eval(scriptS)" wird benutzt, um einen Ausdruck oder eine Funktion in JavaScript aufzurufen.
import java.applet.Applet; import java.awt.*; import java.lang.*; import netscape.javascript.JSObject; |
<html>
<head>
<title>Interactive Root Locus Example</title>
<head>
<body>
<h1>Interactive Example</h1>
...
<applet code=slider.class height=50 width=200
name=slider MAYSCRIPT>
</applet><form>
<input type="button" value="enable"
onClick="document.slider.enable()">
<input type="button" value="disable"
onClick="document.slider.disable()">
</form>
<script language="JavaScript">
document.slider.enable();
</script>
...
</body>
</html>
|
In Bild 3.16 ist ein Ausschnitt aus einer HTML-Datei abgebildet, die neben einem Java-Applet drei JavaScript-Anweisungen enthält. Die ersten beiden Anweisungen werden durch "Buttons" ausgelöst, die dritte Anweisung wird während des Seitenaufbaus ausgeführt. Die aufgerufenen Methoden des Applets sind in Bild 3.17 abgebildet. Neben den "public" Methoden können alle als "public" deklarierten Variablen abgefragt und verändert werden.
import java.applet.Applet;
import java.awt.*;
public class slider extends Applet {
...
public void enable() {
scrollbar.enable();
}
public void disable() {
scrollbar.disable();
}
...
}
|
<html>
<head>
<title>Step Response</title>
<head>
<body>...
<embed type="application/x-matlab" name="matlab"
width=240 height=80>
...
<applet code=slider.class height=50 width=200
name=slider MAYSCRIPT>
|
import netscape.javascript.JSObject;
import VCLabPlugin;
public class slider extends Applet {
private JSObject doc;
private VCLabPlugin vclab;
...
private void toMatlab(double value)
{
doc=(JSObject)JSObject.getWindow(this).getMember("document");
vclab=(VCLabPlugin)doc.getMember("matlab");
vclab.engEvalString("a=5");
}
...
}
|
import netscape.plugin.Plugin;
public class VCLabPlugin extends Plugin {
public native void engEvalString(java.lang.String evalS); |
Bild 3.20 zeigt einen Ausschnitt der Java-Klasse des MATLAB-Plugins. Wichtig für die Referenzierung des Plugins ist die "public" Definition der Plugin-Klasse und der aufgerufenen Methode, die in diesem Fall als "native" Methode implementiert ist. "Native"-Methoden sind alle diejenigen Methoden, die im C++-Teil eines Plugins abgearbeitet werden. Im Java-Teil des Plugins befindet sich dazu der Prototyp der entsprechenden Methode.
<html>
<head>
<title>Impulse Response</title>
<head>
<body>
...
lt;embed type="application/x-matlab" name="matlab" hidden=true>
...
<form name=control>
<input type=button value="compute impulse response"
onClick="document.matlab.engEvalString('impulse(A,B,C,D,1);');">
</form>
...
</body>
</html>
|
Bild 3.21 zeigt einen Ausschnitt aus einer HTML-Datei mit der Einbettung eines Plugins, das mit dem Objektnamen "matlab" in die Objektstruktur von LiveConnect eingebunden wird. Der im Formular definierte "Push-Button" ruft schließlich eine Methode in demselben Plugin auf, indem der Objektname und die dazugehörige Methode angegeben werden. Die aufgerufene Methode ist in Bild 3.22 abgebildet.
import netscape.plugin.Plugin;
public class VCLabPlugin extends Plugin {
public native void engEvalString(java.lang.String evalS);
public void clearAll() {
engEvalString("clear all");
}
}
|