# GroupLayout - wie funktionierts?



## sh (25. Nov 2011)

Hey-ho,

Seit neustem versuch ich mich ja an der GUI-Programierung.. Was ich vor allem lernen will ist, resizable GUIs zu programmieren. Im Anhang mal mit Paint gezeichnet wie die Oberfläche später (grob) aussehen soll. Jede schwarze Box stellt eine Komponente bzw. später evtl. eine Gruppe aus Komponenten dar.

EDIT: Bei Google bin ich auf GroupLayout gestoßen, welches scheinbar ganz gut für mein Vorhaben geeignet ist.

Die (meiner Meinung nach) beste Seite die das GroupLayout erklärt ist
Visual Guide to Layouts (GroupLayout). Allerdings blicke ich trotzdem noch nicht so ganz durch, vor allem wie die Gruppen von setHorizontalGroup() und setVerticalGroup() zusammenhängen und sich gegenseitig beeinflussen.

Ich hab seit gestern schon einige Zeit damit verbracht herauszufinden wie das funktioniert. Also erstmal das hier ausprobiert:

```
layout.setHorizontalGroup(layout.createSequentialGroup()
        		.addComponent(textField)
        		.addComponent(tabbedPane)
        		
        );
        
        layout.setVerticalGroup(layout.createSequentialGroup()
		        .addComponent(textField)
		        .addComponent(tabbedPane)
        );
```
Im Anhang mal das Ergebnis dazu - ergebnis1.png. Ich denke soweit versteh ichs noch. Wenn man von links nach rechts geht (Horizontale) dann wird jede Komponente rechts von der Vorhergehenden angeordnet. Da das gleiche von oben nach unten (Vertikale) auch passiert, erhält man alle Elemente auf einer Diagonalen von oben links nach unten rechts.

2. Versuch:

```
layout.setHorizontalGroup(layout.createParallelGroup()
        		.addComponent(textField)
        		.addComponent(tabbedPane)
        		
        );
        
        layout.setVerticalGroup(layout.createSequentialGroup()
		        .addComponent(textField)
		        .addComponent(tabbedPane)
        );
```
Im Anhang das ergebnis2.png.

Nun habe ich versucht verschiedene Gruppen jeweils im setHorizontalGroup() sowie auch im setVerticalGroup() zu kombinieren um vorlage.png (im Anhang) zu erhalten. Alle versuche gescheitert, könnte mir vll. jemand ein oder zwei einfache Beispiele geben anhand deren ich sehen kann wie genau das ganze funktioniert? 

MfG


----------



## bERt0r (25. Nov 2011)

Ich weis jetzt zwar nicht ganz wie dein Gewünschtes Layout mit den 5 Komponenten die du in deinem Bild hast aussehen soll, aber zum GroupLayout:
Das Layout hat eine vertical group, diese sagt aus, wie die Komponenten liegen, wenn du sie einfach mal von oben nach unten durchgehst.
Z.b
A B
 C
D E F
=>

```
layout.setVerticalGroup(layout.createSequentialGroup()  //3 Zeilen nacheinander also sequenziell
		        .addGroup(layout.createParallelGroup()                    //A und B sind nebeneinander also parallel
                                            .addComponent(A).addComponent(B)
                         )
		        .addComponent(C)
                        .addGroup(layout.createParallelGroup()
                                            .addComponent(D).addComponent(E).addComponent(F)
                        ) 
        );
```
Für die Horizontal Group musst du das ganze dann wieder genauso durchgehen, nur diesmal von links nach rechts. Also hast du erstmal eine Parallele Gruppe (3 Zeilen) und jede Zeile ist wiederum eine Sequential Group.


----------



## sh (26. Nov 2011)

Also am Ende sollte es ungefähr aussehen wie vorlage.png. Hab mal noch ein layout.png drangehängt - mit Paint zusammengeschustert wie es am Ende ca. aussehen sollte.

Danke für die Antwort; Allerdings krieg ichs immer noch nicht gebacken. Das setVerticalGroup() die Gruppen von oben nach unten regelt und setHorizontalGroup() von links nach rechts versteh ich, nur wie ich die Gruppen verschachteln muss um das gewünschte Layout zu erhalten - irgendwie blick ich da nicht so richtig durch!

Hier mal mein ganzer Testcode:

```
package test.gui;
 
import static javax.swing.GroupLayout.Alignment.BASELINE;

import java.awt.Dimension;
import java.awt.EventQueue;

import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.WindowConstants;
 
@SuppressWarnings("serial")

public class GUITest extends JFrame {
	
    public GUITest() {
   
    	JPanel panel1 = new JPanel();
    	JPanel panel2 = new JPanel();
    	JPanel panel3 = new JPanel();
    	
        JLabel label = new JLabel("Label:");;
        JTextField textField = new JTextField();
        JButton button = new JButton("Button");
        JTabbedPane tabbedPane = new JTabbedPane();
        tabbedPane.addTab("Tab1", panel1);
        tabbedPane.addTab("Tab2", panel2);
        tabbedPane.addTab("Tab3", panel3);
        
        GroupLayout layout = new GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setAutoCreateGaps(true);
        layout.setAutoCreateContainerGaps(true);
 
        layout.setHorizontalGroup(layout.createSequentialGroup()
		        .addComponent(label)
		        .addComponent(textField)
		        .addComponent(button)
		        .addComponent(tabbedPane)
        );
        
        layout.setVerticalGroup(layout.createSequentialGroup()  
                .addGroup(layout.createParallelGroup(BASELINE)                    
                		.addComponent(label).addComponent(textField).addComponent(button)
                )
                .addComponent(tabbedPane)
                .addGroup(layout.createParallelGroup()
                		.addComponent(button)
                ) 
        );
        
        
        setMinimumSize(new Dimension(340, 180));
        setPreferredSize(new Dimension(640, 480));
        setTitle("GUI Test");
        pack();
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
    }
     
    public static void main(String args[]) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
                new GUITest().setVisible(true);
            }
        });
    }
}
```


----------



## jgh (26. Nov 2011)

da ich noch nicht mit GroupLayout gearbeitet habe, hier mal eine Möglichkeit deinen Wunsch(Layout.png) mit einem BorderLayout zu realisieren, solltest für dich natürlich nur das GroupLayout in Frage kommen, dann vergiss/überlies diesen Post.


```
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.WindowConstants;

@SuppressWarnings("serial")
public class GUITest extends JFrame {

	public GUITest() {

		JPanel panel1 = new JPanel();
		JPanel panel2 = new JPanel();
		JPanel panel3 = new JPanel();

		JLabel label = new JLabel("Label: ");
		JTextField textField = new JTextField();
		JButton button = new JButton("Button");
		JTabbedPane tabbedPane = new JTabbedPane();
		tabbedPane.addTab("Tab1", panel1);
		tabbedPane.addTab("Tab2", panel2);
		tabbedPane.addTab("Tab3", panel3);

		setMinimumSize(new Dimension(340, 180));
		setPreferredSize(new Dimension(640, 480));
		setSize(new Dimension(640, 480));
		setTitle("GUI Test");
		setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		setLocationRelativeTo(null);

		add(tabbedPane, BorderLayout.CENTER);

		JPanel oben = new JPanel();
		oben.setLayout(new BorderLayout());
		oben.add(label, BorderLayout.WEST);
		oben.add(textField);
		oben.add(button, BorderLayout.EAST);
		add(oben, BorderLayout.NORTH);

		JPanel unten = new JPanel();
		FlowLayout fl = new FlowLayout();
		fl.setAlignment(FlowLayout.RIGHT);
		unten.setLayout(fl);
		for (int i = 0; i < 3; i++) {
			JButton b = new JButton("Button");
			unten.add(b);
		}
		add(unten, BorderLayout.SOUTH);
	}

	public static void main(String args[]) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					UIManager
							.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
				} catch (Exception ex) {
					ex.printStackTrace();
				}
				new GUITest().setVisible(true);
			}
		});
	}
}
```


----------



## sh (26. Nov 2011)

Hey!

Danke für die Antwort - aber ich wollts eben nicht mit BorderLayout/FlowLayout bzw. beides in Kombination machen. 
Hab mir nochmal genau bErt0r's Antwort angesehen und versucht es nachzuvollziehen - und sieh an es hat geklappt (zumindest der erste Teil):

EDIT:
Hab paar unnötige Gruppen weggemacht

```
layout.setHorizontalGroup(
        		layout.createParallelGroup()
        			.addGroup(layout.createSequentialGroup()
        					.addComponent(label)
        					.addComponent(textField)
        					.addComponent(button)
        			)
        			.addComponent(tabbedPane)
        			.addGroup(layout.createSequentialGroup()
        					.addComponent(button2)
        					.addComponent(button3)
        					.addComponent(button4)
        			)
        );
        
        layout.setVerticalGroup(
        		layout.createSequentialGroup()
        			.addGroup(layout.createParallelGroup(BASELINE)
        					.addComponent(label)
        					.addComponent(textField)
        					.addComponent(button)
        			)
        			.addComponent(tabbedPane)
        			.addGroup(layout.createParallelGroup(BASELINE)
        					.addComponent(button2)
        					.addComponent(button3)
        					.addComponent(button4)
        			)
        );
```

Ich denke ich versteh nun wie setVerticalGroup() und setHorizontalGroup() mit den verschachtelten Gruppen funktioniert. Werd noch weiter rumprobieren =)

- Wie krieg ich jetzt allerdings die 3 Buttons "previous" "next" "quit" in die untere rechte Ecke? - Hab grade noch mit createParallelGroup(TRAILING) im setHorizontalGroup() probiert, allerdings "verschwinden" dann 2 Buttons (ich denke die "verstecken" sich dann unter dem 1.)

Danke


----------



## sh (26. Nov 2011)

So ich habs jetzt - musste die parallele "Hauptgruppe" im setHorizontalGroup() auf TRAILING setzen.

Hier nochmal der ganze Code; Wenn jemand Verbesserungsvorschläge hat (vll. hab ich unnütze Gruppen drinnen) dann bitte bescheid geben!


```
package in.pussykill.main;
 
import static javax.swing.GroupLayout.Alignment.*;

import java.awt.Dimension;
import java.awt.EventQueue;

import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.WindowConstants;
 
@SuppressWarnings("serial")

public class GUITest extends JFrame {
	
    public GUITest() {
   
    	JPanel panel1 = new JPanel();
    	JPanel panel2 = new JPanel();
    	JPanel panel3 = new JPanel();
    	
        JLabel label = new JLabel("Label:");;
        JTextField textField = new JTextField();
        JButton button = new JButton("Button");
        JButton button2 = new JButton("previous");
        JButton button3 = new JButton("next");
        JButton button4 = new JButton("quit");
        JTabbedPane tabbedPane = new JTabbedPane();
        tabbedPane.addTab("Tab1", panel1);
        tabbedPane.addTab("Tab2", panel2);
        tabbedPane.addTab("Tab3", panel3);
        
        GroupLayout layout = new GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setAutoCreateGaps(true);
        layout.setAutoCreateContainerGaps(true);
 
        layout.setHorizontalGroup(
        		layout.createParallelGroup(TRAILING)
        			.addGroup(layout.createSequentialGroup()
        					.addComponent(label)
        					.addComponent(textField)
        					.addComponent(button)
        			)
        			.addComponent(tabbedPane)
        			.addGroup(layout.createSequentialGroup()
	        					.addComponent(button2)
	        					.addComponent(button3)
	        					.addComponent(button4)
        			)
        );
        
        layout.setVerticalGroup(
        		layout.createSequentialGroup()
        			.addGroup(layout.createParallelGroup(BASELINE)
        					.addComponent(label)
        					.addComponent(textField)
        					.addComponent(button)
        			)
        			.addComponent(tabbedPane)
        			.addGroup(layout.createParallelGroup(BASELINE)
        					.addComponent(button2)
        					.addComponent(button3)
        					.addComponent(button4)
        			)
        );
        
        
        setMinimumSize(new Dimension(340, 200));
        setPreferredSize(new Dimension(640, 480));
        setTitle("GUI Test");
        pack();
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
    }
     
    public static void main(String args[]) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
                new GUITest().setVisible(true);
            }
        });
    }
}
```


----------

