Draw2d Projektarbeit Software Engineering 12.11.2003 Von Olga Kiefel und Tobias Gunkel.
-
Upload
jannike-readling -
Category
Documents
-
view
107 -
download
0
Transcript of Draw2d Projektarbeit Software Engineering 12.11.2003 Von Olga Kiefel und Tobias Gunkel.
Draw2dProjektarbeit Software Engineering
12.11.2003Von Olga Kiefel und Tobias Gunkel
Was ist Draw2d? - 1
Entsprang dem GEF-Projekt für Eclipse (Model – View – Controller) und ist im Lieferumfang von GEF enthalten
Draw2d kann zusammen mit SWT auch außerhalb von Eclipse genutzt werden
Erweiterung von SWT: bietet die Möglichkeit komplexe, zusammengesetzte grafische Komponenten zu erstellen
Beispiel:
Das LightweightSystem Um mit Draw2d arbeiten zu können, muss ein
Objekt der Klasse LightweightSystem erzeugt werden.
Grundgerüst von Draw2dimport org.eclipse.swt.widgets.Display;import org.eclipse.swt.widgets.Shell;import org.eclipse.draw2d.*;public static void main(String[] args) {
Display disp = new Display();Shell shell = new Shell(disp);/* Dispatcher, UpdateManager und Root-Figure werden vom LWS erzeugt./ * Lediglich der Canvas muss übergeben werden (hier unsere Shell) */LightweightSystem lws = new LightweightSystem(shell);// Diese Figure wird als Container für weitere Figures benutztIFigure contents = new Figure();// Container-Figure wird Inhalt des LWS und Kind der Root-Figurelws.setContents(contents);Figure rect = new RectangleFigure();contents.add(rect);
shell.open();while(!shell.isDisposed()) {
if(!disp.readAndDispatch()) disp.sleep();}disp.dispose();
}
Figures – Die Hauptelemente Grafische Elemente (Figures) implementieren das Interface
IFigure Jede Figure kann als Behälter für weitere Figures dienen Hierarchie von Figures Root-Figure des LightweightSystems ist die Wurzel der Hierarchie Kinder einer Figure werden intern in einer Liste gehalten Einfügen eines Kindes in die Liste entweder mittels
IFigure.add(IFigure child): Einfügen ans Ende der Liste oder IFigure.add(IFigure child, int index): An Position índex einfügen
Nachträgliche Änderung der Position nur durch Entfernen und erneutes Einfügen
Gezeichnet wird beginnend mit der ersten Figure der Liste (mit Unterelementen), zum Schluss wird das letzte Element der Liste gezeichnet
Überlappen zwei Kinder, ist das Kind mit höherem Index vorne
Die Hierarchie der Figure-Objekte
2
RectangleFigure
Figure rect = new RectangleFigure();
rect.setBounds(new Rectangle(200,200,50,50));
root.add(rect);
Rechteck mit Farbe und Text
Figure rect = new RectangleFigure()
rect.setBounds(new
Rectangle(200, 200, 50, 50));
Label lab = new Label("Beispiel");
rect.add(lab);
rect.setBackgroundColor(ColorConstants.blue);
root.add(rect);
Beispiel: ImageFigure
Image image = new Image(null, „bild.gif");
ImageFigure imf = new ImageFigure(image);
Konstruktur von Image verlangt ein Device und den Pfad des Bildes
Ist Device null, wird der Bildschirm genommen Das Bild wird in einer ImageFigure gezeigt
Text mit Bild
Label lbl = new Label("Beispiel", image);// Bild unten, Text oben anzeigenlbl.setTextPlacement(PositionConstants.EAST);
Dem Konstruktur wird der Text und das Bild übergeben setTextPlacement verändert die Position von Bild und Text Die Position bestimmt man mit den in PositionConstants
definierten Konstanten NORTH, SOUTH, WEST, EAST IFigure.setBackgroundColor setzt die Hintergrundfarbe Analog setzt setForegroundColor die Textfarbe
Polyline und Polygon
Polyline-Objekte sind geschlossene Linienzüge Unterschied Polygone zu Polyline: Polygon ist gefüllt Übergabe der Stützpunkte entweder einzeln durch
Polyline.addPoint(Point p) oder mittels setPoints(PointList pl)
Polygon/Polyline verwendet nicht die Werte, die mit setLocation oder setBounds übergeben wurden, sondern nur die Koordinaten der Punkte um Poly-Objekt nachträglich zu bewegen, muss jeder Punkt einzeln bewegt werden (oder die Klasse abgeleitet und setBounds überschrieben werden) kann nicht in LayoutManagern verwendet werden
Beispiel zu Polygon
Polygon poly = new Polygon();
poly.addPoint(new Point(20,20));
poly.addPoint(new Point(60,20));
poly.addPoint(new Point(60,40));
poly.addPoint(new Point(10,40));
Connections Verbinden zwei Figures durch eine Linie Klasse, die dies tut, heißt
PolylineConnection Aussehen der Linie kann man durch
Router beeinflussen Anfangs- und Endpunkt der
Verbindungslinie müssen über Anchors bestimmt werden (Connection.setSourceAnchor und Connection.setTargetAnchor)
Beispiel:PolylineConnection conn = new PolylineConnection();
conn.setSourceAnchor(new ChopboxAnchor(rect1));
conn.setTargetAnchor(new ChopboxAnchor(rect2));
Decorations PolygonDecoration oder PolylineDecoration können an
eine Connection angefügt werden Eine Decoration hat standardmäßig das Aussehen eines
Dreiecks Ändern des Umrisses durch Übergabe einer Liste von
Punkten mit der Methode PolygonDecoration.setTemplate(PointList pl)
Connection.setTargetDecoration(PolygonDecoration) setzt Decoration ans Ende der Verbindungslinie, mit setSourceDecoration an Anfang der Linie
Beispiel:PolygonDecoration deco = new
PolygonDecoration();
// Umriss einer Raute durch PointList definierenPointList points = new PointList();points.addPoint(0, 0); points.addPoint(-1, 3);points.addPoint(-2, 0); points.addPoint(-1,-1);
// Umriss der Dekoration änderndeco.setTemplate(points);connection.setTargetDecoration(deco);
Locator Bestimmt eine Position auf der Verbindungslinie Kann genutzt werden, um eine Figure an der Linie
anzuzeigen (Connection.add(IFigure f, Locator l) Mehrere Klassen implementieren das Interface Locator,
die wichtigsten sind: ConnectionEndpointLocator:
Je nach Wert des zweiten Parameters im Konstruktur bestimmt Locator Anfangs- (false) oder Endposition (true) der Connection
Ein Offset kann der Position hinzugefügt werden (uDistance, vDistance)
MidpointLocator: bestimmt die Mitte der Connection
Beispiel:
ConnectionEndpointLocator targetLocator =new ConnectionEndpointLocator(connection, true);
//Entfernung vom Rechteck entlang der VerbindungslinietargetLocator.setUDistance(40);// vDistance = Entfernung von der Verbindungslinie bei// -45°–45° o. 135°-225°: auf vertikaler Achse oder bei// 45°-135° o. 225°-315°: auf horizontaler AchsetargetLocator.setVDistance(100);Label label = new Label("Label");// Label an die mit Locator bestimmte Stelle setzenconnection.add(label, targetLocator);
vDistance in Abhängigkeit des Verbindungswinkel:
vDistance = vert. Achse
vDistance = hor. Achse
Router Ohne weitere Angaben verwendet
PolylineConnection eine gerade Linie Aussehen der Verbindung kann mit
Routern geändert werden FanRouter und
BendpointConnectionRouter können geschachtelt werden (FanRouter.setNextRouter)
Router im Überblick:
Beispiel
. . .Definition einer Connection connection. . .BendpointConnectionRouter router =
new BendpointConnectionRouter();connection.setConnectionRouter(router);ArrayList list = new ArrayList();// Ecke bei absoluter Koordinate (20, 20)list.add(new AbsoluteBendpoint(20, 20));// Liste der Bendpoints für connection benutzenconnection.setRoutingConstraint(list);
ToolTips
Werden angezeigt, wenn die Maus längere Zeit über einer Komponente schwebt
Sollen weitere Information zur Komponente liefern Unter SWT nur textuelle ToolTips Schon das Interface IFigure bietet die Methode
zum setzen von ToolTips an Jede grafische Komponente in Draw2d unterstützt
ToolTips
Beispiel 1: normaler ToolTip mit Text
. . .kreis.setToolTip(new
Label("Dies ist ein ToolTip!"));. . .
Beispiel 2: erweiterte Möglichkeiten eines Draw2d ToolTip
ImageFigure imageFig = new ImageFigure();imageFig.setImage(new Image(null, "tool.jpg"));ellipse.setToolTip(imageFig);
Nachrichtenverarbeitung durch Listener
Jede Figure kann Listener mit Figure.addXYZListener einbinden um Events zu behandeln
Listener von Draw2d nicht kompatibel mit denen von AWT oder SWT
Listener sind Interfaces alle Methoden müssen implementiert werden
Um Arbeit zu sparen gibt es Stubs (ähnlich den SWT-Adaptern, siehe Beispiel)
Die wichtigsten Listener AncestorListener:
Methoden behandeln das Einfügen, Entfernen und Bewegen einer übergeordneten Figure (ancestor).
FigureListener: Methode figureMoved wird aufgerufen, wenn Figure bewegt
wurde MouseListener:
Methoden werden aufgerufen bei Maustastendruck, Loslassen der Taste wurde Doppelklick
MouseMotionListener: Methoden zur Reaktion auf Mausbewegungen über der Figure,
Verlassen oder Eintreten in die Figure. Bewegung der Maus mit gedrückter Taste durch mouseDragged
gesondert behandelt KeyListener:
Methoden werden aufgerufen, wenn Taste auf Keyboard gedrückt oder losgelassen wurde
Beispiel:class DragAndDrop {private final Point oldPos = new Point(); public DragAndDrop() { owner.addMouseListener(new MouseListener.Stub() {
public void mousePressed(MouseEvent me) { me.consume(); oldPos.x = me.x; oldPos.y = me.y;}
});owner.addMouseMotionListener(new MouseMotionListener.Stub() {
public void mouseDragged(MouseEvent me) { Dimension diff =
(new Point(me.x, me.y)).getDifference(oldPos); Figure owner = (Figure)me.getSource(); Point newPos =
owner.getLocation().getTranslated(diff); owner.setLocation(newPos); oldPos.x = me.x; oldPos.y = me.y;
}}); }}
Layout-Manager Problem: Position und Größe der Kinder einer Figure
äbhängig von Größe der Figure Bounds müssen zur Laufzeit gesetzt werden Layout-Manager bieten genau diese Funktionalität LayoutManager können durch die Methode
IFigure.setLayoutManager jeder Figure zugeordnet werden
Standard LayoutManager einer Figure ist das null-Layout; hierbei werden die mit setBounds und setLocation gesetzten Werte benutzt
Einige Layouts benötigen ein Constraint-Objekt (Anordnungsvorschrift) für jedes der Kinder
setzen beim Einfügen durch Figure.add(IFigure child, Object constraint) oder nachträglich durch LayoutManager.setConstraint(IFigure figure, Object constraint)
XYLayout
Ähnlich dem null-Layout-Manager Unterschied: Position wird als Constraint
übergeben Nur wenn die Constraints einer Figure null
sind, werden die mit setBounds gesetzten Werte genutzt
Beispiel:LayoutManager layout = new XYLayout();figure.setLayoutManager(layout);. . .// fügt Ellipse in figure ein an Koordinaten//(0, 0) mit Breite = 150 und Höhe = 100 // PixelFigure ellipse = new Ellipse();Rectangle bounds = new Rectangle(0,0,150,100);
figure.add(ellipse, bounds);
ToolbarLayout
Die Kinder der Figure werden entlang einer Hauptachse (vertikal oder horizontal) angeordet
Dabei werden die Kinder standardmäßig an der Nebenachse auf die Größe des Vaters gestreckt
FlowLayout
Teilt die Zeichenfläche der Figure in Zeilen bzw. Spalten auf Die Unterelemente der Figure werden nun von links nach
rechts bzw. von oben nach unten angeordnet Ist eine Zeile/Spalte aufgefüllt, wird am Anfang der
nächsten angefügt
Beispiel:
LayoutManager layout = new FlowLayout();
figure.setLayoutManager(layout);
. . .
figure.add(new RectangleFigure());
figure.add(new Ellipse());
figure.add(new Button("Button"));
StackLayout
Jedes Unterelement wird auf die Breite und Höhe seines Vaters gestreckt
Kinder mit höherem Index in der Liste der Vater-Figure werden beim Zeichnen weiter nach vorne gesetzt
BorderLayout
Teilt die Zeichenfläche der Figure in die Regionen Top, Bottom, Left, Right und Center ein
Je nach Region, werden die Kinder auf einer Achse gestreckt
Das Center-Objekt bekommt den verbleibenden Platz in der Mitte, nachdem die Randbereiche besetzt wurden
In welcher Region ein Kind angezeigt werden soll, muss als Constraint übergeben werden
Beispiel:
BorderLayout layout = new BorderLayout();figure.setLayoutManager(layout);// Rechtecke top, bottom, left, right und center anlegen. . .figure.add(top, BorderLayout.TOP);figure.add(bottom, BorderLayout.BOTTOM);figure.add(left, BorderLayout.LEFT);figure.add(right, BorderLayout.RIGHT);figure.add(center, BorderLayout.CENTER);
Delegating Layout
Platzierung durch ein Locator-Objekt, das mittels einer relocate-Methode die Position und Größe eines Kindes bestimmt
Locator-Objekt muss Interface Locator implementieren und als Constraint übergeben werden
Positionierung und Größe der Kinder können von verschiedenen Faktoren abhängig gemacht werden (z.B. gewählter Ansichtsmodus)
Beispiel:
LayoutManager layout = new DelegatingLayout();figure.setLayoutManager(layout);. . .Figure rect = new RectangleFigure();Locator locator = new Locator() {
public void relocate(IFigure target) {target.setBounds(new Rectangle(30, 20, 50, 50));
}});figure.add(rect, locator);
Borders
Viele Grafikkomponenten werden ohne Umrandung angezeigt
Mit IFigure.setBorder kann für jedes Objekt einer Klasse, die IFigure implementiert, ein Rand eingefügt werden
Abmessungen hängen von der Größe der Figure ab, die entweder mit setBounds() oder durch einen LayoutManager gesetzt werden
Innenraum-Abmessungen über getInsets() Erstellen neuer Ränder durch Ableiten der Klasse
AbstractBorder und Implementierung der Methoden getInsets() und paint()
Einige Borders:
Beispiel FrameBorder:
Label lbl = new Label("FrameBorder");lbl.setBorder(new FrameBorder("FrameBorder"));
Beispiel SchemeBorder:
Label lbl = new Label("SchemeBorder2");Color[] highlight = {ColorConstants.blue, ColorConstants.red};Color[] shadow = {ColorConstants.white, ColorConstants.red};lbl.setBorder(new SchemeBorder(new
SchemeBorder.Scheme(highlight, shadow)));
Thumbnails dienen als Vorschau von Grafikelementen
(Figures) Abbild der Quelle wird auf Größe des
Thumbnails skaliert. Das Verhältnis von Breite zu Höhe bleibt erhalten
Thumbnail wird automatisch an Änderungen der Quelle angepasst
Ein Thumbnail sollte auf keinen Fall ein Element der Figure sein, die von dem Thumbnail als Vorschau angezeigt werden soll. Obwohl keine Fehlermeldung erscheint, versucht sich das Thumbnail selbst zu zeichnen
Wird mit 100% CPU-Auslastung bestraft
Beispiel:
import org.eclipse.draw2d.parts.Thumbnail;. . .Figure ellipse = new Ellipse();ellipse.setBounds(new Rectangle(20,20,50,50));
. . .Thumbnail tn = new Thumbnail(root);. . .
ScrollableThumbnail ScrollableThumbnail zeigt im Thumbnail
ein Auswahlrechteck an, mit dem die Ansicht des Quellfensters geändert werden kann
Konstruktor erwartet Viewport einer ScrollPane
ScrollableThumbnail darf nicht als Unterelement einer Figure eingefügt werden, die von dem Thumbail angezeigt werden soll
Beispiel:
import org.eclipse.draw2d.parts.ScrollableThumbnail;. . .// Eine ScrollPane zum Anzeigen der FigureScrollPane scroll = new ScrollPane();. . .// neues Thumbnail, bei Auswahl eines Bereichs im
Thumbnail // soll der Viewport der ScrollPane den neuen Bereich
anzeigenScrollableThumbnail thumb =new ScrollableThumbnail(scroll.getViewport());// Das Thumbnail soll figure mit allen Unterelementen als// Vorschau anzeigen thumb.setSource(figure);