# Layout: oben 20% unten 80%



## Juggl3r (15. Okt 2012)

Hallo,

ich hab gerade begonnen mit GUI Programmierung und will grad ziemlich am Verzweifeln, da ich nichtmal meine Einfachen Ideen hinbekomme.

Ich will mein Frame so unterteilen, dass ich von der Höhe ca. 20-30% oben für einen eigenen Teil nehme (für ein Suchfeld mit Buttons zum Suchen und Optionen) und den unteren Teil zur Anzeige.

D.h. ich hab einen JPanel für den oberen Teil und einen JPanel für den unteren Teil.
Für das Frame runterherum brauche ich jetzt natürlich irgend einen Layout Manager.

Ich hab mir jetzt schon einiges Durchgelesen, bin aber eher mehr Verwirrt, als das ichs verstanden habe....

Soweit ich das Verstanden habe, sollte ich für den Frame runterherum ein GridBagLayout nehmen.
Und für den oberenTeil nehme ich dann einfach ein Flow Layout damit ich die Dinger nebeneinander anordne.
Das Problem ist aber, dass ich beim GridBagLayout keine Höhen oder so angeben kann.
Wenn ich z.b. als Constrains 
		obererTeilConstrains.gridheight = 2;
angebe, dann muss ich beim unteren Teil zwar gridy=2 nehmen damit es sich nicht überschneidet, aber insgesamt sind sie trotzdem gleich Hoch.

Und wenn ich irgendwas mit .ipady nehme, dann wird der obere Teil zwar größer, aber ich benutze für den Unteren Teil nie den gesamten Platz...... Also es pickt trotzdem alles oben.

edit:
Kann mir jemand vll. kurz einen Code zeigen, wie ich es schaffe, z.b. in den oberen 30% des Fensters 3 Labens nebeneinander anzuordnen.
Und darunter auf den adnerenn 70% der Höhe dann einen großen Button, der die ganze Breite + verbleibende Höhe einnimmt? Ist zwar so Schwachsinnige, aber nur damit ich sehe, wie man soetwas anordner..

edit2:
Hier vll. noch der Code mit dem ich gerade herumspiele.
Irgendwie ist der überhaupt nicht dynamisch, wenn ich die Fenstergröße ändere, bleiben die Buttons gleich groß usw. 
Wäre cool wenn mir jemand zeigt, wie ich die ersten 4 Buttons in die 1te Zeile bekomme und den 5ten Button in die 2te, aber so, dass der 5te Button die gesamte Größe einnimmt und dabei 70% der Höhe hat und die ersten 4 Buttons die restlichen 30%.



```
import java.awt.*;
 
import javax.swing.*;
 
public class Demo {
    public static void main( String[] args ) throws Exception{
        
    	JFrame frame = new JFrame("Test");
    	frame.setSize(400,500);
    	frame.setVisible(true);
    	frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    	JPanel panel = new JPanel(new GridBagLayout());
    	frame.add(panel, BorderLayout.NORTH);
    	
    	
    	GridBagConstraints c = new GridBagConstraints();

    	
    	JButton label1 = new JButton("Test1");
    	c.gridx = 0;
    	c.gridy = 0;
    	c.insets = new Insets(10,10,10,10);
    	c.ipady = 20;
    	panel.add(label1,c);
    	
    	JButton label2 = new JButton("Test2");
    	c.gridx = 0;
    	c.gridy = 2;
    	c.ipady = 1;
    	c.gridheight = 1;
    	panel.add(label2,c);
    	
    	JButton label3 = new JButton("Test3");
    	c.gridx = 0;
    	c.gridy = 3;
    	panel.add(label3,c);
    	
    	JButton label4 = new JButton("Test4");
    	c.gridx = 0;
    	c.gridy = 4;
    	panel.add(label4,c);
    	
    	JButton label5 = new JButton("Test5");
    	c.gridx = 0;
    	c.gridy = 5;
    	panel.add(label5,c);
    	
    }
}
```


----------



## L-ectron-X (15. Okt 2012)

Nutze für die Aufteilung eines Frames am besten ein [JAPI]BorderLayout[/JAPI]. Dort hinein legst du dann weitere Panels mit passenden LayoutManagern, die dann deine Komponenten aufnehmen.
Die FAQ hilft da auch weiter.


----------



## Spacerat (15. Okt 2012)

1. Code wäre zu übertrieben...
2. JFrame mit BorderLayout
3. JPanel TOP mit height * 0.25 und FlowLayout
4. JPanel CENTER mit height * 0.75 und beliebigem Layout.
[EDIT]...ich hätt' jetzt gern einen Stock... vllt. komm' ich dann schneller voran. :lol:[/EDIT]


----------



## Niki (15. Okt 2012)

du musst das ganze mit weightx und weighty machen.

hier ein kleines beispiel


```
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;

public class MyFrame extends JFrame {

    public MyFrame() {
        super("MyFrame");
        guiInit();
        pack();
        setLocationRelativeTo(null);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }

    private void guiInit() {
        setLayout(new GridBagLayout());

        Insets i = new Insets(3, 3, 3, 3);
        GridBagConstraints c = new GridBagConstraints(0, 0, 1, 1, 1, 0.3, GridBagConstraints.NORTHWEST,
                GridBagConstraints.BOTH, i, 0, 0);

        JPanel p1 = new JPanel();
        p1.setBackground(Color.LIGHT_GRAY);
        JPanel p2 = new JPanel();
        p1.setBackground(Color.WHITE);

        add(p1, c);
        c.gridy++;
        c.weighty = 0.7;
        add(p2, c);

    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new MyFrame().setVisible(true);

            }
        });

    }

}
```


----------



## Juggl3r (15. Okt 2012)

Hallo,

danke schonmal.
Ich werd eure Kommentare gleich genauer anschauen, aber etwas anderes verwirrt mich immer noch etwas.

Damit ich das ganze Umsetzen kann, muss ich ja z.B.: zu meinem Hauptframe ein BorderLayout benutzen und dann sag ich, ja der erste Panel ist oben und der 2te Panel in der Mitte.

Jetzt benutze ich aber Register:

```
this.getContentPane().add(erstelleRegister(), BorderLayout.NORTH);
```

Passt da überhaupt das "BorderLayout.NORTH"?
Danach mache ich:

```
jRegisterTab = new JTabbedPane(JTabbedPane.TOP, JTabbedPane.SCROLL_TAB_LAYOUT);
		jRegisterTab.addTab("Produkte", erstelleProduktPanel());
```

Und bei erstelleProduktPanel() mache ich dann ein neues JPanel mit einem BorderLayout (wenn ich das vom ersten KOmmentar umsetzen möchte). Aber wegen dem BorderLayout.NORTH "pickt" das ja schon direkt oben alles.

Ist grad etwas blöd beschrieben, weil ich nicht weiß, wie ichs besser erklären soll, aber grob gesagt, wie schaff ich es, zu sagen, dass das "Register Panel" den gesamten Bildschirm benutzen soll?

edit: Hah, wenn man das North loescht und den Code vom vorherigen Poster (vielen Dank!!) nimmt, gehts perfekt  Jetzt kann ich mir das mal näher ansehen damit ich auch versteh warum  Danke nochmals an euch alle!


----------



## Juggl3r (15. Okt 2012)

Hey,

eine Frage hätte ich noch:
Das mit der Aufteilung passt jetzt eigentlich ganz gut.
Aber jetzt habe ich noch das Problem, das ich da Buttons auf der Oberfläche anordne und wenn das Fenster größer wird, werden die Buttons extrem groß.
Wie macht man das am Besten, dass die Buttons nicht ganz so groß werden (das ist total hässlich).
Ich hab auch schon sowas versucht:
suchenButton.setMaximumSize(new Dimension(20,20));

Das hat aber genau gar keine Auswirkung......

ps: Kann mir jemand irgend eine gute Resource empfehlen, wo ich mehr über Swing erfahre? Ich lese gerade ein Buch und schaue von Galileo Computing eine java DVD und die Forumsbeiträge zu Layoutmanager, aber das sind irgendwie alles nur einzelne Bruchteile, ich würde irgendwelche Beispiele brauchen wo wirklich komplexere Guis erstellt werden...

lg


----------



## jgh (15. Okt 2012)

versuch es mal mit 
	
	
	
	





```
setPreferedSize(new Dimension(20,20))
```
;

[edit]bzw. wenn der Button im BorderLayout liegt, bekommt er halt die gesamte Größe...das lässt sich einfach ändern, wenn du bspw. dort, wo du dem Button einfügst, ein JPanel mit dem Button übergibst[/edit]


----------



## Juggl3r (15. Okt 2012)

Super danke,

das setPreferredSize hat zwar mein ganzes Layout zerstört, aber mit maxSize + einem neuen Panel darin ohne LayoutManager (oder standardmanager?) hat es funktioniert 

Langsam begreife ich auch schon den ganzen Swing-Aufbau 

Eine letzte Frage hätte ich bitte noch.
*) Ich möchte mein Gesamtfenster in 2 Teile aufbauen. Der obere Teil hat eine fixe Höhe (z.b. 100 Pixel) und maximale Breite. Der untere Teilt nimmt den Rest der Höhe auch auch gesamte Breite.
*) Der obere Teil wird weiters unterteilt in 3 Bereiche. Links Buttons bzw. Labels mit fixer Größe, in der Mitte das Eingabefeld mit fixer Höhe, aber die Breite soll sich ändern, wenn das Fenster breiter wird und ganz rechts mit fixer Breite + Höhe zusätzliche Optionen.


Wie gehe ich so ein Layout am besten an? Mir würden schon kurz grobe Stichwörter wie "nimm den Layoutmanager mit den Einstellungen" schon reichen.
Und noch was: Würdet ihr so einen Aufbau empfehlen (mit fixer Größe für Buttons) oder macht ihr die Buttons immer mit dynamischer Größe?

lg


----------



## Spacerat (15. Okt 2012)

[OT]





Juggl3r hat gesagt.:


> Langsam begreife ich auch schon den ganzen Swing-Aufbau


Wir sprechen uns wieder, wenn du mal in die Bredullie kommst und deine GUI "dynamisch" brauchst. Also zur Laufzeit Komponenten hinzufügen oder entfernen willst.[/OT]
Zu deinem Problem: Das BorderLayout wäre auch hier eine Lösung, Layouts lassen sich glücklicherweise per Panels schachteln. Wollte man auf diese Schachtelung verzichten, gäbe es immer noch das GridBagLayout. Dann gibt es noch einen Layout-Manager, dessen Name mir grad' nicht einfallen will, der sich in etwa HTML-Like (Prozent-, Pixel- oder Maßangaben) konfigurieren lässt. Dieser ist aber afaik nur als PlugIn erhältlich.


----------



## Juggl3r (15. Okt 2012)

Hm ja, mit dem BorderLayout probier ich es auch gerade. Das ist nur alles sooooooooooo unendlich unlogisch -.-

Ok also was ich jetzt gemacht habe.
Das gesamte Frame mit Border Layout.
obererTeil -> NORTH
untererTeil -> CENTER

Den oberenTeil so unterteilt:
ObenLinks -> WEST
ObenMitte -> CENTER
ObenRechts -> EAST

Jetzt picken aber die Buttons im Bereich "ObenLinks" extrem weit Links am Rand. Und scheinbar ist es Unmöglich sie von dort wegzubekommen. Ich hab versucht beim Border Layout vom ganzen Frame hgaps anzulegen, beim oberenTeil hgaps und auch bei ObenLinks. Außerdem hab ich probiert beim Button selbst die setHorizontalAlignment auf Center zu setzen. Die Buttons bewegen sich von Links nicht weg.

Außerdem wird die Textbox, die ich in ObenMitte angelegt habe, nicht größer, aber ich glaub dazu muss ich darin noch ein anderes Layout anlegen.... Puhhhhhhhhhhhhh

edit: Und anscheinend ist es für mich auch unmöglich, dass die Textbox in ObenMitte die gesamte Breite benutzt -.-

edit2: ich muss nur noch irgendwie dieser textbox sagen, dass sie die maximale verfügbare Breite nehmen soll. Gibts dazu irgendeine Option? Momentan ist meine Textbox ganz dünn, wenn ich setPreferedSize nehme, kann ich wieder nur fixe Werte angeben. Gibts da keinen Trick, das ich sag "nimm die ganze Breite"? Oder muss ich da irgend ein bestimmten Layout Manager nehmen? Wenn ja, welchen?


----------



## jgh (15. Okt 2012)

eines nach dem anderen:


```
public static void main(String[] args) throws IOException {
		JFrame f = new JFrame();
		f.setSize(500, 200);
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		f.setLocationRelativeTo(null);

		JPanel obenPanel = new JPanel();
		obenPanel.setBackground(Color.RED);
		obenPanel.setPreferredSize(new Dimension(1, 100));
		f.add(obenPanel, BorderLayout.NORTH);

		JPanel centerPanel = new JPanel();

		f.add(centerPanel, BorderLayout.CENTER);
		f.setVisible(true);

	}
```

das macht dir immer eine -wenn möglich- 100px hohes Panel, der evtl. Rest kannst du dann einem JPanel centerPanel zuweisen....

Wenn du bspw. deine JButton´s weiter weg von Rand bekommen willst, bietet sich imho setInsets(Insets insets) auf die JButton´s an. 
Auch würde ich davon abraten, deinem oberen Panel ein BorderLayout zu geben, ein GridLayout bietet sich bspw. an, dann hast du dort 3 gleichgroße Bereiche. Den einzelnen Bereichen musst du dann wieder Layouts zuweisen, wie es deinen Anforderungen am besten entspricht

[edit]evtl. langt es dir der JTextbox beim Konstruktor einen festen Integer-Wert für die Anzahl an Zeichen mitzugeben, (bspw. new JTextfield(100)) oder du könntest ein GridLayout(0,0) nehmen, das dann eigentlich der Komponente den gesamten Platz (sowohl vertical, als auch horizontal) zuweist[/edit]


----------



## Juggl3r (15. Okt 2012)

Hm ja danke, soweit hatte ichs auch schon ungefähr.

Beim GridLayout beim oberenTeil habe ich das Problem, wenn das Fenster vergrößert wird, werden alle Teile vergrößert. Das mag ich nicht, das ist doch hässlich, wenn da so viel Platz ist?
Ich würde links sowas schreiben wie "Suchwort:" und darunter einen Suchen Button. Und in der Mitte möchte ich den Platz benutzen, wenn ich das Fenster vergrößere. Prinzipiell funktioniert das auch ganz gut, allerdings ist die Breite von meiner Textbox 0 und ich kann die werte nur hart festlegen, nicht sagen "benutz den Rest der dir zur verfügung steht").

Weiß jemand, wie ich das ändern kann? Hab hier noch ein Bild von meinem bisherigen Layout:

edit: Dem Konstruktor einen festen Wert übergeben ist wieder das gleiche Problem -> Statische Größe, die sich nicht ändert.
GridLayout(0,0) wirft eine Exception. Und wenn ich:

```
JPanel jp = new JPanel(new GridLayout(1,1));
		JTextField suchwortTextbox = new JTextField();
		jp.add(suchwortTextbox);
		obenMitte.add(jp);
```
mache, dann ist das Verhalten wieder genau gleich und die Textbox ist ganz dünn....

edit2: Endlich hab ichs geschafft. ICh muss NOCH ein BorderLayout drum machen und nochmal in der Mitte zuweisen.... die Logik dahinter boah...-.-

Danke an euch alle !!


----------



## bERt0r (16. Okt 2012)

Du kannst dir ja auch mal das Mig Layout anschaun, da kannst du Größenangaben in Prozent machen.


----------

