%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                    %
% Diplomarbeit von Sven Muessig                                      %
% angefangen am 13-okt-92                                            %
%                                                                    %
% Universitaet Hamburg                                               %
% Fachbereich Informatik                                             %
% Arbeitsbereich DBIS                                                %
%                                                                    %
% Kapitel: Graphische Benutzerschnittstellen in Tycoon (newsenv)     %
%                                                                    %
% Version vom 03-jul-94                                              %
%                                                                    %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\cleardoublepage

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter{Graphische Benutzerschnittstellen in Tycoon}
\label{Kap. Graphische Benutzerschnittstellen in Tycoon}

In diesem und dem n"achsten Kapitel werden die beiden im Rahmen dieser
Arbeit implementierten Bibliotheken (\s{newsenv} und \s{editenv}) 
vorgestellt. Zum besseren Verst"andnis dieser Kapitel sind \ua\ Kenntnisse
in der \n- und der \ty-Programmierung sowie dem Aufbau des \tnts\ 
erforderlich. Die vorherigen Kapitel sollten grundlegende Kenntnisse 
vermittelt haben.

Dieses Kapitel stellt ausf"uhrlich die Konzepte und die Implementation des
\s{newsenv}, einer Bibliothek zur dynamischen Erzeugung und Manipulation
graphischer Benutzerschnittstellen unter \ol\ in \ty, vor. Die Bibliothek 
baut auf den Ergebnissen der Untersuchung in Kapitel 
\ref{Kap. Entwicklungswerkzeuge fuer graphische Benutzerschnittstellen}
auf. Dort wurde untersucht, welcher Ansatz am besten geeignet ist, aus 
einer Programmiersprache heraus dynamisch graphische Benutzerschnittstellen
zu erzeugen. Aus diesem Grund werden in der Bibliothek die Klassen
des in Abschnitt \ref{Abs. Das NeWS Toolkit} beschriebenen \tnts\ in
\ty\ verf"ugbar gemacht.

Die umfangreiche Bibliothek (ca.\ 40 Module) bietet Schnittstellen zum
\tnt, zum \ws\ und zum \jo. Sie ist unter anderem eine Voraussetzung f"ur
die Implementation der in Kapitel \ref{Kap. Datenvisualisierung in Tycoon}
vorgestellten typsicheren generischen Editoren. Im Anschlu"s an die
Vorstellung der Bibliothek werden einige praktische Anwendungsgebiete 
des \s{newsenv} aufgezeigt. Ein detaillierter "Uberblick "uber die 
Funktionalit"at der Bibliotheksmodule ist auch in \cite{MMM93} zu finden.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Dynamische Erzeugung graphischer Benutzerschnittstellen}
\label{Abs. Dynamische Erzeugung von graphischen Benutzerschnittstellen}

Das \s{newsenv} ist das Ergebnis der Neuimplementation des in \cite{KiMu92}
vorgestellten Moduls \s{news}. Im Zuge der Erweiterung dieses Moduls
sind die Funktionen auf mehrere Module verteilt worden. Abbildung 
\ref{Abb. Struktur newsenv} zeigt, wie das \s{newsenv} in sechs jeweils
inhaltlich zusammenh"angende Teile gegliedert werden kann. Jeder Teil 
beinhaltet \idR\ mehrere Module.

\begin{figure}[htb]
  \psbild{0.8#1}{newsenv}{ModulstrukturNeWSEnv.ps}
  \caption{Grobstruktur des \s{newsenv}}
  \label{Abb. Struktur newsenv}
\end{figure}

Die Grundlage bildet ein Teil mit Modulen zur Kommunikation und 
Ereignisverwaltung. Alle weiteren Module der Bibliothek nutzen die von 
diesen Modulen zur Verf"ugung gestellte Funktionalit"at. Der weitaus 
gr"o"ste Teil der Module implementiert die Schnittstelle zu dem in 
Abschnitt \ref{Abs. Das NeWS Toolkit} vorgestellten \tnt. Auf dieser 
Ebene sind noch weitere Module angesiedelt, die Schnittstellen zu 
\n-Klassendefinitionen von Anwendern bieten. Einen Teil f"ur sich bilden 
die \jo-Editoren. In der h"ochsten Schicht des \s{newsenv} befinden sich
funktional speziellere Schnittstellenkomponenten, wie \zB\ 
Dateiauswahlboxen, die auf den Basismodulen der Bibliothek aufbauen.
In den nachfolgenden Abschnitten werden die einzelnen Teile ausf"uhrlich
beschrieben.

Die Benutzung von Funktionen aus der Bibliothek hat Vorteile f"ur die
Erstellung von Benutzerschnittstellen. Die Funktionen des \s{newsenv} 
gestatten es, eine Typisierung der Eingabeparameter durchzuf"uhren, von
der kellerspeicher-orientierten Syntax der \n-Methodenaufrufe zu 
abstrahieren und die sonst aufwendig zu programmierende Kommunikation,
die zwischen einer \ty-Anwendung und dem \xns\ stattfindet, zu verbergen
(\VAS\ \ref{Abs. Zusammenspiel der kommerziellen Dienste}). 


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Kommunikation und Ereignisverwaltung}
\label{Abs. Kommunikation und Ereignisverwaltung 2}

Ein Programm, das Schnittstellenkomponenten auf einem Bildschirm darstellen
und "uber Manipulationen an den Komponenten informiert werden will, mu"s 
mit dem \xns\ kommunizieren. Die Verbindung zwischen dem \ty-System und dem
\xns\ wurde in einer "alteren Version des Servers "uber benannte Dateien
des \pn{Unix}-Dateisystems (\e{named pipes}\,) abgewickelt. In der 
aktuellen Version wird die Verbindung durch eine bidirektionale Leitung
(\e{wire}\,) realisiert. Die Leitung kann mit einer Warteschlange 
verglichen werden, in der die Wartenden je nach verf"ugbarer Zeit des 
jeweiligen Empf"angers abgefertigt werden. Optional ist es jedoch m"oglich,
die Abfertigung programmtechnisch zu erzwingen.

In der \ty-Umgebung wird die Kommunikation zwischen einem \ty-Programm 
und dem \xns\ "uber das Modul \s{wire} abgewickelt. Darauf aufbauend 
implementiert das Modul \s{action} eine dynamische Ereignisverwaltung.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\minisec{Kommunikation}

Das Modul \s{wire} stellt im wesentlichen eine Schnittstelle zum \ws\
des \tnts\ dar. Es enth"alt Funktionen zum Auf- und Abbau sowie zur 
Initialisierung von Verbindungen zwischen der \ty-Umgebung und dem \xns.
Weitere Funktionen erlauben das dynamische Laden von \ps-Fragmenten in
den Server sowie das Senden und Empfangen von typisierten Werten.

Die Schnittstelle zum \ws\ ist "uber die dynamische Anbindung von
externen \cc-Bibliotheken realisiert. Die Funktionen der \cc-Bibliothek 
\s{libwire.so.1.0} werden "uber die generische \s{bind} Funktion in 
\ty-Modulen bekannt gemacht. Zum Beispiel wird die \cc-Funktion zum
Verbindungsaufbau zwischen \ty\ und dem \xns\ (\s{Open}) wie folgt 
eingef"uhrt:

\begin{xple}
    \k{let} Open = bind(:\k{Fun}(:String) :Int ''/usr/openwin/lib/libwire.so.1.0'' ''wire\_Open'' ''si'')
\end{xple}

Der erste Parameter beschreibt die Signatur (\s{\k{Fun}(:String) :Int}) 
der neuen \ty-Funktion \s{Open}. Die n"achsten beiden Parameter geben den
Namen der \cc-Bi\-blio\-thek (\s{libwire.so.1.0}) und den Namen der 
\cc-Funktion (\s{wire\_Open}), die importiert werden soll, an. 
Der letzte Parameter beschreibt die erwarteten Parameter der \cc-Funktion.
In diesem Fall ist der Eingabeparameter eine Zeichenkette (\s{s}) und der
R"uckgabeparameter eine ganze Zahl (\s{i}). Alle in \ty\ bekanntgemachten
Funktionen der \cc-Bibliothek werden in der gleichen Weise angebunden. 
Eine ausf"uhrliche Beschreibung der Anbindung externer \cc-Funktionen ist
in \cite{MMM93} zu finden.

Zwecks Vereinfachung der Benutzung wird beim Import des Moduls \s{wire}
automatisch eine Verbindung zum Server aufgebaut. Dies geschieht durch
den internen Aufruf der Funktion \s{new} mit dem \s{defaultServer}. Der
Variable \s{defaultServer} wird der Name des Servers zugewiesen, auf dem
das \ty-System l"auft.

\begin{xple}
  new(defaultServer)
\end{xple}

Nach einem Verbindungsaufbau werden zuerst die ben"otigten Pakete, hier
\s{NeWS}, \s{TNTCore} und \s{TNT} (\VAS\ \ref{Abs. Grundbegriffe NeWS}),
geladen. Anschlie"send k"onnen benutzerdefinierte Klassendefinitionen
in den Server geladen werden.

F"ur die im n"achsten Abschnitt beschriebene Ereignisverwaltung ist die
Funktion \s{allocateTags} wichtig. Sie erlaubt es, Assoziatoren (\e{tags}\,)
zu alloziieren, anhand derer sp"ater aufzurufende \ty-Funktionen 
identifiziert werden (asynchrone Kommunikation). Die Funktion \s{new}
initialisiert au"serdem einen speziellen Assoziator, das \s{scratchTag},
welches zur Abwicklung der synchronen Kommunikation (\VAS\ 
\ref{Abs. Kommunikation und Ereignisverwaltung}) ben"otigt wird. In diesem
Zusammenhang sei noch auf die Funktion \s{scratchSync} hingewiesen. Die
Funktion wird eingesetzt, um die synchrone Kommunikation sicher abzuwickeln
(\VAS\ \ref{Abs. Schnittstelle zum NeWS Toolkit}).

Eine Reihe von Funktionen des \ws\ erlauben das typisierte Schreiben 
(\e{write}\,) in und Lesen (\e{read}\,) aus der Leitung. Die von \ty\ aus
in die Leitung geschriebenen Objekte werden in FIFO-Reihenfolge 
(\e{first in, first out}\,) auf dem Kellerspeicher des Servers abgelegt.
Dort stehen sie anschlie"send f"ur weitere Manipulationen bzw.\ als
Parameter f"ur aufgerufene Methoden zur Verf"ugung. Umgekehrt werden
die Objekte vom Kellerspeicher mittels \k{tagprint} bzw.\ \k{typedprint}
(\VAS\ \ref{Abs. Programmierung NeWS}) in die Leitung geschrieben.
Sie k"onnen dann von \ty\ aus ausgelesen werden.

An einigen Stellen in \ty-Programmen, \zB\ bei der Installation von Aktionen
oder dem Bildschirmaufbau, kann es w"unschenswert sein, die Abarbeitung
der in die Leitung geschriebenen Operatoren, Methoden und Daten zu 
erzwingen. Aus diesem Grund steht die \s{flush}-Funktion des \ws\
auch in \ty\ zur Verf"ugung.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\minisec{Ereignisverwaltung}

Die Ereignisverwaltung wird durch das Modul \s{action} implementiert.
Aufgabe des Moduls ist zum einen die Installation (Assoziation) von 
Aktionen an Schnittstellenkomponenten und zum anderen die Behandlung
auflaufender asynchroner Nachrichten (\e{events}\,).

Vielen \ol\ Schnittstellenkomponenten kann eine Benachrichtigungsprozedur
(\e{notify procedure}\,) zugewiesen werden. Diese Prozedur wird 
ausgef"uhrt, wenn die Schnittstellenkomponente manipuliert, \zB\ 
ein Knopf gedr"uckt wird. Solche Prozeduren k"onnen Aktionen 
(\e{callbacks}\,) in \ty-Programmen ansto"sen. Damit die richtige 
Aktion angesto"sen wird, mu"s die Benachrichtigungsprozedur der 
Schnittstellenkomponente mit der anzusto"senden Aktion assoziiert
werden. Dies geschieht mit der Funktion \s{action.new}, die beide 
Partner "uber einen Assoziator (\e{tag}\,) verbindet. 

\begin{xple}
    \k{let} new(action :\k{Fun}() :\k{Ok}) :Wire.Tag =
       \k{begin}
          \k{let} index = wire.allocateTags(1)
          dynArray.set(events index action)
          index
       \k{end}
\end{xple}

Wie in der Funktion zu sehen ist, werden die Aktionen (\s{action}) 
mit ihrem Assoziator (\s{index}) f"ur den Anwender transparent in 
einem dynamischen Feld (\s{events}) gehalten. Der Vorteil dieser
Datenstruktur gegen"uber dem von \ty\ angebotenen Datentyp \k{Array}
ist, da"s ein dynamisches Feld zur Laufzeit wachsen kann, w"ahrend 
bei dem von \ty\ angebotenen Typ bei der Erzeugung des Feldes die 
Gr"o"se festgelegt werden mu"s.

Die Benachrichtigungsprozedur besteht auf der \n-Seite im einfachsten
Fall nur aus folgender Sequenz:

\begin{xple}
     \{ tag \k{tagprint} \}
\end{xple}

Wenn eine Schnittstellenkomponente manipuliert wird, so wird die 
Prozedur ausgef"uhrt und durch \s{tag \k{tagprint}} der Assoziator
"uber die Leitung zum \ty-Programm gesendet. Ist in der Nachricht
ein g"ultiger Assoziator, so wird die durch den Assoziator 
identifizierte Aktion ausgef"uhrt. Eine solche Vorgehensweise bietet
eine gro"se Flexibilit"at, denn es k"onnen zur Programmlaufzeit 
Aktionen auf einfache Weise hinzugef"ugt und entfernt werden.

Ankommende Ereignisse k"onnen neben dem sie identifizierenden 
Assoziator auch noch weitere Daten beinhalten. Deshalb gibt es f"ur
einige Basistypen von \ty\ (\s{Int}, \s{Real} und \s{String}) eigene
Installationsfunktionen. Die angesto"sene Aktion mu"s dann das 
Datum nicht selbst aus der Leitung lesen, sondern wird automatisch
mit dem entsprechenden Parameter angesto"sen.

Zur Laufzeit mu"s ein \ty-Programm in einer Nachrichtenschleife 
(\e{event loop}\,) auf ankommende Ereignisse warten. Zum Aufbau
dieser Schleife kann die nachfolgend beschriebene Funktion
\s{waitAndDispatch} verwendet werden.

\begin{xple}
    \k{let} waitAndDispatch() :\k{Ok} =
       \k{begin}
          \k{let} tag = wire.peekTag()
          \k{if} tag == 0 \k{then}
             \k{raise} error
          \k{else}
             \k{let} action = dynArray.get(events tag)
             \k{if} action != unused \k{then}
                wire.readTag()  action()   
             \k{else}
                wire.notify()  \k{ok}
             \k{end}
          \k{end}
       \k{end}
\end{xple}

Wird die Funktion aufgerufen, so wird in der Leitung nachgesehen 
(\s{wire.peekTag}), ob ein Assoziator vorliegt. Liegt dort ein 
g"ultiger Assoziator vor, so wird aus dem dynamischen Feld die 
dazugeh"orige Aktion extrahiert (\s{dynArray.get}). Anschlie"send 
wird der Assoziator aus der Leitung entfernt (\s{wire.readTag}) und
die Aktion aufgerufen (\s{action}). Ansonsten wird die Kontrolle
wieder an andere Prozesse "ubergeben (\s{wire.notify}).


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\minisec{Sitzungen}

Das \ty-System besitzt eine interaktive Programmierumgebung. Diese
erm"oglicht, zusammen mit dem Konzept der Persistenz, ein inkrementelles
Arbeiten "uber mehrere Benutzersitzungen hinweg (\VAS\ 
\ref{Abs. Systemintegration im Tycoon-System}). Daraus ergeben sich
aber auch verschiedene Probleme. Zum Beispiel besteht nach dem Beenden
einer Benutzersitzung keine Verbindung mehr zum \xns. Auch sind alle
im Server instanziierten Objekte und alloziierten Bezeichner von \ty\
aus nicht mehr zugreifbar.

In einer neuen Benutzersitzung ist es daher notwendig, eine neue Verbindung
zum Server aufzubauen und dort alle ben"otigten Objekte neu zu 
instanziieren und Bezeichner neu zu alloziieren. Dies mu"s jedoch manuell
erfolgen, da sich das Modul \s{wire} bereits im Objektspeicher befindet
und nicht neu importiert wird. Aus diesem Grund gibt es in der 
\ty-Bibliothek ein Modul namens \s{session}. Es erm"oglicht das Anmelden
von Funktionen, die bei dem Start einer Benutzersitzung ausgef"uhrt werden 
sollen. Im Falle des Moduls \s{wire} wird die folgende Sequenz verwendet:

\begin{xple}
    session.appendInitialization(\k{fun}() new(defaultServer))  
\end{xple}

Diese Sequenz f"ugt den Aufruf der \s{new}-Funktion in die Initialisierung
einer Benutzersitzung ein. 

Auch beim Import des Moduls \s{action} werden Daten initialisiert, \zB\ das
Feld, in dem die Assoziatoren mit den dazugeh"origen Aktionen gehalten
werden. In einer neuen Benutzersitzung sind die Daten im Feld nicht mehr
g"ultig. Das Feld mu"s neu initialisiert werden. Die folgende Sequenz f"uhrt
dies durch:

\begin{xple}
    session.appendInitialization(\k{fun}() events := dynArray.new(:T unused))
\end{xple}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Schnittstelle zum NeWS Toolkit}
\label{Abs. Schnittstelle zum NeWS Toolkit}

Zu jeder Klasse des \tnts\ gibt es im \s{newsenv} ein korrespondierendes
Modul, dessen Name sich aus dem Klassennamen ohne das Prefix \s{Class} 
ergibt. In den Modulen sind jeweils die wichtigsten Methoden der Klasse
durch Funktionen implementiert. Daraus ergeben sich einige Vorteile
gegen"uber dem direkten Methodenaufruf mit \s{wire.writeString}. Die 
Eingabeparameter der Methoden k"onnen durch Funktionsparameter ersetzt
werden. Dadurch wird die Syntax der Aufrufe vereinfacht. Die Typisierung 
der Funktionsparameter erlaubt eine Typ"uberpr"ufung zur "Ubersetzungszeit
und f"ordert damit die Fehlersicherheit. Durch die Definition der 
Funktionen wird eine leichtere Wiederverwendung erm"oglicht.

Intern werden die \ty-Funktionen direkt auf die jeweiligen Methoden der
zu dem Modul geh"orenden Klasse abgebildet. Dies soll anhand von einfachen 
Beispielen verdeutlicht werden. Die Beispiele entstammen dem Modul
\s{buttons}. In diesem Modul sind alle wesentlichen Operationsarten 
(\VAB\ \ref{Abb. Kommunikation} auf Seite \pageref{Abb. Kommunikation}) zu
finden, auf die die meisten Funktionen aus den Modulen des \s{newsenv} 
zur"uckzuf"uhren sind. Die Operationsarten, auf die die Funktionen 
zur"uckzuf"uhren sind, beinhalten das Erzeugen von Objekten (\e{create}\,),
das Setzen (\e{set}\,) und Abfragen (\e{get}\,) von Eigenschaften von 
Objekten sowie das Installieren von Aktionen (\e{set notifier}\,) in Objekten. 

\begin{figure}[htb]
  \psbild{0.65#1}{newsenv}{Kommunikation.ps}
  \caption{Kommunikation zwischen \ty\ und \n\ "uber die Leitung (\e{wire}\,)}
  \label{Abb. Kommunikation}
\end{figure}

In Abbildung \ref{Abb. Kommunikation} ist jeweils der auszuf"uhrende 
\ty- dem auszuf"uhrenden \n-Kode gegen"ubergestellt. Zus"atzlich ist zu 
sehen, welche Daten durch die Leitung zum Server und umgekehrt gesendet 
werden. Bevor nun die Beispiele beschrieben werden, stellt der n"achste
Abschnitt zwei grundlegende Dienste des Moduls \s{object} vor, die f"ur
alle weiteren Module von Bedeutung sind.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\minisec{Grundfunktionalit"at}

Ein oft ben"otigter Dienst ist das Senden einer Nachricht an ein benanntes 
Objekt. Daraus ergibt sich auch der zweite wichtige Dienst des Moduls: Das
Instanziieren und Benennen eines Objekts einer bestimmten Klasse. F"ur
diese beiden Dienste stehen die Funktionen \s{object.send} und 
\s{object.new} zur Verf"ugung.

Der in Abschnitt \ref{Abs. Programmierung NeWS} vorgestellte Methodenaufruf
ist durch die Funktion \s{send} nachgebildet.

\begin{xple} 
    \k{let} send(obj :Object.T  message :String) :\k{Ok} =
       wire.writeString(message $<>$ '' '' $<>$ obj $<>$ '' \k{send}'')
\end{xple}

Der Funktion werden beim Aufruf Nachricht (\s{message}) und Empfangsobjekt
(\s{obj}) "ubergeben. Intern wird aus den beiden Parametern eine
Zeichenkette der Art \s{''message obj \k{send}''} konstruiert und mit der
Funktion \s{writeString} in die Leitung geschrieben. Der Operator \k{send} 
sendet dann die Nachricht im Server an das Empfangsobjekt.

Um aber Nachrichten an Objekte senden zu k"onnen, m"ussen sie einen
Namen bekommen, der sie eindeutig identifiziert. Unter diesem Namen
sind die Objekte dann sowohl auf der \n- als auch auf der \ty-Seite 
identifizierbar. Die Zuweisung an einen Identifikator wird von \ty\ 
aus bei der Instanziierung des Objekts vorgenommen.

\begin{xple}
    \k{let} new(class :String) :T =
       \k{begin}
          send(class  ''/new'')
          \k{let} self = newToken()
          wire.writeString(''/'' $<>$ self $<>$ '' \k{exch} \k{def}'')
          self
       \k{end}
\end{xple}

Nachdem durch \s{send(class ''/new'')} ein neues Objekt der Klasse
\s{class} instanziiert worden ist, wird mit der Funktion \s{newToken}
ein neuer Identifikator (\e{token}\,) generiert. Da nun aber der 
Identifikator "uber dem Objekt auf dem Kellerspeicher liegt, m"ussen
vor der Definition durch den Operator \k{def} die beiden obersten 
Elemente des Kellerspeichers mit dem Operator \k{exch} vertauscht
werden.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\minisec{Erzeugen von Objekten}

In jedem Modul des \s{newsenv}, das mit einer Klasse des \tnts\
korrespondiert, gibt es eine \s{create}-Funktion. Sie wird benutzt,
um Objekte zu instanziieren. 

\begin{xple}
    \k{let} create(parent :Canvas.T) :Buttons.T =
       \k{begin}
          wire.writeString(''/Grid'')
          wire.writeString(parent)
          object.new(''ClassButtons'')
       \k{end}
\end{xple}

Mit dieser Funktion wird eine Gruppe von netzartig (\e{grid placement}\,)
angeordneten Kn"opfen erzeugt. Zu beachten ist, da"s jedem Objekt bei
der Instanziierung ein Vater (\e{parent}\,) zuzuordnen ist. Steht daf"ur
\zZt\ kein Objekt zur Verf"ugung, so kann als Vater der 
Bildschirmhintergrund (\e{framebuffer}\,) angegeben werden. 


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\minisec{Methodenaufruf ohne R"uckgabewerte}

Um die Eigenschaften von Schnittstellenkomponenten dynamisch "andern zu
k"onnen, werden spezielle Funktionen ben"otigt. Da diese Funktionen keine
R"uckgabewerte erwarten, bestehen sie im allgemeinen nur aus einem Teil,
in dem die ben"otigten Parameter in die Leitung geschrieben werden und 
dem eigentlichem Methodenaufruf mittels \s{object.send}.

An dem folgenden Beispiel ist auch ein weiterer Vorteil der Bibliothek zu
sehen. In der Klassenhierarchie des \tnts\ m"ussen gleichlautende Methoden
nur einmal implementiert werden. In der Hierarchie tiefer angeordnete Klassen
erben die Implementation von ihren Superklassen. Auch in \ty\ brauchen
solche Funktionen aufgrund des Subtyppolymorphismus, gleiche Parameterliste
vorausgesetzt, nur einmal implementiert zu werden. Die Funktionen sind
mit Instanzen unterschiedlicher Klassen parametrisierbar.

\begin{xple}
    \k{let} reshape(d :Drawable.T  location :Location  size :Size) :\k{Ok} =
       \k{begin}
          wire.writeInt(location.x)
          wire.writeInt(location.y)
          wire.writeInt(size.width)
          wire.writeInt(size.height)
          object.send(d ''/reshape'')
       \k{end}
\end{xple}

Im ersten Teil der Funktion \s{reshape} werden die gew"unschte Position
und Gr"o"se typisiert in die Leitung geschrieben. Anschlie"send wird die 
Methode \s{reshape} im Objekt \s{d} aufgerufen. Die Funktion erlaubt die
Positionierung (\s{location}\,) und Definition der Gr"o"se (\s{size}\,)
aller Objekte, die aus Subklassen der Klasse \s{ClassDrawable}
instanziiert worden sind. Wie in Abbildung \ref{Abb. TNT Klassenhierarchie}
auf Seite \pageref{Abb. TNT Klassenhierarchie} zu sehen ist, sind fast
alle Klassen direkte oder indirekte Subklassen der Klasse \s{ClassDrawable}.
Aus diesem Beispiel l"a"st sich auch der geschickte Aufbau der Klassenhierarchie
des \tnts\ ableiten. Generell verwendbare allgemeine Methoden sind in 
in der Hierarchie weit oben anzutreffenden Klassen definiert, w"ahrend 
spezielle, nur f"ur die jeweilige Klasse ben"otigte Methoden neu definiert
bzw.\ redefiniert werden m"ussen.



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\minisec{Methodenaufruf mit R"uckgabewerten}

Am Beispiel der \s{size}-Funktion wird die synchrone Kommunikation 
vorgestellt. Alle Funktionen im \s{newsenv}, die auf Methoden abgebildet
werden, welche R"uckgabewerte auf dem Kellerspeicher ablegen, sind in der
gleichen Weise implementiert. 

\begin{xple}
    \k{let} size(d :Drawable.T) :Size =
       \k{begin}
          wire.writeString(''scratchtag \k{tagprint}'')
          object.send(d ''/size'')
          wire.writeString(''\k{exch} \k{typedprint} \k{typedprint}'')
          wire.scratchSync()
          wire.readTag()
          \k{tuple} wire.readInt()  wire.readInt() \k{end}
       \k{end}
\end{xple}

Mit dieser Funktion kann die Gr"o"se aller Objekte des \tnts\ abgefragt
werden. Dazu wird zun"achst das vorher definierte \s{scratchtag} vom
Server aus in die Leitung geschrieben. Anschlie"send wird vom Objekt 
\s{d} die Gr"o"se bestimmt und auf dem Kellerspeicher abgelegt. Damit 
die $x$-Koordinate zuerst gelesen werden kann, m"ussen die beiden 
Koordinaten auf dem Kellerspeicher vertauscht (\k{exch}) werden. Die
"Ubertragung wird mit dem \k{typedprint} Operator vorgenommen. Auf 
der \ty-Seite wird mit \s{wire.scratchSync} auf das zuerst in die 
Leitung geschriebene \s{scratchtag} gewartet. Liegt es vor, kann 
es herausgelesen werden. Anschlie"send m"ussen nur noch die beiden 
Koordinaten gelesen und in ein Tupel verpackt werden.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\minisec{Installation von Aktionen}

Die letzte wichtige Operationsart ist die Installation von Aktionen an
instanziierte Schnittstellenkomponenten (asynchrone Kommunikation). 
Dazu werden der Installationsfunktion \idR\ neben dem Identifikator f"ur
die Schnittstellenkomponente noch die auszuf"uhrende Ak\-tion "ubergeben.
In diesem Beispiel wird zus"atzlich noch der Index des Knopfes in der
Gruppe, an dem die Aktion installiert werden soll, mit "ubergeben. 

\begin{xple}
    \k{let} setItemNotifier(but :Buttons.T  index :Int  act :Action.T) :\k{Ok} =
       \k{begin}
          wire.writeInt(index)
          wire.writeString(''\{ '' $<>$ fmt.int(action.new(act)) $<>$ '' \k{tagprint} \} '')
          object.send(but ''/setitemnotifier'')      
       \k{end}
\end{xple}

Auch hier werden zun"achst die ben"otigten Parameter auf dem Kellerspeicher
abgelegt, bevor die Methode \s{setitemnotifier} aufgerufen wird. Sie
installiert die "ubergebene Aktion an dem durch den Index ausgew"ahlten
Knopf. Die Benachrichtigungsprozedur besteht in diesem Fall aus der
einfachsten, schon in Abschnitt 
\ref{Abs. Kommunikation und Ereignisverwaltung 2} vorgestellten und
beschriebenen Sequenz. Aus diesem Grund wird hier nicht weiter darauf
eingegangen.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Schnittstelle zum Devguide}
\label{Abs. Schnittstelle zum Devguide}

In Abschnitt \ref{Abs. Developers Guide} ist beschrieben worden, wie mit
dem \dg\ interaktiv Benutzerschnittstellen erzeugt werden k"onnen. F"ur
einige Anwendungsklassen sind statische Benutzerschnittstellen ausreichend.
Aus diesem Grund existiert in der Bibliothek auch ein Modul, dessen 
Funktionen es erlauben, solche Benutzerschnittstellen von \ty-Programmen
aus anzusprechen und zu verwenden. 


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Schnittstelle zu benutzerdefinierten Klassen}
\label{Abs. Schnittstelle zu benutzerdefinierten Klassen}

Schnittstellen zu benutzerdefinierten Klassen lassen sich in der gleichen
Weise implementieren, wie die Schnittstellen zu Klassen des \tnts. Zu
erw"ahnen ist nur, da"s sich die Namensgebung der Methoden in den
benutzerdefinierten Klassen in jedem Fall an die durch die Klassenhierarchie
vorgegebene anlehnen sollte. Dies hat den Vorteil, da"s auch in 
benutzerdefinierten Klassen redefinierte Methoden "uber vorhandene
Methoden des \s{newsenv} aufgerufen werden k"onnen.

Die neuen Klassendefinitionen m"ussen dem \xns\ vor der ersten 
Instanziierung bekannt gemacht werden. Am einfachsten und 
wartungsfreundlichsten ist es, die Klassendefinition beim Import des
Moduls automatisch in den Server zu laden. Zu beachten ist dabei jedoch,
da"s die Definitionen nach Abbau der Verbindung verloren gehen 
(\VAS\ \ref{Abs. Kommunikation und Ereignisverwaltung 2}).


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Texteditoren}
\label{Abs. Texteditoren}

Da die Funktionalit"at der \jo-Texteditoren als \cc-Bibliothek vorliegt,
ist die Schnittstelle genau wie beim \ws\ "uber eine dynamische
Anbindung von externen \cc-Bibliotheken an \ty\ realisiert. Mit den drei
Modulen \s{jotText}, \s{jotView} und \s{jot} stehen in \ty\ alle
wichtigen Funktionen des \jo-Textpakets zur Verf"ugung. Auf die 
einzelnen Funktionen soll in diesem Zusammenhang aber nicht weiter
eingegangen werden.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Graphische Anwendungsprogrammierung}
\label{Abs. Graphische Anwendungsprogrammierung}

In diesem Abschnitt wird ein Projekt vorgestellt, in dem die Bibliothek
zur dynamischen Erzeugung graphischer Benutzerschnittstellen produktiv 
eingesetzt worden ist. Dar"uber hinaus werden auch die Probleme
skizziert, die beim Einsatz der Bibliothek aufgetreten sind. 

Bei der Entwicklung und Implementation der graphischen Benutzerschnittstelle
von Werkzeugen der \styl-Umgebung (\e{Systematics of TYped Language
Environments}\,) \cite{Wetz94} ist das \s{newsenv} auf unterschiedliche
Weise eingesetzt worden. Die \styl-Umgebung stellt eine interaktive
Entwurfsumgebung zum systematischen Design datenintensiver Anwendungen
dar. Eingesetzt wurde die Bibliothek \zB\ in einem Klasseneditor zur 
Entwurfsunterst"utzung \cite{Kass94} und in einem Graphikeditor zur 
objektorientierten Datenmodellierung \cite{Loes94}. Im folgenden werden 
jeweils die Motivation und die Konzepte vorgestellt, die zur Entwicklung
des Werkzeuges f"uhrten. Anschlie"send zeigt eine Abbildung den Aufbau 
der Benutzerschnittstelle des betrachteten Werkzeuges.

Ziel der folgenden Beispiele ist es nicht, in die \styl-Umgebung oder die
Werkzeuge vertiefend einzuf"uhren, sondern vielmehr, einen kurzen "Uberblick
"uber m"ogliche Einsatzgebiete der Bibliothek, deren Anforderungen und die
gew"ahlten L"osungen zu geben. F"ur einen vertiefenden Einblick in die
\styl-Umgebung und die Werkzeuge sei auf die angegebene Literatur verwiesen.
 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Ein Klasseneditor zur Entwurfsunterst"utzung}
\label{Abs. Ein Klasseneditor zur Entwurfsunterstuetzung}

%Das Entwickeln und Betreiben gro"ser Datenbanken ist in den vergangenen 
%Jahrzehnten zunehmend komplexer geworden. Im Zuge eines st"andig 
%wachsenden Informationsbedarfs werden Datenbanken und Informationssysteme 
%einerseits immer umfangreicher und komplexer, andererseits kommt es zu
%einer Erweiterung der Anwendungsfelder. Mit zunehmender Komplexit"at der
%Systeme ist es unverzichtbar, geeignete Werkzeuge zur Verf"ugung zu stellen,
%die den Vorgang der Datenmodellierung in geeigneter Weise unterst"utzen. 
%Dieses Problem kann durch die Implementation eines multifunktionalen 
%Texteditors (\VAB\ \ref{Abb. Klasseneditor}) gel"ost werden.

Die Aufgabe des multifunktionalen Texteditors ist die zielgerichtete 
Ent\-wurfs\-un\-ter\-st"ut\-zung bei der Modellierung von Klassendefinitionen
in einem objektorientierten Datenbanksystem.

\begin{figure}[p]
  \psbild{0.65#1}{newsenv}{ClassEditor.ps}
  \caption{Multifunktionaler Klasseneditor zur Entwurfsunterst"utzung 
           \protect\cite{Kass94}}
  \label{Abb. Klasseneditor}
\end{figure}

Die graphische Benutzerschnittstelle des multifunktionalen 
Texteditors ist aus unterschiedlichen Schnittstellenkomponenten 
unter Benutzung des \s{newsenv} zusammengesetzt worden
(\VAB\ \ref{Abb. Klasseneditor}). Die wichtigsten dabei verwendeten
Komponenten sind Fenster, Be\-h"al\-ter, Rollbalken, Festtexte, Men"us,
Kn"opfe, Notizen, Listen sowie eine Dateiauswahlbox.

Durch die Benutzung der Bibliothek hat sich die Konstruktion des 
Editors wesentlich vereinfacht, da die gew"unschte graphische
Benutzerschnittstelle mit relativ geringem Aufwand nach dem 
Baukastenprinzip erstellt werden kann. Demgegen"uber steht
die m"uhsame und fehlertr"achtige Programmierung der graphischen 
Benutzerschnittstelle in \n, die immer dann erforderlich wird, 
wenn eine ben"otigte Funktion nicht im Umfang der Bibliothek 
enthalten ist \cite{Kass94}.

Auch wird in der Arbeit auf einige Probleme des \tnts\ hingewiesen.
Zum Beispiel k"onnen einige Klassen nicht ohne weiteres miteinander
kombiniert werden. Beispielsweise wird bei der "Anderung der Gr"o"se
eines Fensters dessen Inhalt nicht angepa"st, \dh er bleibt in der
urspr"unglichen Gr"o"se bestehen. Ein weiteres Problem ergibt sich
bei einer starken Belastung des Servers mit der Leitung zum \xns. In
solchen Situationen stehen Befehlssequenzen teilweise noch zur H"alfte
im Puffer, w"ahrend die andere H"alfte schon abgearbeitet wurde. 
Bei nicht rechtzeitiger Freigabe des Puffers wird daher vergeblich
auf die fehlenden Informationen gewartet. Durch eine Freigabe des Puffers
nach zeitkritischen Funktionen ist dieses Problem jedoch in den Griff
zu bekommen. Dar"uber hinaus ist eine gelegentliche Restauration des
Bildschirms notwendig unumg"anglich \cite{Kass94}.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Ein Graphikeditor zur objektorientierten Datenmodellierung}
\label{Abs. Ein Graphikeditor zur objektorientierten Datenmodellierung}

Der Graphikeditor ist ein Werkzeug zur objektorientierten Datenmodellierung
in der \styl-Umgebung. Er dient der Erstellung von Diagrammen eines im
Rahmen einer Studienarbeit \cite{LoMo9} entworfenen semantischen
Datenmodells. Dabei werden, wie in Abbildung \ref{Abb. Graphikeditor} zu
sehen ist, in einem Referenzdiagramm die Klassen eines Schemas als
Knoten mit ausblendbaren Werteattributen modelliert. Die referentiellen
Beziehungen werden als Kanten zwischen den Klassen dargestellt. In einem 
Vererbungsdiagramm werden Vererbungsbeziehungen zwischen Klassen als
Pfeile zwischen den Klassenknoten angezeigt.

\begin{figure}[htb]
  \psbild{0.45#1}{newsenv}{GraphicEditor.ps}
  \caption{Graphikeditor zur Visualisierung \protect\cite{Loes94}}
  \label{Abb. Graphikeditor}
\end{figure}

Bei der Implementation der Graphikfunktionalit"at ergibt sich ein Problem
aus der Tatsache, das die oben genannten Diagramme anwendungsspezifische
graphische Bausteine beinhalten, die nicht in den \ol-Stilrichtlinien 
spezifiziert werden. Zur L"osung dieses Problems bieten sich 
grunds"atzlich zwei Strategien an. Zum einen kann das \s{newsenv}
verwendet werden, um die neuen graphischen Bausteine zu erzeugen und zu
verwalten. Diese Vorgehensweise ist zwar portabel, macht aber intensiven
Gebrauch von den bidirektionalen Kommunikationsm"oglichkeiten des \ws.
Zum anderen k"onnen neue \n-Klassen implementiert werden, die die
ben"otigten graphischen Bausteine und Operationen zur Verf"ugung stellen.
Diese Vorgehensweise nutzt auch die M"oglichkeit, komplexe Programme
direkt im \xns\ ausf"uhren zu k"onnen. Dadurch werden auch die im 
vorherigen Abschnitt aufgef"uhrten Probleme des \tnts\ zum Teil umgangen.
Die neuen Klassen erhalten bei Bedarf, genau wie die Klassen des 
\s{newsenv}, eine Schnittstelle in \ty. Die gew"ahlte Strategie wird
im folgenden kurz beschrieben.

F"ur den Aufbau der graphischen Benutzerschnittstelle aus 
\ol-Schnitt\-stel\-len\-kom\-po\-nen\-ten, wie Grund- und Aufklappfenstern,
Men"us, Kn"opfen und Rollbalken, sowie f"ur das Anh"angen von Aktionen an 
Men"upunkte werden Funktionen aus Modulen des \s{newsenv} verwendet.
Um die von \ol\ nicht spezifizierte Funktionalit"at zur Erzeugung, zur
Manipulation und zur Anzeige der Diagramme zu erhalten, werden neue 
Schnittstellen in \ty\ implementiert. Durch Nutzung der Basisdienste
\s{wire} und \s{action} aus dem \s{newsenv} wird der Implementationsaufwand
f"ur die Funktionen, die die Methoden der neu definierten \n-Klassen
aufrufen, verringert \cite{Loes94}.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% End of text                                                        %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
