Steuerungsmethode für die Anordnung von graphischen Elementen
Die Erfindung betrifft die Steuerung von Benutzeroberflächen mit graphischen Elementen ('graphical user interface ' , GUI).
Für die Erstellung von Programmen mit graphischer Oberfläche sind eine Reihe von Werkzeugen verfügbar, die die Erstellung solcher Programme erleichtern.
Ein Beispiel ist das Compiler-System 'Delphi' der Firma
Inprise (vormals Borland) . In diesem System plaziert der Benutzer Objekte der graphischen Oberfläche auf einer Arbeitsoberfläche und weist ihnen Eigenschaften zu. Die Klassen dieser Objekte werden in Delphi als Komponenten bezeichnet. Die Lage der Objekte wird von der Oberfläche des Compilersystems notiert und in Resource-Files abgelegt. Damit sind die Objekte von ihrer Lage vorgegeben. Es ist zwar durchaus möglich, die Lage während der Laufzeit zu verändern; dies erfordert jedoch die Angabe von Pixel-Koordinaten und ist demgemäß entsprechend aufwendig.
Eine solche dynamische Anpassung wird beispielsweise benötigt, wenn Datenbankabfragen dargestellt werden müssen, deren Umfang erst zur Laufzeit nach der Datenbankabfrage bekannt ist . Zu diesem Zweck sind in Delphi besondere Kompo- nenten vorgesehen, die beispielsweise eine tabellarische Darstellung aller ermittelten Daten erlauben. Zwar sind die Eigenschaften der Darstellung parametrisierbar; natürlicherweise aber nur im Rahmen der vorgesehenen Darstellung. Diese vorgesehenen Darstellungen sind textueller Art und entspre- chen Formularen und tabellarischen Darstellungen. Wird eine andere, insbesondere die Beziehungen der Daten untereinander visuell deutlich machende Darstellung gewünscht, muß entweder eine neue spezifische Komponente erstellt werden oder die gesamte graphische Gestaltung speziell programmiert werden. Beides erfordert in erheblichem Umfang Detailkenntnisse und ist dem Einsteiger in ein solches System zunächst verschlossen und daher auch für den Expterten zeitaufwendig.
In der Patentschrift US 5,802,514 ist ein System zur Darstellung von Datenbankinhalten dargestellt, das eine formular-orientierte Darstellung erzeugt. In der Patentschrift US 6,104,393 wird ein System zur Integration prozeduraler und objekt-orientierter Benutzerschnittstellen gezeigt, bei dem gleichfalls die formularmäßige Darstellung gewählt ist . Andere, im UNIX Umfeld entstandene Werkzeuge sind die Programmiersprache JAVA und das Tcl/Tk System. In beiden werden als 'layout manager' bezeichnete Teilsysteme verwendet . In diesem Umfeld werden die angezeigten graphischen Objekte auch als 'widgets' bezeichnet, um sie deutlich von den Objekten der Programmiersprache zu unterscheiden. Ein Layout-Manager ordnet Objekte der Programmiersprache, denen eine graphische Repräsentation zugeordnet ist, auf einer Oberfläche an, wenn diese angezeigt wird oder in der Größe oder sonstwie verändert wurde. Die graphischen Objekte werden dem Layout-Manager-Objekt bekanntgemacht, wobei über Parameter Einfluß auf die Position genommen werden kann, ohne daß dabei absolute Pixelpositionen notwendig sind. Ist die Anzahl der Objekte vorbestimmt, d.h. während der Programmierung fest vorgegeben, ist dieses Vorgehen gut anwendbar. Werden die Objekte jedoch dynamisch generiert und sind nicht vorbestimmt, dann erfordert jeder Fall eine eigene Lösung spezifisch für diese Fall.
Es ist die Aufgabe der vorliegenden Erfindung, eine Methode •anzugeben, mit der die Anordnung von Widgets mit Hilfe von Layout-Managern einfach und zuverlässig gesteuert werden kann, ohne das Programmierung im Detail erforderlich ist. Die Methode soll insbesondere die visuelle Darstellung von Datenbankabfragen einfach machen und zur Integration in eine visuelle Programmgenerator-Oberfläche geeignet sein. Die Erfindung löst diese Aufgabe dadurch, daß zunächst die Widgets als Objekte angelegt werden und sodann bei der Übergabe der Objekte an einen Layout-Manager ein Satz von Regeln die Parameter der Objekte und ihre Position bestimmt. Diese
Regeln werden in einer Tabelle aufgestellt und dann entweder interpretativ abgearbeitet oder in entsprechenden Programmcode übersetzt.
Dabei besteht die Tabelle abstrakt aus zwei Teilen: Einer Bedingung und einer Aktion. Jeweils ein Paar von Objekten wird bezüglich der Bedingung überprüft und im Fall eines Zutreffens gemäß der Aktion dem bezogenen Layout-Manager bekanntgemacht . Dies wird weiter unten an einem Bespiel ausführlich erläutert. Es ergibt sich dann, daß es einfach möglich ist, Regeln für die Reaktion auf Benutzeraktionen hinzuzufügen.
Es handelt sich also um eine Methode für die Steuerung der Anordnung graphischer Elemente, deren Plazierung durch eine Layout-Manger-Komponente bewirkt wird, wobei die Elemente nach einer vorbestimmten Verfahren in Tupeln aufgezählt werden und für jedes Tupel eine boolsche Bedingung ausgewertet wird und bei Zutreffen der boolschen Bedinungung ein zugeordnete Anweisung ausgeführt wird, die Steuerungs- anweisungen für die Layout-Manager-Komponente umfaßt. Die
Methode wird bevorzugt in Generatorsystemen für die Erzeugung von Datenbanken abfragenden Anwendungen eingesetzt, wobei für jede Zeile der Ergebnistabellen graphische Objekte erzeugt werden und diese durch die genannte Methode auf der graphischen Oberfläche angeordnet werden.
Es zeigen
Fig. 1 und Fig. 2 zwei Klassendefinitionen in Java, die ein Beispiel für die Erfindung darstellen, und Fig. 3 das bei der Ausführung entstehende Ergebnis.
Die Erfindung wird im folgenden an Hand eines vereinfachten Beispiels beschrieben. Dabei wird die Programmiersprache JAVA verwendet, im Beispiel die Version 1.1.6. Die in Fig. 1 und Fig. 2 vorangestellten Zeilennummern gehören nicht zum Programmtext, sondern dienen nur der Bezugnahme.
Das Beispiel betrifft eine Telefonkette, in der ein Teilnehmer jeweils einen oder mehrere andere Teilnehmer anruft. Dazu wird eine tabellarische Datenstruktur verwendet, die weiter unten genauer dargestellt wird und in der der Name eines Teilnehmers mit seiner eigenen Telefonnummer und der Telefonnummer desjenigen verknüpft wird, von dem er angerufen werden soll.
In Fig. 1 ist die Klasse 'Layouter' dargestellt, die einen Bildschirmbereich mit graphischen Objekten füllt und deren Ausführung ein Ergebnis gibt, wie es in Fig. 3 dargestellt ist. Die graphischen Objekte sind in diesem Beispiel alle von einer Klasse 'aPanel', die in Fig. 2 aufgeführt ist. Diese Klasse 'aPanel' besteht hier lediglich aus dem Kon- struktor in Zeile 85 bis 92 und drei Zugriffsfunktionen in Zeile 93 bis 95.
Der Konstruktor von 'aPanel' ist von der Klasse 'Panel' abgeleitet und definiert ferner drei Variablen. In den Variablen 'myNumber' und 'hisNumber' in Zeile 82 und 83 werden zwei Zeichenketten, in dem Beispiel Telefonnummern, gespeichert. Ferner wird ein weiteres 'Panel' verwendet, das in das Panel der Klasse 'aPanel' verschachtelt ist. Der Konstruktur hat ausweislich Zeile 85 drei Parameter, nämlich 'who', 'myTel' und ■ calledFrom' . Diese Parameter ent- sprechen den Spalten der die Daten definierenden Tabelle.
Benutzt wird der Konstruktor in den Zeilen 42 bis 49 von Fig. 1, in denen acht Instanziierungen von 'aPanel' erzeugt werden. In den Zeilen 86 und 87 werden der zweite und dritte Para- meter in jeweils einer Variablen abgelegt. Diese sind durch die Funktionen 'getCallee' und 'getNumber' in Zeile 94 und 95 abfragbar .
In Zeile 88 wird als Layout-Manger ein 'BorderLayout ' festgelegt. Ein Layout-Manager arrangiert eine Anzahl von graphischen Objekten innerhalb eines Bereichs, hier eines 'Panel', indem zunächst die relative Lage der Objekte angegeben wird und später diese Objekte von dem Layout-Manger
positioniert werden. Layout-Manager sind fester Bestandteil der Oberflächenprogrammierung durch das 'JAVA AWT' und daher in einer Vielzahl von Publikationen beschrieben. Sie sind in ähnlicher Form auch in der Programmierumgebung 'Tcl/TK' vorhanden und in können daher als Grundkenntnisse vorausgesetzt und als allgemein bekannt angesehen werden. In der Regel wird eine geschachtelte Hierarchie von spezifischen Layout-Managern verwendet und diese auch insgesamt als Layout-Manager bezeichnet. Ein 'BorderLayout' erlaubt es, graphische Objekte dem 'Panel' hinzuzufügen und dabei anzugeben, ob sie oben, als 'NORTH', oder in der Mitte, als 'CENTER' bezeichnet, anzuordnen sind. Demgemäß wird in Zeile 89 ein Objekt 'Button' oben in dem Panel des in Instanzierung befindlichen Objekts 'aPanel' angeordnet. Es wurde das Objekt 'Button' für dieses Beispiel gewählt, weil ein solcher üblicherweise eine Umrahmung hat und damit gut in dem Panel unterscheidbar ist . Die mit einem Button mögliche Ereignissteuerung wird in diesem Beispiel nicht verwendet. Die Beschriftung des 'Button' enthält den Namen und die eigene Telefonnummer, wie sie durch den ersten und zweiten Parameter des Konstruktors gegeben sind. Sodann wird in Zeile 90 dem in Zeile 84 erzeugten Panel ein anderer Layout-Manger, nämlich ein 'GridLayout ' , zugeordnet. In Zeile 91 wird dieses Panel dem Layout-Manger 'Border- Layout' als Zentrum ('CENTER') bekanntgegeben. Gefüllt wird dieses untergeordnetes 'Panel' namens ' subPanel ' noch nicht; die Erfindung benutzt hierzu eine weiter unten beschriebene Methode . Mit der Klasse 'aPanel' wird also ein Bereich erzeugt, in dem eine als 'Button' dargestellte Kopfzeile mit Name und Telefonnummer vorhanden ist, unterhalb derer ein untergeordnetes Panel gegeben ist, in dem die Objekte für die anzurufenden Personen darzustellen sind.
Es sei an dieser Stelle darauf hingewiesen, daß bei Program- mierung nach dem Stand der Technik zunächst die durch die
Tabelle beschriebene Baumstruktur nachgebildet werden würde, um sodann die Objekte von den Blättern des Baumes aufsteigend
zu erzeugen, so daß das Layout der Blätter eines jeden Knotens bereits fertiggestellt ist und sodann in das Layout des nächsthöheren Knotens integriert werden kann. Die Erfindung läßt die Verknüpfung der Objekte zunächst offen und verwendet eine eigene Methode, die weiter unten dargestellt wird.
Wenden wir uns nun der Klasse 'Layouter' zu, die den Zeilen
10 bis 59 in Fig. 1 dargestellt ist.
Die Klasse 'Layouter' enthält eine statische Funktion 'main' in Zeile 51 bis 58, die damit einen Aufruf als 'application' zuläßt. In Zeile 52 wird ein 'Vector' names 'theData' erzeugt, der die anzuzeigenden Daten enthalten wird. Ein Vektor aggregiert eine Anzahl von Objekten. In Zeile 53 wird durch Aufruf der Funktion 'createData' eine Anzahl von Objekten der Klasse 'aPanel' instanziert und in dem Vektor 'theData' gespeichert. Diese Funktion steht hier stellvertretend dafür, daß eine nicht vorbestimmte Anzahl von graphischen Objekten erzeugt wird, deren Anordnung Inhalt der Erfindung ist. In der Regel wird hierzu eine Datenbank- Abfrage beispielsweise einer relationalen Datenbank verwendet werden, in der für das Beispiel eine dreispaltige Tabelle ermittelt wird und für jede Zeile ein Objekt der Klasse 'aPanel' erzeugt wird, dem die Spaltenwerte als Parameter mitgegeben werden. Die Vielzahl der dem Fachmann zugänglichen Techniken zur Gewinnung solcher Datenmengen wird hier der Übersichtlichkeit halber durch die Funktion 'createData' repräsentiert . Das Beispiel ist auch insofern besonders einfach, als nur eine Tabelle und nur eine Klasse von Objekten verwendet wird. Sind die, in der Regel nach Anzahl und Art nicht einzeln vorbestimmten, Objekte erzeugt, dann wird in Zeile 54 eine eine Instanz der Klasse 'Layouter' erzeugt. Diese ist aus der Klasse 'Frame' abgeleitet und stellt damit einen (rechteckigen) Rahmen dar, in dem die Objekte durch die Erfindung angeordnet werden sollen. Dies erfolgt in Zeile 55 durch den Aufruf der Funktion 'doArrange', die weiter unten genauer dargestellt wird. Die Instanziierung in Zeile 54 hat den
Konstruktor in Zeile 14 bis 16 aufgerufen, der lediglich als Layout-Manger ein 'BorderLayout' festlegt. Dieses ist der Standard-Layout-Manager und hier nur expliziert, um die Struktur deutlicher zu machen. Nachdem die noch zu beschreibende Funktion 'doArrange' die Anordnung der Objekte festgelegt hat, wird in Zeile 56 durch die aus der Klasse geerbte Funktion 'pack' die spezifizierte Anordnung durch die Layout-Manger arrangiert und durch Zeile 57 sichtbar gemacht, so daß das Ergebnis nach Fig. 3 sichtbar wird. Nicht aufgeführt sind in dem Beispiel alle Elemente zur Interaktion, insbesondere eine Ereignisbehandlung zum Beenden der gestarteten Applikation.
In der Funktion 'doArrange' in den Zeilen 29 bis 40 werden nun durch zwei verschachtelte Schleifen alle Paare von in dem Vektor 'theData' enthaltenen Objekten gebildet. Der Einfachheit halber werden hierzu die beiden Variablen 'xx' und 'yy' verwendet, die bereits von dem Typ der in dem Beispiel einzigen Klasse 'aPanel' sind. Kern der Funktion 'doArrange' sind die Zeilen 36 und 37, in denen für jedes Paar ' (xx,yy) ' zunächst eine boolsche Funktion 'constraintl ' (Zeile 17-19) bzw. 'constraint2 ' (Zeile 23-25) aufgerufen wird. Liefern diese Funktionen 'true', wird die Funktion 'arrangel' (Zeile 20-22) bzw. 'arrange2' (Zeile 26-28) aufgerufen. Dabei prüfen die 'constraint ' -Funktionen, ob die abhängige 'arränge' -Funktion anzuwenden ist. Im Beispiel wird in 'contstraintl' die eigene Nummer des einen ('xx') mit Nummer des Anrufenden ('yy') auf Gleichheit verglichen. Sind die Nummern gleich, dann muß 'xx' als von 'yy' anzurufen ange- ordnet werden. Dies erledigt die Funktion 'arrangel' durch Aufruf der Klassenfunktion 'intoPanel', durch die das Objekt 'yy' in dem Unterpanel 'subPanel' des Objekts 'xx' eingetragen wird. Damit der Ursprung der Telefonkette in das 'Frame' des umfassenden Objekts 'mywin' eingetragen wird, wird die gleiche Technik verwendet. Hier besteht die durch ' constraint2 ' formulierte Bedingung darin, daß alle Teil-
nehmer, die von niemandem angerufen werden, durch 'arrange2' dorthin eingetragen werden. In dem Beispiel ist das nur ein Teilnehmer bzw. Objekt. In dem Bespiel wird die robuste Funktionalität der JAVA AWT ausgenutzt, weil 'arrange2' mehr- fach mit identischen Parametern aufgerufen wird. In einer optimierten Version würde die Zeile 37 hinter die Zeile 33 verschoben werden.
Die Zeilen 36 und 37 in Verbindung mit den Funktions- definitionen der aufgerufenen Funktionen stellen die Codegenerierung für folgende Tabelle dar:
In den ersten beide Spalten werden die Objekte 01 und 02 aufgeführt, die in den weiteren Spalten als Parameter verwendet werden. In der dritten Spalte wird eine Bedingung aufgeführt, bei deren Erfülltsein die Aktion der vierten Spalte ausgeführt wird. In dem Beispiel wurde die Tabelle in Code in den Zeilen 17 bis 40 umgesetzt. Alternativ kann die Tabelle als Tabelle dargestellt werden und interpretativ abgearbeitet werden.
Im praktischen Einsatz der Erfindung werden fast immer mehr als zwei Klassen von Objekten darzustellen sein. In diesem Fall wird in den ersten beiden Spalten auch die Klasse des Objekts aufgeführt. Für unser Beispiel würde die Tabelle dann so lauten:
Diese Darstellung ist äquivalent einer Form, in der die Bedingung eine UND-Verknüpfung von zwei Vorbedingungen, die die Klasse der Parameter festlegen, und der eigentlichen Bedingung darstellen. Die letztere Form ist jedoch besser für Optimierungen geeignet. Eine solche Optimierung besteht darin, für jede Klasse einen eigenen Vektor anzulegen, in dem die Objekte der Klasse aggregiert werden. Die paarbildende Schleife, in der die Bedingung geprüft wird, braucht dann nur die Objekte des jeweiligen Vektors aufzuzählen. Im übrigen ergibt sich die oben angesprochene Optimierung, bei der Zeile 37 vor Zeile 34 verschoben ist, automatisch von selbst.
Im Gegensatz zu den Objekten ist die Tabelle vordefiniert, d.h. nicht von den Datenbankinhalten abhängig, wenn die Daten aus einer Datenbank gewonnen werden.
Bevorzugt wird die Erfindung in GeneratorSystemen für Anwendungen eingesetzt, mittels derer Datenbankinhalte visuali- siert werden sollen. In einem solchen System erstellt der An- wender zunächst die Datenbankabfragen, zum Beispiel in der
Form von SELECT-Anweisungen einer relationalen Datenbank. Das System ermittelt die Anzahl und die Art der Spalten durch eine Strukturabfrage . In den bislang bekannten Systemen wie dem oben genannten Delphi werden nunmehr graphische Objekte zugeordnet. Diese können dem gesamten Abfrageergebnis zugeordnet sein, meist in Form einer tablellarisch-textuellen Darstellung. Sie können auch einer Zeile zugeordnet sein, die über einen (sichtbaren oder unsichtbaren) Navigator bestimmt wird. Dabei steht jedes Graphik-Objekt in dem Generatorsystem für eine zur Laufzeit anzulegende Instanziierung der zugehörigen Klasse; die Anzahl der Instanziierungen ist also zur Erstellungszeit vorbestimmt.
Bei der Benutzung der Erfindung hingegen wird im einfachsten Fall einer Zeile einer Ergebnistabelle eine Klasse zugeord- net; und zur Laufzeit wird sodann für jede Zeile ein Objekt der Klasse instanziiert . In dem Generatorsystem wird sodann für jede Klasse ein Objekt angelegt und prototypisch auf der
graphischen Oberfläche gezeigt, so daß der Bediener die Verknüpfung der Objekte eingeben kann. Die eingegebenen Verknüpfungen werden in einer Tabelle wie oben dargestellt abgelegt, bis das Generatorsystem die Anwendung erzeugt und dann bevorzugt in Anweisungen der zugehörigen Programmiersprache umgesetzt, so daß Code ähnlich dem in Fig. 1 und Fig. 2 entsteht. Häufig werden dabei zwei oder mehr Objekte prototypisch angelegt werden, um Bezüge untereinander darstellen zu können. Dies wäre in dem obigen Beispiel eine mögliche Möglichkeit der Darstellung gewesen, in dem ein Objekt der Klasse ' aPanel ' zunächst mit der Kopfzeile versehen wird, sodann der Rest durch ein Panel ausgefüllt wird und in dieses Panel ein weiteres Objekt der Klasse 'aPanel' eingefügt wird. Dieser Vorgang wird von dem GeneratorSystem erkannt und es wird nach der Bedingung gefragt, unter der diese Plazierung erfolgen soll. Die Aktion selber ist durch die 'drag-and-drop' Operation in dem Generatorsystem selbst bereits festgelegt, falls keine Mehrdeutigkeit für die verwendeten Spalten besteht. Hierzu ist anzumerken, daß in tatsächlichen Anwendungen die Methode bevorzugt für Verknüpfungen von Tabellen angewendet wird, die in der Terminologie der Datenbanken häufig als Referenz ('foreign key') bezeichnet werden. Die obige Tabelle würde die zweite Spalte als Schlüssel und die dritte als Referenz auf dieselbe Tabelle darstellen. In diesen Fällen sind die möglichen
Beziehungen der Objekte bereits über die Datenbankstruktur vordefiniert.
In dem Beispiel und in den meisten Anwendungsfällen werden
Paare von Objekten gebildet, auf eine Bedingung hin überprüft und gegebenenfalls einer Aktion zugeführt. Es ist aber durchaus möglich, nur einzelne Objekte oder Tripel oder andere n- Tupel zu bilden. Im obigen Beispiel könnte genausogut der übergeordnete Behälter (das Layouter-Objekt) als globale Variable angesehen werden und demnach die zweite Zeile der Tabelle nicht auf Paare von Objekten, sondern nur auf alle Objekte einmal anzuwenden sein. Dies ist als bevorzugte Ausprägung anzusehen. Eine Anwendung von Tripein oder mehr-
dimensionalen n-Tupeln ist immer dann sinnvoll, wenn ein Layout-Manager entsprechende Zuordnungen zuläßt. In dem Beispiel waren die Objekte der Einfachheit halber als 'Button' definiert, so daß die Darstellung der Baumstruktur eher grob und unbeholfen erscheint. Selbstverständlich können die Objekte auch als graphische Symbole dargestellt werden und damit eine wesentlich dichtere Packung zulassen. Auch kann ein Objekt ein Piktogramm enthalten, das datenabhängig ausgewählt wird. Zudem ist es denkbar, daß aus einer Zeile mehrere Objekte unterschiedlicher Klassen erzeugt werden. Gerade in diesen Fällen ist es sinnvoll, daß die oben gezeigte Tabelle in den ersten beiden Spalten die Klasse auswählt und so sowohl die Bedingung als auch die Aktion von der Klasse des Objekts abhängig macht.
In einer Weiterbildung der Erfindung wird nicht nur die Anordnung der graphischen Objekte durch eine bevorzugt in Programmcode übersetzte Tabelle definiert. Vielmehr werden auch die Aktionen des Benutzers, insbesondere solche durch Ziehen und Loslassen ('drag-and-drop'), spezifiziert. In den bekannten Generatorsystemen sind die graphischen Objekte vorbestimmt, so daß der Benutzer der Systeme die Aktionen als Methoden programmiert, die den entsprechenden Ereignissen zugeordnet sind. Dies ist bei der Anwendung der vorliegenden Erfindung weder möglich noch notwendig.
Allerdings ist auch hier eine Lösung über eine Regel-Aktion- Tabelle gegeben. Eine solche Tabelle könnte lauten:
Drag Drop Aktion aPanel :x aPanel :y y. setCallee (x. getNu ber () )
Damit wird erreicht, daß bei jedem Objekt 'x', welches auf das Objekt 'y' gezogen und dort losgelassen wird, die Nummer von 'x' als neue Nummer des Anrufenden in der Varablen 'hisNumber' (Zeile 83) abgelegt wird. Fast immer wird es notwendig sein, durch eine 'redraw' Nachricht einen Neuaufbau
der Anzeige zu veranlassen. Ob die Aktion nun als Methode der 'drop' -Klasse oder sogleich als Datenbankbefehl 'UPDATE...' spezifiziert wird, ist dem Fachmann bei der Gestaltung eines entsprechenden Generatorsystems überlassen. Auch ist eine Erweiterung möglich, bei der die Tabelle nicht nur die Typen, sondern auch die Art des Ereignisses aufführt:
Durch die Erfindung ist es möglich, aus jeder Zeile der Ergebnistabelle ein oder mehrere Objekte zu erzeugen. Deren graphische Anordnung wird dann prototypisch festgelegt, und die Anordnung der Objekte wird letztlich erst während der Laufzeit festgelegt. Die gleiche Methodik ist für das Ver- halten bei Ereignissen anwendbar.