34
Prof. Dr. Nikolaus Wulff LayoutManager LayoutManager Einsatz von LayoutManagern in AWT/Swing Containern

LayoutManager - fh-muenster.de · 2019. 5. 31. · LayoutManager selber entwickeln • Für spezielle Zwecke kann der LayoutManager selber entwickelt werden. • Hierzu bietet es

  • Upload
    others

  • View
    0

  • Download
    0

Embed Size (px)

Citation preview

Page 1: LayoutManager - fh-muenster.de · 2019. 5. 31. · LayoutManager selber entwickeln • Für spezielle Zwecke kann der LayoutManager selber entwickelt werden. • Hierzu bietet es

Prof. Dr. Nikolaus Wulff

LayoutManagerLayoutManager

Einsatz von LayoutManagern in AWT/Swing Containern

Page 2: LayoutManager - fh-muenster.de · 2019. 5. 31. · LayoutManager selber entwickeln • Für spezielle Zwecke kann der LayoutManager selber entwickelt werden. • Hierzu bietet es

Prof. Dr. Nikolaus Wulff Informatik II 2

Wozu LayoutManager

• Graphische Oberflächen müssen variabel auf Größenänderung eines Fenster reagieren.

• Hierzu wird intern vom „Hauptfenster“, i.A. ein (J)Frame oder (J)Dialog, eine repaint Nachricht an alle aggregierten Widgets gesendet.

• Diese müssen jetzt wissen, wie sie sich auf Grund dieser Größenänderung neu zu zeichen haben.

• Problem: Die Widgets wissen nichts um die anderen sie umgebenden Objekte, wie groß dürfen sie sich jetzt zeichnen?– parent.getSize() reicht nicht... ?

Page 3: LayoutManager - fh-muenster.de · 2019. 5. 31. · LayoutManager selber entwickeln • Für spezielle Zwecke kann der LayoutManager selber entwickelt werden. • Hierzu bietet es

Prof. Dr. Nikolaus Wulff Informatik II 3

Strategie Algorithmus

• Lösung I:– Der Container kennt seine Größe und alle aggregierten

Widgets.– Er weist jedem Widget eine Größe und Position zu.

• Problem: Es gibt viele Möglichkeiten die Widgets anzuordnen. Dies bedeutet in jedem abgeleiteten Frame, Dialog oder Panel die repaint Methode geeignet zu überladen.

• Lösung II:– Lagere den Algorithmus nach dem Stragegie-Muster in

einer externen Klasse aus, mit der der Container parametrisiert wird. => LayoutManager

Page 4: LayoutManager - fh-muenster.de · 2019. 5. 31. · LayoutManager selber entwickeln • Für spezielle Zwecke kann der LayoutManager selber entwickelt werden. • Hierzu bietet es

Prof. Dr. Nikolaus Wulff Informatik II 4

LayoutManager Klassendiagramm

Strategie

●●●

●●●

Button Table

Component

Panel Window

Frame Dialog

BorderLayout FlowLayout

GridLayout

Container

0..*0..*

LayoutManager<<Interface>>

111 1

• Bei Größenänderung fordert der Container seinen LayoutManger per layoutContainer(this) zum Ausrichten der aggregierten Komponenten auf.

Page 5: LayoutManager - fh-muenster.de · 2019. 5. 31. · LayoutManager selber entwickeln • Für spezielle Zwecke kann der LayoutManager selber entwickelt werden. • Hierzu bietet es

Prof. Dr. Nikolaus Wulff Informatik II 5

LayoutManager Vielfalt

• Für viele mögliche Layoutstrategien gibt es bereits vorgefertigte LayoutManager:– FlowLayout– BorderLayout– CardLayout– GridLayout– GridBagLayout– SplittPaneLayout– SpringLayout– ...

• Eigene LayoutManager entwickeln: http://java.sun.com/docs/books/tutorial/uiswing/layout/custom.html

Page 6: LayoutManager - fh-muenster.de · 2019. 5. 31. · LayoutManager selber entwickeln • Für spezielle Zwecke kann der LayoutManager selber entwickelt werden. • Hierzu bietet es

Prof. Dr. Nikolaus Wulff Informatik II 6

LayoutManager auswählen

• Beim Design gilt es zuerst einmal eine grobe Skizze zur Anordung der Widgets zu erstellen.

• Folgende Fragen müssen beantwortet werden:

– Wie ist die Positionierung der einzelnen Widgets?• absolut oder relativ

– Wie ist die Ausrichtung der Widgets?• links, rechts oder zentriert

– Gibt es visuelle Abhängigkeiten untereinander?– Welche Widgets haben feste Größe?– Welche Widgets haben veränderliche Größe?

• horizontal, vertikal oder variabel in beiden Dimensionen

Page 7: LayoutManager - fh-muenster.de · 2019. 5. 31. · LayoutManager selber entwickeln • Für spezielle Zwecke kann der LayoutManager selber entwickelt werden. • Hierzu bietet es

Prof. Dr. Nikolaus Wulff Informatik II 7

Größe einer Komponente

• Jede Swing/AWT Komponente hat eine Dimension, gegeben durch ihre Höhe und Breite.

• Pro Komponente gibt es vier Ausprägungen:

– Die aktuelle Größe: getSize()– Die minimalen Größe: getMinimalSize()– Die maximale Größe: getMaximalSize()– Die „Lieblingsgröße“: getPreferredSize()

• LayoutManager fragen alle Componenten vor jeder Neuberechung nach diesen Dimensionen und werden diese je nach Strategie berücksichtigen oder auch nicht...

Page 8: LayoutManager - fh-muenster.de · 2019. 5. 31. · LayoutManager selber entwickeln • Für spezielle Zwecke kann der LayoutManager selber entwickelt werden. • Hierzu bietet es

Prof. Dr. Nikolaus Wulff Informatik II 8

Flow- und BoxLayoutManager

• FlowLayout ordnet die Elemente horizontal fließend nebeneinander an, bis die Zeile voll ist.

• BoxLayout ordnet die Elemente horizontal oder vertikal fließend neben- oder untereinander an.

1 2 3

1

2

3

1 2 3

LayoutManager layout = new BoxLayout(comp,BoxLayout.Y_AXIS);

Page 9: LayoutManager - fh-muenster.de · 2019. 5. 31. · LayoutManager selber entwickeln • Für spezielle Zwecke kann der LayoutManager selber entwickelt werden. • Hierzu bietet es

Prof. Dr. Nikolaus Wulff Informatik II 9

BorderLayout

• Das BorderLayout unterteilt den Container in maximal 5 Bereiche:– Nord, Süd, Ost, West und Mitte.

CENTERWEST

NORTH

SOUTH

EAST

JPanel panel = new JPanel(new BorderLayout()); panel.add(comp, BorderLayout.CENTER);

Page 10: LayoutManager - fh-muenster.de · 2019. 5. 31. · LayoutManager selber entwickeln • Für spezielle Zwecke kann der LayoutManager selber entwickelt werden. • Hierzu bietet es

Prof. Dr. Nikolaus Wulff Informatik II 10

BorderLayout Strategie

1)Nur Komponenten die tatsächlich gesetzt sind werden berücksichtigt.

2)Nord- und Südkomponente werden horizontal gestreckt, ihre preferredHeight wird berücksichtigt.

3)West- und Ostkomponente werden vertikal gestreckt, ihre preferredWidth wird berücksichtigt.

4)Die mittlere Komponente wird so groß wie irgend möglich in beiden Dimensionen gestreckt, ohne die Punkte 1) – 3) zu verletzen.

Page 11: LayoutManager - fh-muenster.de · 2019. 5. 31. · LayoutManager selber entwickeln • Für spezielle Zwecke kann der LayoutManager selber entwickelt werden. • Hierzu bietet es

Prof. Dr. Nikolaus Wulff Informatik II 11

CardLayout

• Ein CardLayout verhält sich wie ein Stapel von Spielkarten, eine ist oben und sichtbar, die anderen liegen darunter und sind verdeckt.

• Jede „Karte“ bildet genau eine Komponente ab.• Über die einzelnen Schichten kann mit first(), last(),

next() und previous() iteriert werden.• Einfacher ist allerdings das Arbeiten mit einer

JTabbedPane. Diese erlaubt einzelne Tabulatoren zu selektieren. Intern verwendet sie ein TabbedPaneLayout...

Page 12: LayoutManager - fh-muenster.de · 2019. 5. 31. · LayoutManager selber entwickeln • Für spezielle Zwecke kann der LayoutManager selber entwickelt werden. • Hierzu bietet es

Prof. Dr. Nikolaus Wulff Informatik II 12

GridLayout

• Diese Layout erzeugt ein NxM Gitter mit gleichgroßen Zellen.

• Komponenten werden in der Reihenfolge des Einfügens auf die Zellen verteilt...

1 2

3 4

5 6

7 8

JPanel panel = new JPanel( new GridLayout(2,4)); panel.add(new Button("1"));

panel.add(new Button("8"));

●●●

Page 13: LayoutManager - fh-muenster.de · 2019. 5. 31. · LayoutManager selber entwickeln • Für spezielle Zwecke kann der LayoutManager selber entwickelt werden. • Hierzu bietet es

Prof. Dr. Nikolaus Wulff Informatik II 13

GridBagLayout

• Am kompliziertesten ist das GridBagLayout.• Es definiert ähnlich wie das GridLayout ein Gitter.• Die Gitterbreite und -höhe ist jetzt jedoch nicht

konstant und kann variabel justiert werden.• Componenten können sich über mehrere

Gitterplätze erstrecken.• Nicht alle Gitterplätze müssen besetzt sein.• Hierzu müssen mit Hilfe sogenannter Constraints

spezielle Argumente beim Hinzufügen der Komponente zum Container gesetzt werden

Page 14: LayoutManager - fh-muenster.de · 2019. 5. 31. · LayoutManager selber entwickeln • Für spezielle Zwecke kann der LayoutManager selber entwickelt werden. • Hierzu bietet es

Prof. Dr. Nikolaus Wulff Informatik II 14

GridBagLayout Constraints

• Das GridBagLayout gestattet per Vergabe von Constraints für jede einzelne Komponente sehr feine Justierungen.

• GridBagConstraints erlauben die Angabe von:– relativer oder absoluter Positionierung– horz., vertikale oder Ausfüllung in beide Dimension(en)– Angabe von Gitterplatz und Gitterbreite und -höhe– Justierung: left, center,right.– Verankerung am Gitterplatz: NW N N

E

SW SE

W E

S

Page 15: LayoutManager - fh-muenster.de · 2019. 5. 31. · LayoutManager selber entwickeln • Für spezielle Zwecke kann der LayoutManager selber entwickelt werden. • Hierzu bietet es

Prof. Dr. Nikolaus Wulff Informatik II 15

Felder von GridBagConstraint

• Integer gridx und gridy: Gitterplatz (x,y)• Integer gridwidth und gridheigth: Breite und Höhe

der Komponente in Gitterplatzkoordinaten.• Float weightx und weighty: relative Breite und

Höhe der Spalte bzw. Reihe im Gitter.• Aufzählung fill: Komponente in x und/oder y

Richtung skalieren.– HORIZONTAL, VERTIKAL, BOTH.

• Aufzählung anchor: Verankerung der Komponente am Gitterplatz.– NORHTEAST, WEST, etc.

Page 16: LayoutManager - fh-muenster.de · 2019. 5. 31. · LayoutManager selber entwickeln • Für spezielle Zwecke kann der LayoutManager selber entwickelt werden. • Hierzu bietet es

Prof. Dr. Nikolaus Wulff Informatik II 16

Variables Gitter

1 2

3

4

• Ein solches, variables Gitter kann nicht mit dem GridLayout erzeugt werden.

• Hierzu eignet sich das GridBagLayout.

5

Page 17: LayoutManager - fh-muenster.de · 2019. 5. 31. · LayoutManager selber entwickeln • Für spezielle Zwecke kann der LayoutManager selber entwickelt werden. • Hierzu bietet es

Prof. Dr. Nikolaus Wulff Informatik II 17

“Auszählen des Gitters“

1 2

3

4

• Button 3 hat eine gridWidth von 2.• Button 5 hat Position (gridx,gridy)=(1,3).

5

1

1

0

0

2

3

Page 18: LayoutManager - fh-muenster.de · 2019. 5. 31. · LayoutManager selber entwickeln • Für spezielle Zwecke kann der LayoutManager selber entwickelt werden. • Hierzu bietet es

Prof. Dr. Nikolaus Wulff Informatik II 18

GridBagConstraints anwenden

GridBagConstraints constraints = new GridBagConstraints();constraints.fill = GridBagConstraints.BOTH;constraints.gridx = 0;constraints.gridy = 0;constraints.gridwidth = 1;panel.add(new Button("1"), constraints); constraints.gridx++;panel.add(new Button("2"), constraints); constraints.gridx = 0;constraints.gridy = 1;constraints.gridwidth = 2;panel.add(new Button("3"), constraints);// Button 4 missing ...constraints.gridx = 1;constraints.gridy = 3;constraints.gridwidth = 1;panel.add(new Button("5"), constraints);

Page 19: LayoutManager - fh-muenster.de · 2019. 5. 31. · LayoutManager selber entwickeln • Für spezielle Zwecke kann der LayoutManager selber entwickelt werden. • Hierzu bietet es

Prof. Dr. Nikolaus Wulff Informatik II 19

Variable Gitterbreite oder -höhe

• Soll das Gitter nicht einheitlich dimensioniert werden, so kann hierzu in x- oder y Dimension jeder Komponente ein Gewicht zugewiesen werden.

• Solange alle Gewichte gleich groß gewählt (oder 0 sind) macht sich dies nicht bemerkbar...

• Wird hingegen weightx und weighty explizit unterschiedlich gewählt, so kann jeder Gitterplatz eine eigene variable Größe erhalten.

• Die Gewichte müssen größer Null sein und gehen relativ in die Gewichtung ein.

Page 20: LayoutManager - fh-muenster.de · 2019. 5. 31. · LayoutManager selber entwickeln • Für spezielle Zwecke kann der LayoutManager selber entwickelt werden. • Hierzu bietet es

Prof. Dr. Nikolaus Wulff Informatik II 20

Gewichtetes Gitter

• „2“ und „1“ als Gewichte in x Richtung• „3“, „2“, „0“ und „1“ als Gewichte in y Richtung.

2/3 1/3

3/6

2/6

1/6

minSize

Page 21: LayoutManager - fh-muenster.de · 2019. 5. 31. · LayoutManager selber entwickeln • Für spezielle Zwecke kann der LayoutManager selber entwickelt werden. • Hierzu bietet es

Prof. Dr. Nikolaus Wulff Informatik II 21

Gewichte vergeben constraints.gridx = 0; constraints.gridy = 0; constraints.gridwidth = 1; constraints.gridheight = 1; constraints.weightx = 2; constraints.weighty = 3; panel.add(new JButton("1"), constraints); constraints.gridx++; constraints.weightx = 1; panel.add(new JButton("2"), constraints); constraints.gridx = 0; constraints.gridy++; constraints.weighty = 2; panel.add(new JButton("3"), constraints);

Page 22: LayoutManager - fh-muenster.de · 2019. 5. 31. · LayoutManager selber entwickeln • Für spezielle Zwecke kann der LayoutManager selber entwickelt werden. • Hierzu bietet es

Prof. Dr. Nikolaus Wulff Informatik II 22

GridBagLayout properties

int columns=4;GridBagLayout layout = new GridBagLayout();JPanel panel = new JPanel(layout);layout.columnWeights = new double[columns];layout.columnWidths = new int[columns];for(int i=0;i<columns;i++) { layout.columnWeights[i] = 1.0; layout.columnWidths[i] = 100; } • GridBagLayout ermittelt aus den einzelnen

Gewichten und Weiten der Constraints vier Arrays, die jedoch auch explizit gesetzt werden können und dann diese Berechnung übersteuern.

• Es lohnt sich daher ein GridBagLayout zunächst auf einem Blatt Papier zu designen...

Page 23: LayoutManager - fh-muenster.de · 2019. 5. 31. · LayoutManager selber entwickeln • Für spezielle Zwecke kann der LayoutManager selber entwickelt werden. • Hierzu bietet es

Prof. Dr. Nikolaus Wulff Informatik II 23

Alternativen

• Das Arbeiten mit dem GridBagLayout ist relativ kompliziert und aufwendig.

• Gerade für Formulare bietet sich eine einfachere Alternative an:

• Das Verschachteln von Panels mit jeweils eigenen LayoutManagern.

• Die einzelnen „Bereiche“ lassen sich recht modular programmieren, testen und zusammensetzen.

• Tip: Im Testmodus jedem Panel eine andere Hintergrundfarbe setzten. Dies erleichtert die visuelle Zuordnung.

Page 24: LayoutManager - fh-muenster.de · 2019. 5. 31. · LayoutManager selber entwickeln • Für spezielle Zwecke kann der LayoutManager selber entwickelt werden. • Hierzu bietet es

Prof. Dr. Nikolaus Wulff Informatik II 24

Layouts verschachteln

• Beispiel: Ausgangspunkt ist ein BorderLayout. Jede der fünf möglichen Komponenten ist selber ein Panel mit unterschiedlichem Layouts.– Ein GridBagLayout mit zwei FlowLayouts im Norden

und Süden und Box- und GridLayout in Ost und West...

Page 25: LayoutManager - fh-muenster.de · 2019. 5. 31. · LayoutManager selber entwickeln • Für spezielle Zwecke kann der LayoutManager selber entwickelt werden. • Hierzu bietet es

Prof. Dr. Nikolaus Wulff Informatik II 25

LayoutManager selber entwickeln

• Für spezielle Zwecke kann der LayoutManager selber entwickelt werden.

• Hierzu bietet es sich an einen existierenden LayoutManager zu überladen, um nicht alle Funktionalität selber implementieren zu müssen.

• Meistens wird nicht die Schnittstelle LayoutManager sondern die Erweiterung LayoutManager2 verwendet.– Letzterer bietet optimierte Layoutfähigkeiten in Form

von Constraints an.

• Wichtige zu implentierende Funktionen sind:addLayoutComponent(Component comp, Object constraints)layoutContainer(Container parent)

Page 26: LayoutManager - fh-muenster.de · 2019. 5. 31. · LayoutManager selber entwickeln • Für spezielle Zwecke kann der LayoutManager selber entwickelt werden. • Hierzu bietet es

Prof. Dr. Nikolaus Wulff Informatik II 26

ApplicationLayout

• Es soll ein spezieller LayoutManager für eine Anwendung mit Tool- und Statusbar, sowie einer Navigator- und Inhaltsansicht entwickelt werden.

• Bemerkung: Das geht auch mit dem BorderLayout!

Statusbar

ToolbarN

avig

ator

Content

Page 27: LayoutManager - fh-muenster.de · 2019. 5. 31. · LayoutManager selber entwickeln • Für spezielle Zwecke kann der LayoutManager selber entwickelt werden. • Hierzu bietet es

Prof. Dr. Nikolaus Wulff Informatik II 27

ApplicationLayout Design

• Es werden vier Konstanten definiert, zum Setzen der vier Komponenten in einer Map:– NAVIGATOR, TOOLBAR, STATUSBAR,CONTENT

• Ferner werden drei Variablen benötigt:– Die relative Toolbar Höhe– Die relative Statusbar Höhe– Die relative Navigator Breite

• Aus diesen drei Werten ergeben sich– Die relative Höhe und Breite vom Inhaltsbereich

• In der layoutContainer Methode wird für jede der vier Komponenten, ausgehend von der aktuellen Größe des Containers, die BoundingBox berechnet.

Page 28: LayoutManager - fh-muenster.de · 2019. 5. 31. · LayoutManager selber entwickeln • Für spezielle Zwecke kann der LayoutManager selber entwickelt werden. • Hierzu bietet es

Prof. Dr. Nikolaus Wulff Informatik II 28

ApplicationLayout Implementierungpublic class ApplicationLayout extends BorderLayout { public final static String TOOLBAR = "ToolBar"; public final static String STATUSBAR = "StatusBar"; public final static String NAVIGATOR = "Navigator"; public final static String CONTENT = "Center"; private final static float TOOBAR_HEIGHT = 0.10f; private final static float NAVIGATOR_WIDTH = 0.15f; private final static float STATUSBAR_HEIGHT = 0.10f; private float toolbarHeight = TOOBAR_HEIGHT; private float statusbarHeight = STATUSBAR_HEIGHT; private float navigatorWidth = NAVIGATOR_WIDTH; private HashMap<String, Component> components = new HashMap<String, Component>(); @Override public void addLayoutComponent(Component comp, Object constraints) { // super.addLayoutComponent(comp, constraints); components.put(constraints.toString(), comp); }

Page 29: LayoutManager - fh-muenster.de · 2019. 5. 31. · LayoutManager selber entwickeln • Für spezielle Zwecke kann der LayoutManager selber entwickelt werden. • Hierzu bietet es

Prof. Dr. Nikolaus Wulff Informatik II 29

layoutComponent @Override public void layoutContainer(Container parent) { Component component; Insets insets = parent.getInsets(); int x,y,h,w; int width = parent.getWidth(); int height = parent.getHeight(); width -= insets.left + insets.right; height -= insets.top + insets.bottom; component = components.get(TOOLBAR); x = insets.left; y = insets.top; w = width; h = (int)(toolbarHeight*height); component.setBounds(x,y,w,h);

Page 30: LayoutManager - fh-muenster.de · 2019. 5. 31. · LayoutManager selber entwickeln • Für spezielle Zwecke kann der LayoutManager selber entwickelt werden. • Hierzu bietet es

Prof. Dr. Nikolaus Wulff Informatik II 30

layoutComponent cont. component = components.get(NAVIGATOR); x = insets.left; y += h; w = (int)(navigatorWidth*width); h = (int)(getNavigatorHeight()*height); component.setBounds(x,y,w,h);

component = components.get(CONTENT); x += w; w = width-w; component.setBounds(x,y,w,h); component = components.get(STATUSBAR); x = insets.left; y += h; w = width; h = (int)(statusbarHeight*height); component.setBounds(x,y,w,h); }

Achtung: Annahme ist alle vier Komponenten sind gesetzt!

Page 31: LayoutManager - fh-muenster.de · 2019. 5. 31. · LayoutManager selber entwickeln • Für spezielle Zwecke kann der LayoutManager selber entwickelt werden. • Hierzu bietet es

Prof. Dr. Nikolaus Wulff Informatik II 31

Anwendung des ApplicationLayouts

public JPanel createApplicationPane() { JComponent comp; ApplicationLayout layout; layout = new ApplicationLayout(); layout.setNavigatorWidth(0.18f);

JPanel panel = new JPanel(); panel.setLayout(layout); comp = createStatusPanel(); comp.setBackground(Color.BLUE); panel.add(comp,ApplicationLayout.STATUSBAR);

comp = createToolbarPanel(); comp.setBackground(Color.GRAY); panel.add(comp,ApplicationLayout.TOOLBAR);

Page 32: LayoutManager - fh-muenster.de · 2019. 5. 31. · LayoutManager selber entwickeln • Für spezielle Zwecke kann der LayoutManager selber entwickelt werden. • Hierzu bietet es

Prof. Dr. Nikolaus Wulff Informatik II 32

ApplicationManager in Aktion

18% 82%

10%

10%

80%

Page 33: LayoutManager - fh-muenster.de · 2019. 5. 31. · LayoutManager selber entwickeln • Für spezielle Zwecke kann der LayoutManager selber entwickelt werden. • Hierzu bietet es

Prof. Dr. Nikolaus Wulff Informatik II 33

NullLayoutManager

• Als letzte Alternative bleibt der sogenannte NullLayoutManager:

container.setLayout(null);• Dadurch wird der Layout-Mechanismus eines

Containers abgeschaltet.• Es werden exakt die (x,y)-Positionen und

(withd,height)-Dimensionen der Componenten verwendet, wie explizit angegeben.

• Dies erzeugt eine starre GUI ohne resize Fähigkeiten, jedoch exakt ausgerichtet.

• Dies setzt allerdings Kenntniss des Displaygröße des Benutzers zur Entwicklungszeit voraus...

Page 34: LayoutManager - fh-muenster.de · 2019. 5. 31. · LayoutManager selber entwickeln • Für spezielle Zwecke kann der LayoutManager selber entwickelt werden. • Hierzu bietet es

Prof. Dr. Nikolaus Wulff Informatik II 34

Zusammenfassung

• LayoutManager bieten eine effiziente Möglichkeit geeignete Strategien zum Justieren der Widgets auszuwählen.

• Sie lassen sich beliebig mit Hilfe von Panels verschachteln.

• Für Spezialfälle ist es relativ leicht eigene LayoutManager selbst zu entwickeln.