FOPRA Systementwicklungsprojekt Konzeption und Realisierung des Editor Frameworks Visual Shape Thomas Maier [email protected] Betreuer : Peter Braun, Oscar Slotosch Technische Universität München Lehrstuhl Prof. Broy Version : 1.6 Datum : 12.05.99 1 MOTIVATION 3 2 KONZEPTION 3 2.1 2.2 2.3 2.4 2.4.1 2.4.2 2.4.3 2.4.4 2.5 2.5.1 2.5.2 2.5.3 2.5.4 2.6 WHITE BOX FRAMEWORK ÜBERSICHT ÜBER DAS UMFELD VON VISUAL SHAPE INTERNE ARCHITEKTUR VON VISUAL SHAPE DIE GRAPHISCHEN OBJEKTE DAS GRAPHISCHE OBJEKT STANDARD AREAOBJEKT STANDARD LINEAROBJEKT GOMANAGER, DIE VERWALTUNGSZENTRALE DER GRAPHISCHEN OBJEKTE EVENT HANDLING EVENT LAYER SELECTION EVENT LAYER CONTRUCTION EVENT LAYER BEISPIELE ZUR VERDEUTLICHUNG DER EVENT MECHANISMEN LAYOUT MANAGER 3 4 5 7 8 8 8 9 10 10 11 12 13 13 3 ANWENDERÜBERSICHT 14 3.1 3.2 3.3 14 14 14 WAS KANN DAS FRAMEWORK ? WIE ERSTELLE ICH EINEN NEUEN EDITOR ? EIN WIZARD ZUR ERSTELLUNG EINES NEUEN EDITORS 4 LITERATUR 15 5 ANHANG 15 5.1 5.2 15 17 EVENT LAYER UML DIAGRAMME 2 1 Motivation Die Erfassung und Vermittlung von Wissen orientiert sich zunehmend am Bild. Komplexe Zusammenhänge können durch visuell strukturierte und organisierte Darstellungen vereinfacht werden. Genau hier setzt Visual Shape an. Es soll dem Anwender helfen die ständig wachsende Datenflut zu visualisieren und damit komplexe Zusammenhänge schneller erfaßbar zu machen. Die Visualisierung von Daten stellt in der Praxis oft ein großes Problem dar. Entscheiden ist die Aufbereitung der Daten und die Übersichtlichkeit dieser, deshalb möchte Visual Shape den Programmierer von lästigen Standardaufgaben befreien damit sich dieser auf die Strukturierung und somit der Übersichtlichkeit widmen kann. Nur so können dann auch die komplexen zusammenhänge veranschaulicht werden.(und gewinn aus einer visualisierung gewonnen werden) 2 Konzeption VS soll keine Speziallösung darstellen sondern so flexibel wie möglich sich seinen Anforderungen anpassen. Damit verbunden ist das benutzte Baukastenprinzip, die Aufgabe des FrameWorks würden unterteilt und die einzelnen Komponenten durch Schnittstellen getrennt um sie austauschbar zu machen. Der Benutzer(hier der Ersteller eines Editors/Viewers) kann sich dann die benötigten Teile des FrameWorks aussuchen. Das folgende Kapitel sollen eine Übersicht über das Design und die über die Entwicklung des Frameworks geben. 2.1 White Box Framework Es gibt viele Definitionen und Unterteilungen des Begriffs „Framework“ [De89, JF88][RJ98]. Das hier vorgestellte Framework Visual Shape wurde als White box Framework entwickelt. Es bietet nicht nur eine klare Schnittstelle für den Anwender, sondern ermöglicht ihm auch durch Dokumentation und klare Strukturen, selbst Änderungen und Weiterentwicklungen durchzuführen. Daher ist es unverzichtbar, klare Schnittstellen zu definieren um die Kompatibilität zu gewährleisten. Jede Änderung dieser „Frameworkschnittstelle“ würde alle Anwender betreffen. Ein weiterer Punkt ist ,das Framework so flexibel und erweiterbar wie möglich zu gestalten, um möglichst viele der Anforderungen der Entwickler zu erfüllen. Dies geschah durch die Verwendung von unzähligen Design Patterns, die zusätzlich den Vorteil der besseren Dokumentation und dadurch Verständnis bei den Anwendern für das Framework schaffen. Die Vorteile eines solchen Frameworks sind nicht nur die schnellere Entwicklung einer Anwendung, sondern auch ihre ähnliche Struktur, mit der die Wartung und die Konsistenz verbessert werden. 3 2.2 Übersicht über das Umfeld von Visual Shape DatenTypEditor STD Editor UML Editor Visual Shape Java2D API Swing Java AWT Java 2.0 Abbildung 2.2-1 Das Framework wurde komplett mit JDK1.2(Java 2.0) entwickelt. Insbesondere wurden die Packages: Swing, Java.AWT und die Java2D API, die sich im Packages java.awt.geom befindet, verwendet. Für die Anwendung von Visual Shape sind ausschließlich die APIs, die mit Java2.0 ausgeliefert werden, nötig. Da nun das Umfeld des Framework geklärt ist werden in den folgenden Kapitel die Komponenten von Visual Shape vorgestellt und anschließend versucht das Zusammenspiel dieser Komponenten zu verdeutlichen. 4 2.3 Interne Architektur von Visual Shape Das Framework besteht aus verschiedenen Komponenten und Managern. Die vier wichtigsten Komponenten sind: • Die Graphischen Objekte mit ihrem Verwaltungsmanager • Die EventLayer die durch den EventManager angesprochen und in ihrer Reihenfolge verändert werden können • Die Graphischen Hilfsobjekte, die für die zwei erstgenannten zu Verfügung stehen. Ein typisches Beispiel sind die Handles der Graphischen Objekte oder eine Selektionbox für den Selektion Event Layer • Der Auto Scroll Panel, der die Schnittstelle zum Anwender herstellt und diesem eine komfortable Anbindung ermöglicht, z.B. in einem Visuellen GUI Editor. Die folgende Abbildung soll die Zusammenhänge verdeutlichen. Handel Manager Layout Komponente Scroll Panel Kernel GO Manager Graphische Objekte Event Manager Event Layer Abbildung 2.3-1 Architektur von Visual Shape Der Kernel von Visual Shape ist die Zentrale aller Vorgänge. Diese Schaltzentrale koordiniert die einzelnen Komponenten. Die Manager kapseln die eigentlichen Datenstrukturen und beantworten Anfragen selbständig. Der Scroll Panel dient als Schnittstelle zum Benutzer der Anwendung. Durch die Definition von Schnittstellen zwischen den einzelnen Komponenten sind diese 5 ohne Probleme auszutauschen, wobei am Kernel keine Änderungen nötig sind. Durch dieses „Baukastenprinzip“ ist das Framework sehr flexibel und kann sich, durch Auswechslung von Komponenten, an unterschiedlichste Anforderungen anpassen. Der reine Anwender des FrameWork sollte zwar ein Verständnis für den internen Aufbau besitzen, es ist aber nicht nötig diesen ins Detail zu kennen. Durch die Aufteilung der Aufgaben an die verschiedenen Komponenten könnte der interne Aufbau strukturiert werden. Dadurch wird es auch für Entwickler einfacher Änderungen durchzuführen. Als erstes sollen die graphischen Objekte und der dazugehörige Manager(GO Manager) erklärt werden 6 2.4 Die Graphischen Objekte Die graphischen Objekte stehen im Mittelpunkt des Frameworks. Bei den graphischen Objekten sind nur wenige Methoden abstract deklariert. Alle anderen Methoden bauen auf diesen auf. BasicFigure (from figures) selected : boolean = false BasicFigure() draw() getBounds() move() setSize() getHandles() select() unselect() contains() getLocation() setLocation() getWidth() getHeight() getTop() getBottom() getRight() getLeft() getTopLeft() getTopRight() getBottomLeft() getBottomRight() VShape (from figures) VShape() reshape() setSize() BasicAreaFigure BasicLinearFigure (from figures) (from figures) BasicAreaFigure() draw() getBounds() move() reshape() getHandles() BasicLinearFigure() draw() getBounds() move() reshape() getHandles() RectangleFigure (from figures) Abbildung 2.4-1 Der Ableitungsbaum der graphischen Objekte Zu den elementaren Methoden gehören getBounds(), draw() und move(). Alle anderen Methoden kann der Benutzer ohne weiteren Aufwand benutzen. Die entsprechenden Eigenschaften die ihm nicht zusagen, kann er durch überladen von Methoden korrigieren. Der Benutzer ist auch frei in der Entscheidung von welcher Klasse er ableitet um sein Graphisches 7 Objekt zu erstellen. BasicAreaFigure und BasicLinearFigure sind nur Vorschläge wie solche Figuren aussehen könnten. Im folgenden Kapiteln werden die einzelnen graphischen Objekte noch detaillierter vorgestellt. 2.4.1 Das Graphische Objekt Die einzelnen graphischen Objekte können sich auf weiteren Klassen abstützen. Dabei sollte aber darauf geachtet werden, daß Daten nicht mehrmals vorhanden sind. So ist es sicherlich sinnvoll sich auf den Klassen von Java2.0 im Package java.awt.geom abzustützen (siehe Abbildung 2.4-2). Diese bieten schon einen Großteil der benötigten Funktionen. Dabei ist es aber nicht nötig z.B. die Position zweimal zu speichern. Die Anfrage getPosition() sollte vielmehr an das assoziierte Objekt weitergeleitet werden. Dadurch wird die Konsistenz bei den Graphischen Objekte gefördert und zweitens Speicherplatz gespart. Java 2.0 Visual Shape Java2DAPI.Shape Graphic Object GO Manager Abbildung 2.4-2 Beim erstellen eines neuen Figure ist eine der wichtigsten Entscheidungen von welcher der angebotenen Klassen abgeleitet werden soll, deshalb werden nun die zwei wichtigsten Klassen kurz vorgestellt. 2.4.2 Standard AreaObjekt Dieses Graphische Objekt kann für alle Figuren verwendet werden die eine Fläche beinhalten. Dabei ist die Form des neuen Objektes beliebig solange sie in ein Rechteck paßt. Es können vier/acht handels gewählt werden(links mit vier handels), die dazu dienen die Größe des Objektes zu verändern. Die Handels bauen auf der reshape() Methode auf deshalb sollte diese auf jeden Fall korrekt implementiert werden.(->Wizard?) 2.4.3 Standard LinearObjekt Dieses Objekt kann für viele Aufgaben benutzt werden. Es ist besonders dafür geeignet zwei Standard AreaObjekte zu verknüpfen und damit sich bei diesen als Listener anzumelden um bei Bewegungen der AreaObjekte sich entsprechen zu aktualisieren. Des weiteren können beliebige Symbole an den zwei Enden angebracht werden und die Figur kann beliebig viele Knickpunkte enthalten, die dann jeweils mit einem handel versehen werden. 8 2.4.4 GOManager, die Verwaltungszentrale der graphischen Objekte Durch die Verwendung eines Manager wird die eigentlich Datenstruktur der Graphischen Objekte gekapselt. Der Manager sollte die Konsistenz der Graphischen Objekte sicherstellen. Über ihn laufen allen Aufgaben die mit löschen, erzeugen und Auffinden/Selektion von Graphischen Objekten zu tun haben. Er ist auch für die Rückfragen an die Graphischen Objekte zuständig, z.B. ob ein Objekt nun wirklich gelöscht werden darf. Bei der Selektion/Deselektion von graphischen Objekten wendet er sich zusätzlich noch an den Handel Manager um die das erzeugen/löschen der handels anzustoßen. Dieser verwaltet die Handels wieder selbständig und ist nur über den GOManager zu erreichen. 9 2.5 Event Handling Bei der Konzeption und Realisierung würde diesem Punkt besonders viel Aufmerksamkeit geschenkt. Das Event Handling sollte die Erstellung eines neuen Editors nicht einschränken und auf der anderen Seite möglichst viel dem Benutzer abnehmen. Die Abbildung 2.5-1 zeigt das Modell und das Zusammenspiel der beteiligten Komponenten. Selecti on Figure 1 Canvas Event Layer (Construction Figure 1) Bouble Click and Key Pressed Event Single Click Event Layer (Selection) Event Double Click Event Event Single Click Figure 2 Event Layer (Construction Figure 2) Abbildung 2.5-1 Modell des Event Handlings Der Canvas soll die Zeichenfläche des Editor darstellen. Hier werden durch Benutzeraktionen die verschiedenen Events(siehe java.awt.Event.*) angestoßen. Der Event Manager bereitet diese auf und gibt sie an die einzelnen Event Layer weiter. Diese sind auf einem Stack angeordnet, die Reihenfolge kann der Benutzer in diesem Beispiel durch die Toolbar ändern. Nun kann jeder Layer für sich entscheiden ob er das angefallene Event konsumieren oder an den Event Mangaer zurückgeben will. Dieser korrespondiert alle ihm bekannten Layer bis das Ereignis konsumiert wird. Für zusätzliche Informationen sei auf die Bespiele im Kapitel 2.5.4 verwiesen. Nach diesem Überblick werden nun die einzelnen Komponente genauer erläutert. 2.5.1 Event Layer Durch das FrameWork wird den einzelnen Event Layern folgende Schnittstelle angeboten : 10 public void mousePressed(MouseEvent e, Point2D.Double p2d) public void mousePressed(MouseEvent e, Point2D.Double p2d, BasicFigure bf) public void mouseDragged(MouseEvent e, Point2D.Double scr, Point2D.Double dest) public void mouseReleased(MouseEvent e, Point2D.Double scr, Point2D.Double dest) public void mouseReleased(MouseEvent e, Point2D.Double scr, Point2D.Double dest, BasicFigure bf) public void mouseSingleClick(MouseEvent e, Point2D.Double p2d) public void mouseSingleClick(MouseEvent e, Point2D.Double p2d, BasicFigure bf) public void mouseDoubleClick(MouseEvent e, Point2D.Double p2d) public void mouseDoubleClick(MouseEvent e, Point2D.Double p2d, BasicFigure bf) Dabei würde darauf geachtet die einzelnen Ereignisse möglichst breit aufzufächern, damit die einzelnen Event Layer nicht zu groß und unübersichtlich werden. Dies hilft auch dem Anwender der sich nicht um die als Parameter mitgelieferten Informationen kümmern muß. 2.5.2 Selection Event Layer Der Selection Event Layer ist ein Bestandteil des FrameWorks. Er sorgt für die Selektion und die Verschiebung der Figuren. Mann kann diesen Layer fest als obersten im Layer Stack festlegen und stellt somit sicher daß jederzeit eine Selektion und Bewegung der Graphischen Objekte möglich ist. Wenn eine individuellere Interpretation der Benutzeraktionen entstehen soll, ist aber von diesem Schritt abzuraten. Das Folgende Flußdiagramm soll den Selektion Layer nochmals im Zusammenhang darstellen. 11 Selektion Event Layer -> Mouse Pressed Mouse Pressed On a Handle ? Yes No On a Figure ? Is Figure Selected ? Yes No Is Shift Key Pressed ? No Yes Select Figure Yes No Deselect all Figures Select Figure deselect all Figures new SelectionRectangle Move_Event_Layer to the Top Save Handle Handle_Event_Layer to the Top Mouse Dragged draw Slection Rectangle with new Coordinates move selcted Figures redraw() move saved Handle Mouse Released Select all Figures in the Selection Rectangle remove Selection Rectangle redraw() setMove_Event_Layer_Back redraw() remove saved_handle setHandle_Event_Layer_Back redraw() Abbildung 2.5-2 2.5.3 Contruction Event Layer Erzeugung neuer graphischer Objekte steht ein Layer(Construction Layer) zu Verfügung, der die Benutzereingaben entsprechend interpretiert. Hier sollte zusätzlich eine Methode newFigure() definiert werden um die Wiederverwendbarkeit sicherzustellen. Ansonsten ist der Benutzer an dieser Stelle nicht eingeschränkt. 12 2.5.4 Beispiele zur Verdeutlichung der Event Mechanismen Neue Komponente anlegen: 1.) Der Benutzer wählt „Neue Komponente anlegen“(z.B. entsprechender Toolbar Button). Dadurch wird der entsprechende ConstructionsLayer im FrameWork auf aktiv gesetzt. 2.) Doppelklick auf den Canvas. Beim aktiven Layer wird die Methode doubleClick(Event) aufgerufen. Eine neue Komponente wird erzeugt.(falls an dieser Stelle noch keine vorhanden ist) Selektieren einer Komponente: 1.) Der Benutzer wählt „Selektieren“ (z.B. entsprechender Toolbar Button). Dadurch wird der SelectionLayer im FrameWork auf aktiv gesetzt. 2.) Einfacher Maus Klick auf den Canvas. Befindet sich an dieser Stelle eine Objekt wird es in eine Liste eingetragen (falls es noch nicht in dieser Liste ist), falls nicht wird die Liste gelöscht. Anschließend werden die Bounding Points Dargestellt und in einer Liste abgespeichert. Bounding Points sind primitive graphische Objekte, die sich darstellen können, eine Referenz auf ein graphisches Objekt(und sich auch bei diesen als Listener anmelden) haben und eine Boundingbox besitzen. Bewegen einer Komponente: 1.) Der Benutzer wählt „Selektieren“(z.B. entsprechender Toolbar Button). Dadurch wird der SelctionLayer im FrameWork auf aktiv gesetzt.(in diesem Beispiel nicht nötig) 2.) Wie bei 2. Selektieren folgend sind mouse Dragged events. Sollte kein Objekt selektiert sein wird ein Rechteck aufgespannt zur Mehrfachselektierung. Ansonsten werden alle selektierten Objekte um die entsprechenden Koordinaten verschoben und der Canvas neu gezeichnet. Größe einer Komponente verändern 1.) Die Komponente wird zunächst Selektiert(siehe oben) 2.) Der Benutzer wählt und zieht an einem Bounding Point. Es wird immer zuerst nach Bounding Points an der gewählten Stelle gesucht(bei den anderen Beispielen nicht erwähnt)bei diesem wird dann die Methode mouseDragged() aufgerufen. Durch die Referenz zu seiner Komponente wird diese in der Größe geändert. 2.6 Layout Manager Dadurch daß Layout Algorithmen oft sehr komplex sind, ist es sinnvoll diese vom Framework zu kapseln und von den graphischen Objekten unabhängig zu gestalten. Durch die Verwendung eines Stragiemusters [Gamma96] würde die Wiederverwendung und der Austausch der Layout Algorithmen, auch zur Laufzeit, sichergestellt. Die einzelnen Graphischen Objekte sind an den Algorithmus durch ein vordefiniertes Interface gebunden. Siehe dazu auch [Loetz99]. So ist es auf der einen Seite möglich mit mehreren Layout Algorithmen im selben Editor zu arbeiten und auf der anderen Seite ist es nicht nötig für jeden Algorithmus neue Graphische Objekte zu erstellen. ->Klaus Layout Manager als Beispiel 13 3 Anwenderübersicht 3.1 Was kann das FrameWork ? 3.2 Wie erstelle ich einen neuen Editor ? 3.3 Ein Wizard zur Erstellung eines neuen Editors FrameWork (4) Anwendersicht Welche Eigenschaften/Funktionen sollen die Graphischen Objekte haben ? Erfüllen vorhandene GO diese Bedingungen oder kann von diesen Abgeleitet werden ? Welche Interface müssen implementiert werden ? (Speichern, Beschriftung, Bounding) Ist ein default Construction Layer ausreichend ? Erstellen eines eigenen Event Layers. Wie soll das GO erzeugt werden ? Erzeugen des Editor Canvas. Die Event Layer mit z.B. einer Toolbar verknüpfen. Bei den action Events der Toolbar werden die Layer dann entsprechend im Canvas gesetzt. 14 4 Literatur [De89] [JF88] [O.Coplin] [RJ98] [Gamma96] [Loetz99] [TM99Info] [Mfow 97] L. Peter Deutsch. Design reuse and frameworks in the Smalltalk-80 system. In TED J. Biggerstaff und Alan J. Perlis, Hrsg., Software Reusability, 1989. Ralph E. Johnson und Brian Foote. Designing reusable classes. Journal of Object Oriented Programming, 1988. James O. Cpolin, Douglas C. Schmidt, Pattern Languages of Programming Design, Addison-Wesley Don Roberts, Ralph Johnson, „Patterns for Evolving FrameWorks“, erste Veröffentlichung in Patterns Languages of Program Design 3, AddisonWesley, 1998. Siehe auch http://www.cd.uiuc,edu/~droberts/evolve.html Erich Gamma, Richard Helm, Ralph Johnson und John Vlissides. Design Patterns, Addison-Wesley 1996, ISBN 0-201-63361-2 Layoutmechanismus für das Editor-Framework Heiko Lötzbeyer, Institut für Informatik, Technische Universität München, Internal draft of January 21, 1999. Informationen zu Visual Shape Thomas Maier, Institut für Informatik, Technische Universität München, 12. April, 1999. Martin Fowler, Analysis Patterns: Reusable Object Models. Addison Wesley 1997 5 Anhang 5.1 Event Layer 15 Selektion_Event_Layer -> Mouse Dragged Mouse Dragged draw Slection Rectangle with new Coordinates Move_Event_Layer -> Mouse Dragged Mouse Dragged move selcted Figures redraw() new move_Rectangle move this Handle_Event_Layer -> Mouse Dragged Mouse Dragged move saved Handle Abbildung 5.1-1 16 Selektion_Event_Layer -> Mouse Released Mouse Released Select all Figures in the Selection Rectangle remove Selection Rectangle redraw() Move_Event_Layer -> Mouse Released Mouse Released remove move_Rectangle setMove_Layer_Back redraw() setMove_Event_Layer_Back redraw() Handle_Event_Layer -> Mouse Released Mouse Released remove saved_handle setHandle_Event_Layer_Back redraw() Abbildung 5.1-2 5.2 UML Diagramme 17