# Wieder ne Layout Frage



## GUI-Programmer (5. Nov 2011)

Ich habe ja bereits in einem anderen Thread, und zwar in Kurze Layout Frage danach gefragt, welches Layout man benutzen sollte, um einen einzelnen Komponenten mittig in ein Panel zu positionieren (hilfreichste Antwort von L-ectron-X: GridBagLayout).
Grund hierfür war, dass ich schon eine ganze Zeit lang versucht habe, Komponent an exakten Stellen (=Pixeln --> Koordinaten) zu positionieren, die sehr unterschiedlich sein sollen, ohne das NullLayout zu verwenden (Gründe hierfür sind wohl bekannt!). Hauptgrund war, dass ich nach dem Positionieren möchte, dass die Komponenten dennoch auf Größenveränderungen (z.B. bei Frame) reagieren.
Anfangs habe ich dies durch mühsame Berechnungen in der componentResized()-Methode auch erreicht (bie NullLayout). Jedoch ist auch dies eine schlechte Vorgehensweise.

Daher nun mein letzter Stand, um mein Vorhaben umzusetzen: jgoodies FormLayout
Beispiel:

```
import java.awt.EventQueue;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import com.jgoodies.forms.layout.FormLayout;
import com.jgoodies.forms.layout.ColumnSpec;
import com.jgoodies.forms.layout.RowSpec;

public class MyExample1 extends JPanel {
	protected JButton btnButton1, btnButton2;

	public MyExample1() {
		setPreferredSize(new Dimension(500, 350));
		setFormLayout(this, 500, 350);
		
		btnButton1 = new JButton("Button 1");
		btnButton1.setPreferredSize(new Dimension(180, 25));
		add(mittig(btnButton1), "101, 11, 180, 25, fill, fill");
		
		btnButton2 = new JButton("Button 2");
		btnButton2.setPreferredSize(new Dimension(160, 75));
		add(btnButton2, "301, 41, 160, 75, fill, fill");
		
	}
	
	private JPanel mittig(JComponent comp) {
		JPanel panel = new JPanel();
		panel.setOpaque(false);
		panel.setLayout(new GridBagLayout());
		panel.add(comp);
		return panel;
	}
	
	private void setFormLayout(JPanel panel, int width, int height) {
		ColumnSpec[] columnspec = new ColumnSpec[width];
		for(int i=0; i<columnspec.length; i++) {
			columnspec[i] = ColumnSpec.decode("1px:grow");
		}
		RowSpec[] rowspec = new RowSpec[height];
		for(int i=0; i<rowspec.length; i++) {
			rowspec[i] = RowSpec.decode("1px:grow");
		}
		panel.setLayout(new FormLayout(columnspec, rowspec));
	}
	
	private static void createFrame() {
		JFrame f = new JFrame("MyExample");
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		f.setContentPane(new MyExample1());
		f.pack();
		f.setVisible(true);
	}
	
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				createFrame();
			}
		});
	}
}
```

Nun meine Frage an euch: Gibt es bessere Möglichkeiten???


----------



## GUI-Programmer (6. Nov 2011)

Nun wie siehts aus? Gibt es nun, nicht speziell bessere, sondern andere Möglichkeiten oder habe ich hier schon eine der besten angewandt?


----------



## turtle (6. Nov 2011)

Ich nehme auch immer das jgoodies FormLayout und baue die UIs mit dem Abeille-Builder.

Die Konstruktion der GUI kann in XML oder in proprietären Binärdateien gespeichert werden und das Erzeugen der UI beschränkt sich auf wenige CodeZeilen:


```
class DeinPanel extends FormPanel 
	public DeinPanel (String s) {
		super(s);
	}
```
Laden der Gui-Definitionsdatei

```
DeinPanel deinPanel = new DeinPanel("resources/frm/GuiBeschreibung.xml");
```

Ich nehme keinen anderen Ansatz zur Erzeugung einer GUI mehr. Vielleicht ist das auch für Dich einen Versuch wert?


----------



## GUI-Programmer (6. Nov 2011)

Also momentan benutze ich ja den WindowBuilder (Eclipse) und bin damit auch sehr zufrieden. Gibt es irgendwelch Alternativen zu den Abeile-Builder??? (Im Vergleich zum WindowBuilder viel zu klein!)

Und bitte noch mal meine ursprüngliche Frage beantworten!


----------



## bERt0r (6. Nov 2011)

Also ich nutze auch den WindowBuilderPro von Google, bin aber an GroupLayout Anhänger. Welches Layout du benutzt liegt im Endeffekt an deinen persönlichen Vorlieben. Die "besseren" Layoutmanager (forms, mig, group, gridbag) können eigentlich alles realisieren, es kommt nur darauf an wie viel Aufwand damit einhergeht.
Bezüglich deinem Problem mit den Pixelangeben: z.B im Grouplayout kannst du genau angeben, wieviele Pixel ein Component vom nächsten entfernt sein soll oder du fügst einen "Gap" ein, der quasi als Glue a la BoxLayout fungiert.


----------



## XHelp (6. Nov 2011)

Schau dir doch einfach mal die Standard-Layouts mal an (da gibt es sogar FAQ-Beiträge dazu), dann weißt du auch, welches was kann und musst nicht jedes mal fragen.


----------



## GUI-Programmer (6. Nov 2011)

XHelp hat gesagt.:


> Schau dir doch einfach mal die Standard-Layouts mal an (da gibt es sogar FAQ-Beiträge dazu), dann weißt du auch, welches was kann und musst nicht jedes mal fragen.



Das hab ich schon oft genug gemacht!!!


----------



## Harry Kane (6. Nov 2011)

GUI-Programmer hat gesagt.:


> Nun meine Frage an euch: Gibt es bessere Möglichkeiten???


Also ich finde das hier besser (erstellt mit MigLayout).
Ein paar Erläuterungen zur Instanziierung des Layouts:
*Erster String*: Parameter fürs ganze Layout: debug -> Zeichnen von nützlichen Hilfslinien, fill: zeit an dass der Container den gesamten zur Verfügung stehenden Platz beanspruchen soll.
*Zweiter String*: Parameter für die Spalten: die Komponenten in einer Spalte sollen mittig angeordnet sein
*Dritter String*: Parameter für die Zeilen. Aufgrund des fill-Parameters im ersten String werden die Zeilen und Spalten vergrössert, wenn das JPanel grösser wird, was wiederum der Fall ist wenn es direkt als Center im BorderLayout einer Content Pane eines JFrames angelegt ist.
Hier ist angegeben dass die erste Zeile nicht wachsen soll, und der ganze beim vergrössern zur Disposition stehden Platz der zweiten Zeilen zugeschlagen werden soll. 

```
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import net.miginfocom.swing.MigLayout;

public class CenteredButton{
	public static void main(String[] args){
		JFrame frame = new JFrame("Centered Button");
		JPanel panel = new JPanel(new MigLayout("debug, fill","center","[grow 0][align center, grow 100]"));
		JButton center = new JButton("Center");
		center.setPreferredSize(new Dimension(80,120));
		//Die erste Zeile erstreckt sich auch über die gesamte Breite des JPanels (fill-Parameter).
		// Hier wird festgelegt, dass die Komponente in der Zeile linksbündig positioniert werden soll
		// Mit wrap wird in die nächste Zeile umgebrochen
		panel.add(new JButton("Left aligned in First Row"), "align left, wrap");
		panel.add(center);
		//panel.add(new JButton("Centered 2"));
		frame.getContentPane().add(panel);
		frame.pack();
		frame.setVisible(true);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
}
```


----------



## GUI-Programmer (6. Nov 2011)

@Harry Kane Und wenn ich jetzt 6, 7 weitere Komponent hätte, deren Koordinaten sehr verschieden wären und nur ein vergrößert/verkleinert werden soll, und ein anderer Teil nur wie in meinen Beispiel verschoben werden soll?


----------



## Harry Kane (6. Nov 2011)

Die Frage ist ziemlich allgemein formuliert, was soll man genauer zu sagen?
Deshalb eine allgemeine Antwort:
MigLayout eignet sich zur Erstellung tabellenartiger Dialog, wobei in jeder Zelle eine oder mehrere Komponenten stehen können. Wenn eine tabellenartige Anordnung bei deinen "6,7 weiteren Komponenten" auch sinnvoll ist, und du eine Komponenten wachsen lassen möchtest wenn das JPanel grösser wird, musst du nur für die entsprechende Zelle in den Zeilen-und Spaltenparametern angeben dass sie wachsen soll, und du musst der Komponenten erlauben, dass sie "mit der Zelle wächst". Entferne mal die Kommentarzeichen in Zeile 17 vor  
	
	
	
	





```
//panel.add(new JButton("Centered 2"));
```
und ersetze sie durch 

```
panel.add(new JButton("Centered 2"), "grow");
```


----------



## turtle (7. Nov 2011)

Der WindowBuilder von Google ist auch gut. Ich habe mal zwei Versionen gebaut, die einen Button zentriert in einem Panel anzeigen und das auch auf Grössenänderungen reagiert.
Zunnächst der Code für den WindowBuilder:

```
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

import com.jgoodies.forms.factories.FormFactory;
import com.jgoodies.forms.layout.ColumnSpec;
import com.jgoodies.forms.layout.FormLayout;
import com.jgoodies.forms.layout.RowSpec;

@SuppressWarnings("serial")
public class Demo extends JPanel {

	/**
	 * Create the panel.
	 */
	public Demo() {
		setLayout(new FormLayout(new ColumnSpec[] {
				ColumnSpec.decode("default:grow"),
				FormFactory.RELATED_GAP_COLSPEC, FormFactory.DEFAULT_COLSPEC,
				FormFactory.RELATED_GAP_COLSPEC,
				ColumnSpec.decode("default:grow"), }, new RowSpec[] {
				FormFactory.GLUE_ROWSPEC, FormFactory.RELATED_GAP_ROWSPEC,
				FormFactory.DEFAULT_ROWSPEC, FormFactory.RELATED_GAP_ROWSPEC,
				FormFactory.GLUE_ROWSPEC, }));

		JButton btnZentriert = new JButton("Zentriert");
		add(btnZentriert, "3, 3, fill, fill");

	}

	public static void main(String[] args) {
		JFrame frame = new JFrame("Demo");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.add(new Demo());
		frame.pack();
		frame.setVisible(true);
	}
}
```
Und für Abeille:

```
import javax.swing.JFrame;

import com.jeta.forms.components.panel.FormPanel;

@SuppressWarnings("serial")
public class Abeille extends FormPanel{

	public Abeille(String panel) {
		super(panel);
	}

	public static void main(String[] args) {
		JFrame frame = new JFrame("Demo");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.add(new Abeille("panel.xml"));
		frame.pack();
		frame.setVisible(true);

	}

}
```

Hier steckt der ganze GUI-Beschreibung in der panel.xml-Datei. Hier ist der Inhalt:
[XML]
<?xml version="1.0" encoding="UTF-8"?>

<object classname="com.jeta.forms.store.memento.FormPackage">
 <at name="fileversion">
  <object classname="com.jeta.forms.store.memento.FormsVersion2">
   <at name="major">2</at>
   <at name="minor">0</at>
   <at name="sub">0</at>
  </object>
 </at>
 <at name="form">
  <object classname="com.jeta.forms.store.memento.FormMemento">
   <super classname="com.jeta.forms.store.memento.ComponentMemento">
    <at name="cellconstraints">
     <object classname="com.jeta.forms.store.memento.CellConstraintsMemento">
      <at name="column">1</at>
      <at name="row">1</at>
      <at name="colspan">1</at>
      <at name="rowspan">1</at>
      <at name="halign">default</at>
      <at name="valign">default</at>
      <at name="insets" object="insets">0,0,0,0</at>
     </object>
    </at>
    <at name="componentclass">com.jeta.forms.gui.form.FormComponent</at>
   </super>
   <at name="id">Vfe94839G1337dfa51c6FU8000</at>
   <at name="rowspecs">CENTEREFAULT:GROW(1.0),CENTEREFAULT:NONE,CENTEREFAULT:GROW(1.0)</at>
   <at name="colspecs">FILLEFAULT:GROW(1.0),FILLEFAULT:NONE,FILLEFAULT:GROW(1.0),FILLEFAULT:NONE</at>
   <at name="components">
    <object classname="java.util.LinkedList">
     <item >
      <at name="value">
       <object classname="com.jeta.forms.store.memento.BeanMemento">
        <super classname="com.jeta.forms.store.memento.ComponentMemento">
         <at name="cellconstraints">
          <object classname="com.jeta.forms.store.memento.CellConstraintsMemento">
           <at name="column">2</at>
           <at name="row">2</at>
           <at name="colspan">1</at>
           <at name="rowspan">1</at>
           <at name="halign">default</at>
           <at name="valign">default</at>
           <at name="insets" object="insets">0,0,0,0</at>
          </object>
         </at>
         <at name="componentclass">com.jeta.forms.gui.form.StandardComponent</at>
        </super>
        <at name="jetabeanclass">com.jeta.forms.gui.beans.JETABean</at>
        <at name="beanclass">javax.swing.JButton</at>
        <at name="beanproperties">
         <object classname="com.jeta.forms.store.memento.PropertiesMemento">
          <at name="classname">javax.swing.JButton</at>
          <at name="properties">
           <object classname="com.jeta.forms.store.support.PropertyMap">
            <at name="text">Zentriert</at>
            <at name="height">23</at>
            <at name="width">77</at>
            <at name="name"></at>
            <at name="actionCommand">Zentriert</at>
            <at name="border">
             <object classname="com.jeta.forms.store.properties.CompoundBorderProperty">
              <super classname="com.jeta.forms.store.properties.BorderProperty">
               <at name="name">border</at>
              </super>
              <at name="borders">
               <object classname="java.util.LinkedList">
                <item >
                 <at name="value">
                  <object classname="com.jeta.forms.store.properties.DefaultBorderProperty">
                   <super classname="com.jeta.forms.store.properties.BorderProperty">
                    <at name="name">border</at>
                   </super>
                  </object>
                 </at>
                </item>
               </object>
              </at>
             </object>
            </at>
           </object>
          </at>
         </object>
        </at>
       </object>
      </at>
     </item>
    </object>
   </at>
   <at name="properties">
    <object classname="com.jeta.forms.store.memento.PropertiesMemento">
     <at name="classname">com.jeta.forms.gui.form.GridView</at>
     <at name="properties">
      <object classname="com.jeta.forms.store.support.PropertyMap">
       <at name="name"></at>
       <at name="fill">
        <object classname="com.jeta.forms.store.properties.effects.PaintProperty">
         <at name="name">fill</at>
        </object>
       </at>
       <at name="scollBars">
        <object classname="com.jeta.forms.store.properties.ScrollBarsProperty">
         <at name="name">scollBars</at>
         <at name="verticalpolicy">21</at>
         <at name="horizontalpolicy">31</at>
        </object>
       </at>
       <at name="border">
        <object classname="com.jeta.forms.store.properties.CompoundBorderProperty">
         <super classname="com.jeta.forms.store.properties.BorderProperty">
          <at name="name">border</at>
         </super>
         <at name="borders">
          <object classname="java.util.LinkedList"/>
         </at>
        </object>
       </at>
      </object>
     </at>
    </object>
   </at>
   <at name="cellpainters">
    <object classname="com.jeta.forms.store.support.Matrix">
     <at name="rows">
      <object classname="[Ljava.lang.Object;" size="3">
       <at name="item" index="0">
        <object classname="[Ljava.lang.Object;" size="4"/>
       </at>
       <at name="item" index="1">
        <object classname="[Ljava.lang.Object;" size="4"/>
       </at>
       <at name="item" index="2">
        <object classname="[Ljava.lang.Object;" size="4"/>
       </at>
      </object>
     </at>
    </object>
   </at>
   <at name="rowgroups">
    <object classname="com.jeta.forms.store.memento.FormGroupSet">
     <at name="groups">
      <object classname="java.util.HashMap"/>
     </at>
    </object>
   </at>
   <at name="colgroups">
    <object classname="com.jeta.forms.store.memento.FormGroupSet">
     <at name="groups">
      <object classname="java.util.HashMap"/>
     </at>
    </object>
   </at>
  </object>
 </at>
</object>
[/XML]


----------



## GUI-Programmer (7. Nov 2011)

turtle hat gesagt.:


> Der WindowBuilder von Google ist auch gut.



Den benutz ich ja momentan!!!


----------

