Draw2d: Unterschied zwischen den Versionen

Aus Eclipse
Wechseln zu: Navigation, Suche
(ToolbarLayout)
K
 
(11 dazwischenliegende Versionen von einem anderen Benutzer werden nicht angezeigt)
Zeile 82: Zeile 82:
  
 
= Zeichnungsreihenfolge und Überlappung der Figuren =
 
= Zeichnungsreihenfolge und Überlappung der Figuren =
 +
Die Figuren bilden eine Baumhierarchie. Die Zeichnung fängt vom Wurzel des Baums an - das bedeutet, dass die Kinder-Objekte nach den Eltern-Objekten gezeichnet werden und stehen deswegen immer im Vordergrund zu ihren Eltern. Jede Figur verwaltet ihre Kinder in einer geordneten Liste. Die Reihenfolge, in der die Kinder gezeichnet werden, entspricht ihrer Reihenfolge in dieser Liste. Deswegen überlappen die Kinder mit dem größeren Index die mit dem kleineren.
 +
<br>
 +
Wenn die Kinder zu groß für die Zeichenfläche einer Eltern-Figur sind, werden sie am Rand der Eltern-Figur abgeschnitten.
 +
 
= Verbindungen und Routing =
 
= Verbindungen und Routing =
 
== Verbindungen und Anker ==
 
== Verbindungen und Anker ==
Zeile 311: Zeile 315:
 
<br>
 
<br>
 
Man sieht hier deutlich, wie der Muster definiert wird, und wie die automatische Rotation funktioniert. Bei der Definition des Templates muss man sich vorstellen, dass die Verbindungslinie waagerecht ist und der Anfang des Koordinatensystems am Endpunkt der Linie sich befindet. Die negative X-Richtung ist dann die Richtung zum Zentrum der Linie. Beim Zeichnen wird der Muster um den Winkel rotiert, den die Verbindungslinie (oder ihr letzter Abschnitt im Fall einer Polylinie) zu der X-Achse bildet.
 
Man sieht hier deutlich, wie der Muster definiert wird, und wie die automatische Rotation funktioniert. Bei der Definition des Templates muss man sich vorstellen, dass die Verbindungslinie waagerecht ist und der Anfang des Koordinatensystems am Endpunkt der Linie sich befindet. Die negative X-Richtung ist dann die Richtung zum Zentrum der Linie. Beim Zeichnen wird der Muster um den Winkel rotiert, den die Verbindungslinie (oder ihr letzter Abschnitt im Fall einer Polylinie) zu der X-Achse bildet.
 +
 +
= Rahmen =
 +
Mit der Methode ''setBorder'' des Interfaces ''IFigure'' kann man einer Figur einen Rahmen zuordnen. Für die Rahmen-Objekte ist das Interface ''Border'' definiert. Wie bei anderen wichtigen Elementen, gibt es auch von ''Border'' viele fertige Implementierungen, die sich äußerlich unterscheiden. Man könnte alle vorgefertigten Rahmentypen in drei Gruppen verteilen. Das sind
 +
* Einfache Linienrahmen (z.B. ''LineBorder'')
 +
* Rahmen, die nach GUI-Elementen (z.B. Buttons) aussehen, das heißt gesenkt oder erhöht aussehen (z.B. ''SimpleLoweredBorder'')
 +
* Rahmen mit einer Beschriftung (abgeleitet von ''AbstractLabeledBorder'')
 +
<br>
 +
Der Rahmen wird als letztes beim Zeichnen einer Figur augegeben. Deswegen ist er immer im Vordergrund im vergleich mit anderen Teilen der Figur. Die neue experimentelle Klasse ''AbstractBackground'' soll ermöglichen, auch im Hintergrund einer Figur die Teile des Rahmens zu zeichnen.
 +
<br>
 +
Mit der Klasse ''CompoundBorder'' kann man mehrere Rahmen kombinieren.
 +
 +
= Layer =
 +
''Layer'' ist ein spezieller Typ von Figuren. Die ''Layer'' sind transparent optisch und auch für die Ereignisse. Das bedeutet, dass die GUI-Ereignisse wie z.B. Maus-Ereignisse sowie die "Hit Tests" werden tranparent an hinteren Figuren geleitet. Die ''Layer'' sind dafür gedacht, explizit nur in den ''LayerPanes'' benutzt zu werden.
  
 
= Anordnungen (''Layouts'') =
 
= Anordnungen (''Layouts'') =
Zeile 357: Zeile 374:
 
contents.setLayoutManager(layout);
 
contents.setLayoutManager(layout);
 
</source>
 
</source>
 +
<br>
 +
Und so sieht jetzt der Output aus:
 +
<br>
 
<br>
 
<br>
 
[[Datei:dratva_1919_example10_draw2d.png]]
 
[[Datei:dratva_1919_example10_draw2d.png]]
 +
<br>
 +
<br>
 +
Die Zeile mit dem Aufruf von ''setStretchMinoxAxis'' sagt dem ''LayoutManager'', die Objekte in der X-Achs nicht zu dehnen. Wenn man diese Zeile weg lässt, sieht der Output so aus:
 +
<br>
 +
<br>
 +
[[Datei:dratva_1919_example10_1_draw2d.png]]
 +
<br>
 +
<br>
 +
Mit dem folgenden Code kann man die Richtung der Anordnung um 90 Grad drehen:
 +
<br>
 +
<source lang=java>
 +
ToolbarLayout layout = new ToolbarLayout();
 +
layout.setStretchMinorAxis(false);
 +
layout.setVertical(false);
 +
contents.setLayoutManager(layout);
 +
</source>
 +
<br>
 +
<br>
 +
Und so sieht es aus:
 +
<br>
 +
<br>
 +
[[Datei:dratva_1919_example10_2_draw2d.png]]
 +
<br>
 +
 +
[[Kategorie:Draw2d]]

Aktuelle Version vom 15. Juli 2010, 10:59 Uhr

Einführung

Draw2d ist ein auf Diagrammenzeichnung orientiertes Vektorgrafik-Toolkit für Eclipse. Es ist als Teil von GEF entstanden, kann aber unabhängig von GEF benutzt werden. Draw2d weist nicht so viele Möglichkeiten für eine komplizierte Grafikdarstellung auf, legt aber Akzent auf die in verschiedenen Diagrammentypen vorkommende Elemente wie z.B. rechteckige Blöcke mit Text oder Verbindungslinien jeglicher Art. Es bietet weiter die Möglichkeiten für eine automatische Anordnung der Elemente auf der Zeichnung sowie das sogenannte "Hit Testing" - die Erkennung des Elementes unter dem Mauszeiger.
Draw2d benutzt Standard Widget Toolkit (SWT, org.eclipse.swt) für das Rendering der Objekte.
Als Interface zwischen draw2d und SWT dient die Klasse org.eclipse.draw2d.LightweightSystem. Sie bietet die Möglichkeit, die draw2d-Objekte auf dem SWT-Canvas zu zeichnen, ohne das für die draw2d-Objekte OS-Ressourcen beansprucht werden (deswegen heißt die Klasse LightweightSystem).
Jedes sichtbare draw2d-Objekt ist eine Figur.

Packages

  • org.eclipse.draw2d - alle wichtigsten Klassen sind hier definiet.
  • org.eclipse.draw2d.geometry - Basisklassen für geometrische Objekte wie Punkte, Vektoren, Rechtecke usw.
  • org.eclipse.draw2d.graph - Klassen für die Graphendarstellung.
  • org.eclipse.draw2d.images
  • org.eclipse.draw2d.internal
  • org.eclipse.draw2d.parts - enthält im Moment eine Thumbnail-Figur. Das ist eine Figur, die eine andere Figur verkleinert darstellen kann.
  • org.eclipse.draw2d.text - diverse Klassen für die Textdarstellung.
  • org.eclipse.draw2d.widgets

Figuren (Figures)

Eine Figur in Draw2d ist alles, was das Interface IFigure implementiert, wobei es nicht empfohlen wird, in eigenen Klassen direkt dieses Interface zu implementieren, sondern eigene Klassen von existierenden Draw2d-Figuren abzuleiten.
Jede Figur ist ein Container für weitere Figuren. Man kann aus Figuren ganze Hierarchiebäume erzeugen. In der Praxis, für die Darstellung auf einem SWT-Canvas müssen alle Figuren sich in einem Baum befinden. Das Wurzelobjekt dieses Baums, das auch eine Figur ist, wird dem LightweightSystem übergeben.
Jede Figur hat bevorzugte Größe, minimale Größe und maximale Größe.
In der Methode paint muss eine Figur sich Zeichnen. Dafür hat sie die Methoden der abstrakten Klasse org.eclipse.draw2d.Graphics zur Verfügung.

"Hello world" in draw2d

In diesem Beispiel wird die Zusammenarbeit von SWT und draw2d demonstriert. Ausserdem sieht man hier, wie die Wurzelfigur für das LightweightSystem eingestellt wird und wie ein Figurenbaum entsteht.
In diesem Beispiel werden die SWT-Klassen Display und Shell benutzt. Weit SWT ausserhalb des Geltungsbereiches dieses Artikels ist, werden diese Klassen hier nicht weiter beschrieben. Siehe dazu die SWT-Dokumentation.

import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.draw2d.*;
 
public class draw2d_test {
 
	public static void main(String[] args) {
		Display display = new Display();
		Shell shell = new Shell(display);
 
		LightweightSystem lwSystem = new LightweightSystem(shell);
 
		IFigure contents = new Figure();
		LineBorder border = new LineBorder();
		border.setWidth(5);
		contents.setBorder(border);
 
		ToolbarLayout layout = new ToolbarLayout(false);
		layout.setSpacing(10);
		contents.setLayoutManager(layout);
 
		Label label = new Label("Hello world!!!");
		contents.add(label);
 
		shell.open();
 
		lwSystem.setContents(contents);
		while(!shell.isDisposed() )
		{
			if(!display.readAndDispatch() )
			{
				display.sleep();
			}
		}
 
		display.dispose();
	}
 
}


Das Output von diesem Beispiel sieht so aus:
Dratva 1919 example1 draw2d.png

In diesem Beispiel werden zwei Figuren erstellt, contents und label. Das label wird mit add an das contents angehängt, contents wird als Wurzelfigur im lwSystem gesetzt. Damit man die Wurzelfigur contents sehen kann, wird ihr ein dicker Rahmen hinzugefügt.

Zeichnungsreihenfolge und Überlappung der Figuren

Die Figuren bilden eine Baumhierarchie. Die Zeichnung fängt vom Wurzel des Baums an - das bedeutet, dass die Kinder-Objekte nach den Eltern-Objekten gezeichnet werden und stehen deswegen immer im Vordergrund zu ihren Eltern. Jede Figur verwaltet ihre Kinder in einer geordneten Liste. Die Reihenfolge, in der die Kinder gezeichnet werden, entspricht ihrer Reihenfolge in dieser Liste. Deswegen überlappen die Kinder mit dem größeren Index die mit dem kleineren.
Wenn die Kinder zu groß für die Zeichenfläche einer Eltern-Figur sind, werden sie am Rand der Eltern-Figur abgeschnitten.

Verbindungen und Routing

Verbindungen und Anker

Eine spezielle Art der Figuren sind die Verbindungen. Verbindungen müssen das Interface Connection implementieren, das das IFigure erweitert.
Diese Verbindungsfiguren stellen Verbindungslinien dar, die zwei Figuren miteinander verbinden. Der Verlauf einer solchen Linie wird von einem anderen Objekt - einem ConnectionRouter definiert.
Für die polygonartige Verbindungslinien existiert die Klasse org.eclipse.draw2d.PolylineConnection. Das ist die einzige Connection-Implementierung in draw2d. Diese Klasse wird auch im nächsten Beispiel verwendet.

 
	Label label1 = new Label("Label 1");
	LineBorder borderL1 = new LineBorder();
	label1.setBorder(borderL1);
	contents.add(label1);
 
	Label label2 = new Label("Label 2");
	label2.setBorder(borderL1);
	contents.add(label2);
 
	PolylineConnection connection = new PolylineConnection();
	connection.setSourceAnchor(new ChopboxAnchor(label1) );
	connection.setTargetAnchor(new ChopboxAnchor(label2) );
	contents.add(connection);


Dratva 1919 example2 draw2d.png



In diesem Beispiel sieht man, dass eine Verbindung zwei so genannte Anker braucht, um sicht richtig darzustellen. Ein Anker ist eine Implementierung des Interfaces ConnectionAnchor. Diese Anker werden nicht nur in PolylineConnection verwendet, sondern in jeder Connection-Implementierung. Die Methoden setSourceAnchor und setTargetAnchor sind nähmlich in diesem Interface definiert. Diese zwei Anker legen zwei Punkte fest, die von der Linie verbunden werden. Die Eigenschaften des hier verwendeten ChopboxAnchor werden im nächsten Beispiel besser demonstriert:

	Label label1 = new Label("Label 1");
	LineBorder borderL1 = new LineBorder();
	label1.setBounds(new Rectangle(10, 10, 100, 50) );
	label1.setBorder(borderL1);
	contents.add(label1);
 
	Label label2 = new Label("Label 2");
	label2.setBounds(new Rectangle(150, 150, 100, 50) );
	label2.setBorder(borderL1);
	contents.add(label2);
 
	PolylineConnection connection = new PolylineConnection();
	connection.setSourceAnchor(new ChopboxAnchor(label1) );
	connection.setTargetAnchor(new ChopboxAnchor(label2) );
	contents.add(connection);



Der Output von diesem Program sieht so aus:

Dratva 1919 example3 draw2d.png



Hier sieht man deutlich die Eigenschaften des in diesem Beispiel gewählten ChopboxAnchor. Die Linie wird zwischen Zentren der gewählten Figuren gezeichnet, wobei die Teile der Linie, die auf den Figuren selbst liegen, werden verborgen.

Neben dem ChopboxAnchor existieren in draw2d folgende vorgefertigten Implementierungen des ConnectionAnchor:

  • ConnectionAnchorBase - abstrakte Implementierung, die einen Listener-Mechanismus für die Verschiebung des Ankers anbietet.
  • XYAnchor - eine konkrete Implementierung, die eine feste Position für den Anker definiert, unabhängig von anderen draw2d-Objekten.
  • AbstractConnectionAnchor - abstrakte Basisklasse für alle Anker, deren Position von Eigenschaften einer Figur abhängig ist.
  • ChopboxAnchor - eine Implementierung von AbstractConnectionAnchor, die sich wie im obigen Beispiel verhält.
  • EllipseAnchor - auch eine Implementierung von AbstractConnectionAnchor, die ähnlich dem ChopboxAnchor ist. Der Unterschied ist die Art, wie der unsichtbare Teil der Linie festgelegt wird. Im Fall von EllipseAnchor ist es der der Ellipse, der in das Rechteck der Figur eingebettet ist, der die Grenze der Linie festlegt.



Wenn man das vorherige Beispiel auf folgende Weise modifiziert:

	Label label1 = new Label("Label 1");
	LineBorder borderL1 = new LineBorder();
	label1.setBounds(new Rectangle(10, 10, 100, 100) );
	label1.setBorder(borderL1);
	contents.add(label1);
 
	Label label2 = new Label("Label 2");
	label2.setBounds(new Rectangle(150, 150, 100, 100) );
	label2.setBorder(borderL1);
	contents.add(label2);
 
	PolylineConnection connection = new PolylineConnection();
	connection.setSourceAnchor(new EllipseAnchor(label1) );
	connection.setTargetAnchor(new EllipseAnchor(label2) );
	contents.add(connection);



sieht man, wir der EllipseAnchor funktioniert:

Dratva 1919 example4 draw2d.png



Die roten Kreise in diesem Bild sind nicht Teil der Figuren, sondern wurden auf dem Screenshot gezeichnet, um die Eingenschaften des EllipseAnchor darzustellen.

Im folgenden Beispiel wird eine freischwebende Linie mithilfe von XYAnchor gezeichnet:

	PolylineConnection connection = new PolylineConnection();
	connection.setSourceAnchor(new XYAnchor(new org.eclipse.draw2d.geometry.Point(10, 20) ) );
	connection.setTargetAnchor(new XYAnchor(new org.eclipse.draw2d.geometry.Point(100, 40) ) );
	contents.add(connection);



Dratva 1919 example5 draw2d.png

Routing

Wie man oben gesehen hat, zeichnet die PolylineConnection eine gerade Linie zwischen den von Anker festgelegten Punkten. Oft braucht man aber die Möglichkeit, die Linien anderer Formen zu zeichnen. In diesem Fall kann man eine neue Implementierung von Connection entwickeln. Es besteht aber eine einfachere Möglichkeit - das Connection-Objekt mit einem ConnectionRouter zu parametrieren. Das macht man mit der Methode Connection.setConnectionRouter. ConnectionRouter ist ein Interface in draw2d, vom dem es mehrere fertige Implementierungen gibt:

  • AbstractRouter - abstrakte Klasse mit einigen Hilfsfunktionen.
  • AutomaticRouter - abstrakte Klasse mit "Collision Detection" - Erkennung überlappender Verbindungen. Die Auflösung des Konflikts müssen die abgeleiteten Klassen übernehmen.
  • FanRouter - eine Ableitung von AutomaticRouter mit Konfliktauflösung. Die Konflikte werden so gelöst, dass mehrere Verbindungen zwischen zwei gleichen Punkten unterschiedlich geführt werden und eine Art Ventilatorschaufel bilden.
  • BendpointConnectionRouter - führt die Linie über die in einer Liste gegebenen Punkte.
  • ShortestPathConnectionRouter - finden den kürzesten Pfad, der alle Kinder einer gegebenen Figur meidet.
  • ManhattatConnectionRouter - erzeugt eine rechteckige Verbindung mit nur senkrechten und waagerechten Linien.


Hier ein Beispiel mit dem ManhattanConnectionRouter:

	Label label1 = new Label("Label 1");
	LineBorder borderL1 = new LineBorder();
	label1.setBounds(new Rectangle(10, 10, 100, 30) );
	label1.setBorder(borderL1);
	contents.add(label1);
 
	Label label2 = new Label("Label 2");
	label2.setBounds(new Rectangle(150, 150, 100, 30) );
	label2.setBorder(borderL1);
	contents.add(label2);
 
	ManhattanConnectionRouter router = new ManhattanConnectionRouter(); 
 
	PolylineConnection connection = new PolylineConnection();
	connection.setConnectionRouter(router);
	connection.setSourceAnchor(new ChopboxAnchor(label1) );
	connection.setTargetAnchor(new ChopboxAnchor(label2) );
	contents.add(connection);


Und der Output:
Dratva 1919 example6 draw2d.png

Decorations

Das letzte Beispiel wird jetzt modifiziert:

	Label label1 = new Label("Label 1");
	LineBorder borderL1 = new LineBorder();
	label1.setBounds(new Rectangle(10, 10, 100, 30) );
	label1.setBorder(borderL1);
	contents.add(label1);
 
	Label label2 = new Label("Label 2");
	label2.setBounds(new Rectangle(150, 150, 100, 30) );
	label2.setBorder(borderL1);
	contents.add(label2);
 
	ManhattanConnectionRouter router = new ManhattanConnectionRouter(); 
 
	PolylineConnection connection = new PolylineConnection();
	connection.setConnectionRouter(router);
	connection.setSourceAnchor(new ChopboxAnchor(label1) );
	connection.setTargetAnchor(new ChopboxAnchor(label2) );
 
	PolygonDecoration decoration = new PolygonDecoration();
	connection.setTargetDecoration(decoration);
 
	contents.add(connection);


Der Output von diesem Programm sieht so aus:
Dratva 1919 example7 draw2d.png

Wie man sieht, wurde hier ein Pfeil an einem Ende der Linie gezeichnet. Das wurde mit dem Aufruf von connection.setTargetDecoration erreicht. Es gibt eine entsprechende Methode für den Anfang der Linie, setSourceDecoration. Für das Decoration selbst wurde hier PolygonDecoration verwendet. In draw2d gibt es noch eine Decoration-Implementierung, PolylineDecoration. Und man darf natürlich eigene Decorations implementieren. Sie müssen das Interface RotatableDecoration implementieren.
Die Klassen PolygonDecoration und PolylineDecoration zeichnen standardmäßig einen Pfeil. Sie besitzen aber die Methode setTemplate, mit der man das Aussehen von diesem Decoration ändern kann. Das wird im nächsten Beispiel demonstriert. Hier wird auch das ManhattanRouting weggenommen, um das Rotieren des Templates deutlicher zu zeigen.


	Label label1 = new Label("Label 1");
	LineBorder borderL1 = new LineBorder();
	label1.setBounds(new Rectangle(10, 10, 100, 30) );
	label1.setBorder(borderL1);
	contents.add(label1);
 
	Label label2 = new Label("Label 2");
	label2.setBounds(new Rectangle(150, 150, 100, 30) );
	label2.setBorder(borderL1);
	contents.add(label2);
 
	//ManhattanConnectionRouter router = new ManhattanConnectionRouter(); 
 
	PolylineConnection connection = new PolylineConnection();
	//connection.setConnectionRouter(router);
	connection.setSourceAnchor(new ChopboxAnchor(label1) );
	connection.setTargetAnchor(new ChopboxAnchor(label2) );
 
	PointList template = new PointList();
	template.addPoint(0, 0);
	template.addPoint(-4, 2);
	template.addPoint(-2, 0);
	template.addPoint(-4, -2);
 
	PolygonDecoration decoration = new PolygonDecoration();
	decoration.setTemplate(template);
 
	connection.setTargetDecoration(decoration);
 
	contents.add(connection);


Dratva 1919 example8 draw2d.png
Man sieht hier deutlich, wie der Muster definiert wird, und wie die automatische Rotation funktioniert. Bei der Definition des Templates muss man sich vorstellen, dass die Verbindungslinie waagerecht ist und der Anfang des Koordinatensystems am Endpunkt der Linie sich befindet. Die negative X-Richtung ist dann die Richtung zum Zentrum der Linie. Beim Zeichnen wird der Muster um den Winkel rotiert, den die Verbindungslinie (oder ihr letzter Abschnitt im Fall einer Polylinie) zu der X-Achse bildet.

Rahmen

Mit der Methode setBorder des Interfaces IFigure kann man einer Figur einen Rahmen zuordnen. Für die Rahmen-Objekte ist das Interface Border definiert. Wie bei anderen wichtigen Elementen, gibt es auch von Border viele fertige Implementierungen, die sich äußerlich unterscheiden. Man könnte alle vorgefertigten Rahmentypen in drei Gruppen verteilen. Das sind

  • Einfache Linienrahmen (z.B. LineBorder)
  • Rahmen, die nach GUI-Elementen (z.B. Buttons) aussehen, das heißt gesenkt oder erhöht aussehen (z.B. SimpleLoweredBorder)
  • Rahmen mit einer Beschriftung (abgeleitet von AbstractLabeledBorder)


Der Rahmen wird als letztes beim Zeichnen einer Figur augegeben. Deswegen ist er immer im Vordergrund im vergleich mit anderen Teilen der Figur. Die neue experimentelle Klasse AbstractBackground soll ermöglichen, auch im Hintergrund einer Figur die Teile des Rahmens zu zeichnen.
Mit der Klasse CompoundBorder kann man mehrere Rahmen kombinieren.

Layer

Layer ist ein spezieller Typ von Figuren. Die Layer sind transparent optisch und auch für die Ereignisse. Das bedeutet, dass die GUI-Ereignisse wie z.B. Maus-Ereignisse sowie die "Hit Tests" werden tranparent an hinteren Figuren geleitet. Die Layer sind dafür gedacht, explizit nur in den LayerPanes benutzt zu werden.

Anordnungen (Layouts)

Die Layouts legen fest, wie die Parent-Figur ihre Kinder platziert. Ein Layout ist eine Implementierung des Interfaces LayoutManager. Es gibt mehrere Standardimplementierungen in draw2d:

  • AbstractLayout - eine abstrakte Implementierung mit vielen Hilfsfunktionen
  • AbstractHintLayout - Basisklasse für die Layouts, die die bevorzugte Größe der Figuren berücksichtigen.
  • ToolbarLayout - die Kinder werden senkrecht oder waagerecht an einer Linie platziert.


In folgenden Beispielen werden die Figuren wie folgt erzeugt:

	Label label1 = new Label("Label 1");
	LineBorder borderL1 = new LineBorder();
	label1.setBounds(new Rectangle(10, 10, 100, 30) );
	label1.setBorder(borderL1);
	contents.add(label1);
 
	Label label2 = new Label("Label 2");
	label2.setBounds(new Rectangle(150, 150, 100, 30) );
	label2.setBorder(borderL1);
	contents.add(label2);
 
	Ellipse ellipse = new Ellipse();
	ellipse.setBackgroundColor(ColorConstants.blue);
	ellipse.setBounds(new Rectangle(0, 0, 20, 40) );
	ellipse.setOpaque(true);
	contents.add(ellipse);
 
	RectangleFigure rectangle = new RectangleFigure();
	rectangle.setBounds(new Rectangle(20, 40, 120, 30) );
	rectangle.setOpaque(true);
	rectangle.setBackgroundColor(ColorConstants.red);
	contents.add(rectangle);


Ohne Anordnung erzeugen sie folgenden Output:
Dratva 1919 example9 draw2d.png

ToolbarLayout

Folgender Code benutzt das ToolbarLayout, um die Kinder senkrecht darzustellen:

	ToolbarLayout layout = new ToolbarLayout();
	layout.setStretchMinorAxis(false);
	contents.setLayoutManager(layout);


Und so sieht jetzt der Output aus:

Dratva 1919 example10 draw2d.png

Die Zeile mit dem Aufruf von setStretchMinoxAxis sagt dem LayoutManager, die Objekte in der X-Achs nicht zu dehnen. Wenn man diese Zeile weg lässt, sieht der Output so aus:

Dratva 1919 example10 1 draw2d.png

Mit dem folgenden Code kann man die Richtung der Anordnung um 90 Grad drehen:

	ToolbarLayout layout = new ToolbarLayout();
	layout.setStretchMinorAxis(false);
	layout.setVertical(false);
	contents.setLayoutManager(layout);



Und so sieht es aus:

Dratva 1919 example10 2 draw2d.png