Anhand einiger einfacher Beispiele haben Sie bereits gelernt, wie die Größe oder Position von Kindfensterobjekten basierend auf der Größe des Elters verändert werden kann. Bislang fand dieser Berechnungstyp als Reaktion auf eine Listener-Funktion für eine Größenänderung statt. Dies ist häufig die beste Methode, um die Anordnung von einfachen Fensterobjekten zu handhaben. Es gibt jedoch allgemeine Muster, die von Anwendungen beim Platzieren von Fensterobjekten verwendet werden. Diese Muster können in Form von Algorithmen für ein konfigurierbares Layout strukturiert sein, die durch viele unterschiedliche Anwendungen wieder verwendet werden können.
SWT definiert Layouts, die Größe und Position von Kindfensterobjekten in einem kombinierten Anzeigenobjekt für allgemeine Zwecke definieren. Layouts sind Unterklassen der abstrakten Klasse Layout. Die SWT-Standardlayouts befinden sich im Paket org.eclipse.swt.layout.
Wenn Sie Größe und Position von Fensterobjekten ändern wollen, sollten Sie einige allgemeine Definitionen kennen.
Diese Konzepte sind für alle Anwendungen wichtig, und zwar unabhängig davon, ob ein Layout verwendet wird. Ein Layout ist im Grunde genommen eine praktische Methode, um eine Funktionalität für das Ändern der Größe in einem Paket zu definieren und so erneut zu verwenden.
Durch Layouts werden einige weitere Konzepte eingeführt.
Eine weitere Erörterung dieser Konzepte sowie Abbildung zu deren Veranschaulichung finden Sie unter Understanding Layouts in SWT.
Der folgende Code-Ausschnitt zeigt den einfachen Fall einer Anwendung, die einen Rückruf für die Größenänderung verwendet, um ein Anzeigenelement auf die Größe seiner Eltern-Shell zu setzen.
Display display = new Display ();
Shell shell = new Shell (display);
Label label = new Label (shell, SWT.CENTER);
shell.addControlListener(new ControlAdapter() {
public void controlResized(ControlEvent e) {
label.setBounds (shell.getClientArea ());
}
});
Der nächste Ausschnitt verwendet ein Layout, um denselben Effekt zu erzielen:
Display display = new Display ();
Shell shell = new Shell (display);
Label label = new Label (shell, SWT.CENTER);
shell.setLayout(new FillLayout());
Selbst bei einem so einfachen Beispiel kann der Anwendungscode durch die Verwendung eines Layouts reduziert werden. Bei komplexeren Layouts ist der Vereinfachungseffekt erheblich größer.
SWT bietet drei Standardlayoutklassen, die in vielen Situationen eingesetzt werden können.
FillLayout ist die einfachste Layoutklasse. Sie ordnet Fensterobjekte in einer einzigen Zeile oder Spalte an. Hierbei erhalten alle Objekte dieselbe Größe. Anfänglich sind alle Fensterobjekte so groß wie das größte Fensterobjekt und so breit, wie das breiteste. FillLayout nimmt keinen Umbruch vor, und Sie können weder Randeinstellungen noch Abstände angeben.
Die Klasse FillLayout könnte verwendet werden, um Schaltflächen in einer Taskleiste oder einer Symbolleiste anzuordnen oder um Markierungsfelder in einem Objekt Group zusammenzufassen. Die Klasse FillLayout kann außerdem verwendet werden, wenn ein Objekt Composite nur ein Kindobjekt hat. Im oben dargestellten Beispiel bewirkt die Klasse FillLayout, dass das Anzeigenelement die Eltern-Shell vollständig ausfüllt.
Die Klasse RowLayout ordnet ebenfalls Fensterobjekte in Zeilen an, ist aber flexibler als die Klasse FillLayout. Sie kann einen Umbruch in den Fensterobjekten vornehmen und daher so viele Zeilen erstellen, wie zum Anzeigen benötigt werden. Außerdem bietet sie konfigurierbare Randeinstellungen für den Rand des Layouts sowie konfigurierbare Abstände zwischen den Fensterobjekten im Layout. Sie können eine Klasse RowLayout packen. Hierdurch erhalten alle Fensterobjekte dieselbe Größe. Wenn Sie ein Klasse RowLayout ausrichten, wird der zusätzlich im Objekt Composite verbleibende Platz als Rand zwischen den Fensterobjekten zugeordnet.
Höhe und Breite der Fensterobjekte in einer Klasse RowLayout können in einem Objekt RowData angegeben werden, das mit Hilfe von setLayoutData im Fensterobjekt festgelegt werden sollte.
Die Klasse GridLayout bietet das vielseitigste (und komplexeste) Layout. GridLayout ordnet Fensterelemente in einem Raster an und stellt auf diese Weise viele konfigurierbare Parameter zur Verfügung, mit denen das Verhalten der Rasterzeilen und -spalten beim Ändern der Größe des kombinierten Anzeigenobjekts gesteuert werden kann.
Die Klasse GridLayout definiert eine API, die die Gesamtstrategie des Layouts steuert. Das wichtigste Attribut ist das Attribut numColumns, das die horizontale Größe des Rasters bestimmt. In der Regel legen Sie diesen Wert fest, wenn Sie die Darstellung des Fensters erstmalig definieren. Die Reihenfolge der Fensterobjekte im Raster ist mit der Reihenfolge identisch, in der diese erstellt werden. Um die Reihenfolge der Fensterobjekte im Raster zu ändern, müssen Sie die Methoden für Steuerelemente moveAbove(Control) und moveBelow(Control) verwenden. Mit diesen Methoden können Fensterobjekte vor oder nach anderen Objekten im Layout eingefügt werden. (Die Angaben "above" (über) und "below" (unter) beziehen sich auf die Reihenfolge der Fensterobjekte und nicht auf die Position im eigentlichen Raster.)
Die folgende Tabelle fasst die konfigurierbaren Parameter für eine Klasse GridLayout zusammen.
Attribut |
Beschreibung |
---|---|
horizontalSpacing |
Anzahl der Pixel zwischen dem rechten Rand einer Zelle und dem linken Rand der Nachbarzelle. |
makeColumnsEqualWidth |
Gibt an, ob alle Spalten auf dieselbe Größe gesetzt werden sollen. |
marginWidth |
Anzahl der Pixel für den Rand am rechten und linken Rand des Rasters. |
marginHeight |
Anzahl der Pixel für den Rand am oberen und unteren Rand des Rasters. |
numColumns |
Anzahl der Spalten, aus denen das Raster bestehen soll. |
verticalSpacing |
Anzahl der Pixel zwischen dem unteren Rand einer Zelle und dem oberen Rand der Nachbarzelle. |
Die Klasse GridLayout unterstützt für die einzelnen Fensterobjekte im Raster viele weitere Layoutparameter. Diese Eigenschaften werden in einem Objekt GridData angegeben. Für jedes Fensterobjekt im Raster müssen Sie ein Objekt GridData als Objekt layoutData festlegen.
Die Klasse GridData definiert Darstellungskonstanten, mit denen Sie häufig verwendete Kombinationen von Layoutparametern im Konstruktor von GridData angeben können. Außerdem können Sie diese Attribute individuell festlegen, indem Sie die öffentlichen Methoden in GridData verwenden.
Extrem dynamische und komplexe Layouts können Sie mit GridData realisieren. Durch das Definieren dieser Werte für unterschiedliche Fensterobjekte im Raster können Sie viele verschiedene Layoutkombinationen erzielen. Selbst die komplexesten Dialoglayouts können mit GridData angegeben werden. Durch die Möglichkeit, Fensterobjekte über mehrere Zellen hinweg auszudehnen, können viele Layouts erstellt werden, die nicht einmal wie ein Raster aussehen.
Die folgende Tabelle fasst die konfigurierbaren Parameter für GridData zusammen. Eine weitere Beschreibung sowie Beispielanzeigen, die die unterschiedlichen Rasterparameter verwenden, finden Sie unter Understanding Layouts in SWT.
Attribut |
Beschreibung |
---|---|
grabExcessHorizontalSpace |
Gibt an, ob eine Zelle vergrößert werden soll, um zusätzlichen horizontalen Bereich zu nutzen, der im Raster verfügbar ist. Nachdem die Zellengrößen im Raster basierend auf den Fensterobjekten und deren Rasterdaten berechnet wurden, wird solchen Zellen mit erhöhtem Platzbedarf der gesamte zusätzliche Platz zugeordnet, der im kombinierten Anzeigenobjekt übrig ist. |
grabExcessVerticalSpace |
Gibt an, ob eine Zelle vergrößert werden soll, um zusätzlichen vertikalen Bereich zu nutzen, der im Raster verfügbar ist. |
heightHint |
Gibt eine Mindesthöhe für das Fensterobjekt (und somit für die es enthaltende Zeile) an. |
horizontalAlignment |
Kann einer der Werte BEGINNING, CENTER, END oder FILL sein. FILL bedeutet, dass das Fensterobjekt auf die gesamte Breite seiner Rasterzelle vergrößert wird. |
horizontalIndent |
Die Anzahl der Pixel zwischen dem Fensterobjekt und dem linken Rand seiner Rasterzelle. |
horizontalSpan |
Gibt die Anzahl der Spalten im Raster an, über die sich das Fensterobjekt erstrecken soll. In der Standardeinstellung belegt ein Fensterobjekt 1 Zelle im Raster. Es kann weitere horizontale Zellen belegen, wenn dieser Wert heraufgesetzt wird. |
verticalAlignment |
Kann einer der Werte BEGINNING, CENTER, END oder FILL sein. FILL bedeutet, dass das Fensterobjekt auf die gesamte Höhe seiner Rasterzelle vergrößert wird. |
verticalSpan |
Gibt die Anzahl der Zeilen im Raster an, über die sich das Fensterobjekt erstrecken soll. In der Standardeinstellung belegt ein Fensterobjekt 1 Zelle im Raster. Es kann weitere vertikale Zellen belegen, wenn dieser Wert heraufgesetzt wird. |
widthHint |
Gibt eine Mindestbreite für das Fensterobjekt (und somit für die es enthaltende Spalte) an. |
Es kann unter Umständen vorkommen, dass Sie eine eigene angepasste Klasse Layout schreiben müssen. Dies ist beispielsweise in Fällen die beste Lösung, in denen ein komplexes Layout an vielen unterschiedlichen Stellen einer Anwendung verwendet werden muss. Es kann außerdem geeignet sein, wenn Sie ein Layout durch anwendungsspezifische Kenntnisse anpassen können. Bevor Sie ein angepasstes Layout erstellen, sollten Sie sich über die folgenden Punkte Gedanken machen:
Sofern Sie kein extrem generisches Layout schreiben wollen, das durch unterschiedliche Fensterobjekte von Composite verwendet wird, ist es häufig einfacher, Größen zu berechnen und Kindelemente in einer Listener-Funktion für Größenänderung zu platzieren. Viele der angepassten Fensterobjekte von SWT wurden auf diese Weise geschrieben. Obwohl ein neues Fensterobjekt als Paar aus Composite/Layout implementiert werden kann, ist es eindeutiger und nicht mit dem Schreiben einer weiteren Klasse verbunden, es als Objekt Composite zu implementieren, das sein Layout über eine Listener-Funktion für Größenänderung festlegt und seine bevorzugte Größe durch eine Methode computeSize berechnet.
Wenn Sie noch immer der Meinung sind, dass Sie eine angepasste Layoutklasse benötigen, beginnen Sie am besten damit, den Layoutalgorithmus in einer Listener-Funktion für Größenänderung zu implementieren. Dies macht das Debug für den Algorithmus selbst einfacher. Achten Sie darauf, die unterschiedlichen Fälle für das Layout zu testen: Vergrößerung, Verkleinerung, Umbruch und Abschneiden. Sobald der Algorithmus funktioniert, kann der Code durch das Refactoring als Unterklasse von Layout erstellt werden.
Layouts müssen zwei Methoden implementieren:
Eine tiefer gehende Erörterung von angepassten Layouts finden Sie im Artikel Understanding Layouts in SWT.