LayoutManager GridBag richtig nutzen - Komponenten richtig anordnen und automatisch vergrößern

w00t

Aktives Mitglied
Hallo,

ich habe ein kleines GridBagLayout Problem.
Allgemeine Beschreibung:
Im Screenshot kann man sehen wie es aktuell aussieht. Dieses Panel liegt auf einem JFrame, das über ein JSplitPane geteilt wird (das auf dem Screenshot ist die rechte Seite, was links ist, ist hierfür irrelevant).

Problembeschreibung:
Um die Beschreibung etwas einfacher zu machen, teile ich die Oberfläche mal in zwei Teile:
  1. Linke Seite: Statische Komponenten. Panel1
  2. Rechte Seite: Dynamische Komponenten. Panel2

Nun möchte ich folgendes. Panel1 und Panel2 sollen immer am oberen linken Rand sein. Fest.
Wenn man das Fenster nun größer zieht, soll der Abstand zwischen den Panels gleich bleiben. Es sollen sich aber folgende Felder wie folgt vergrößern:
Panel1:
TextField Titel
ComboBox Typ
Button Speichern
Diese drei sollen sich nach rechts vergrößern, wenn das Fenster größer gezogen wird.

TextArea
Dieses Soll sich so weit nach unten strecken, so das der Button Speichern Platz hat und so das nach unten der Abstand fest bleibt. Das TextArea soll auch nach rechts größer werden.

Panel2:
Hier soll sich das zweite TextField (was in dem Screenshot die URL enthält) nach rechts ausstrecken, wenn das Fenster vergrößert wird.

Panel1:
Java:
	private JTextField tfTitleValue = null;
	private JComboBox cbTypeValue = null;
	private DefaultComboBoxModel cbTypeValueModel = null;
	private JTextArea taContent = null;
	private JButton bSave = null;

	private void createComponents() {
		final GridBagConstraints gbc = new GridBagConstraints();

		this.cbTypeValueModel = new DefaultComboBoxModel();

		this.tfTitleValue = new JTextField("");
		this.cbTypeValue = new JComboBox(this.cbTypeValueModel);
		this.cbTypeValue.addItemListener(this.controller);
		this.taContent = new JTextArea();
		this.taContent.setTabSize(2);

		gbc.insets = new Insets(10, 0, 0, 0);

		gbc.fill = GridBagConstraints.HORIZONTAL;
		gbc.gridx = 1;
		gbc.gridy = 1;
		gbc.gridwidth = 2;
		this.add(new JLabel("Ausgewähltes Element"), gbc);

		gbc.gridwidth = 1;
		gbc.gridx = 2;
		gbc.gridy = 2;
		gbc.ipadx = 75;
		this.add(new JLabel("Titel"), gbc);

		gbc.gridx = 3;
		gbc.ipadx = 2;
		this.add(this.tfTitleValue, gbc);

		gbc.gridx = 2;
		gbc.gridy = 3;
		gbc.ipadx = 75;
		this.add(new JLabel("Typ"), gbc);

		gbc.gridx = 3;
		gbc.ipadx = 2;
		this.add(this.cbTypeValue, gbc);

		JScrollPane spTaContent = new JScrollPane(this.taContent);
		gbc.gridx = 2;
		gbc.gridy = 4;
		gbc.gridwidth = 2;
		spTaContent.setPreferredSize(new Dimension(300, 150));
		this.add(spTaContent, gbc);

		gbc.gridx = 2;
		gbc.gridy = 5;
		gbc.gridheight = 1;
		gbc.gridwidth = 2;
		this.bSave = new JButton("Speichern");
		this.bSave.addActionListener(this.controller);
		this.add(this.bSave, gbc);

	}

Panel2:
Java:
	private JPanel pInformation = null;

	private void createComponents() {
		final GridBagConstraints gbc = new GridBagConstraints();
		gbc.gridwidth = 1;
		gbc.insets = new Insets(10, 0, 0, 0);

		gbc.fill = GridBagConstraints.HORIZONTAL;
		gbc.gridx = 1;
		gbc.gridy = 1;
		gbc.gridwidth = 2;
		this.add(new JLabel(PropertiesReader.getInstance().getProperties("application.gui.tree.form.additionaltitle")), gbc);

		gbc.gridx = 1;
		gbc.gridy = 2;
		gbc.gridwidth = 1;
		this.pInformation = new JPanel(new GridBagLayout());
		this.add(this.pInformation, gbc);

Hier werden die beiden Komponenten auf ein JFrame geschmissen:
Java:
	private void addComponentsToView() {
		final JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
		final GridBagConstraints gbc = new GridBagConstraints();
		JPanel basePanel = new JPanel(new GridBagLayout());

		gbc.gridx = 0;
		gbc.gridy = 0;
		gbc.anchor = GridBagConstraints.NORTHWEST;
		basePanel.add(this.infoPanel, gbc);

		gbc.anchor = GridBagConstraints.NORTHEAST;
		gbc.insets = new Insets(0, 10, 0, 0);
		gbc.gridx = 1;
		basePanel.add(this.additionalInfoPanel, gbc);

		// create scroll panes
		JScrollPane treeViewScrollPane = new JScrollPane(this.tree);
		JScrollPane scrollPaneView = new JScrollPane(basePanel);

		// order split pane components
		splitPane.setLeftComponent(treeViewScrollPane);
		splitPane.setRightComponent(scrollPaneView);

		// set minimum size
		treeViewScrollPane.setMinimumSize(new Dimension(200, 50));
		scrollPaneView.setMinimumSize(new Dimension(355, 50));

		// set size and divider location
		splitPane.setDividerLocation(200);
		splitPane.setPreferredSize(new Dimension(900, 350));

		// add to view
		this.view.add(splitPane);
	}

Ihr könnt auch gerne schreiben wenn ihr allgemein was zu dem Code zu sagen habt. Also wie man das allgemein besser machen könnte.


______________
Crosspost @ tutorials.de
 

Anhänge

  • fg_examplepic.JPG
    fg_examplepic.JPG
    15,9 KB · Aufrufe: 49
Zuletzt bearbeitet:
Hallo.
Ich will dir dein Problem nicht direkt lösen (zu faul 😉 ), kann dir aber sagen, was die entsprechenden Attribute beim GridBagLayout (GBL) sind.

Zunächste einmal verwende ich oft Hilfsmethoden zum erstellen der Contraints, dann hat man beim Layouting etwas mehr Übersicht, welche Koordinaten für welche Komponente sind:
Java:
private GridBagContraints gbc(int x, int y, int w, int h /*...und die weiteren params für den konstruktor*/) {
    return new GridBagConstraints(x, y, w, h, ...);
}

...

myContainer.setLayout(new GridBagLayout());
myContainer.add( labelHello, 
        gbc(0, 0, 1, 1, 1.0f, 0.0f, ...));

So. Zu den Contraints. Wichtig für das Vergrößern und Verkleinern sind weightx und weighty sowie fill:
Code:
gridx
= x-Position im Raster (Spalte)
Code:
gridy
= y-Position im Raster (Zeile)
Code:
gridwidth
= Anzahl der Spalten für die Komp. (>= 1)
Code:
gridheight
= Anzahl der Zeilen für die Komp. (>= 1)
Code:
weightx
= Vergrößerungsfaktor in x-Richtung (Horizontale), 0.0 heißt gar nicht "wachsen", 1.0 heißt dass die Komp. den ganzen freien Platz einnimmt. Ferner sollten innerhalb einer Zeile die Summen aller weightx nicht mehr als 1 ergeben, darüber kann man dann steuern, dass nebeneinanderliegende Komponenten sich den freien Platz entsprechend teilen
Code:
weighty
= analog zu weightx, nur eben für die Vertikale
Code:
anchor
= Platzierung der Komponente innerhalb ihrer Zelle, meist reicht BASELINE_LEADING aus, dann ist es linksbündig
Code:
fill
= Vergrößerungsverhalten innerhalb der Zelle. HORIZONTAL sagt, dass die Komp. die vollen horizontale Breite einnehmen soll, analog VERTICAL und eben BOTH für komplettes Ausfüllen und NONE für kein Wachstum.
Code:
insets
= (verwende ich nie, sie API 🙂 )
Code:
ipadx
= (dito)
Code:
ipady
= (dito)

Also für das Vergrößerungsverhalten solltest du dir vor allem die weight's und das fill anschauen. Als Beispiel etwas Code, der zwei Labels mit zugehörigen Textfeldern anordnet, wobei beim Vergrößern die Textfelder 80% des Platzes nehmen:

Java:
int base   = GridBagConstraints.BASELINE_LEADING;
int hori   = GridBagConstraints.HORIZONTAL;
Insets ins = new Insets(0, 0, 0, 0);

JPanel pnl = new JPanel(new GridBagLayout());
pnl.add(new JLabel("Vorname"),
    gbc(0, 0, 1, 1, 0.2d, 0.0d, base, ins, 0, 0));
pnl.add(new JTextField("Max"),
    gbc(1, 0, 1, 1, 0.8d, 0.0d, base, ins, 0, 0));
pnl.add(new JLabel("Nachname"),
    gbc(0, 1, 1, 1, 0.2d, 0.0d, base, ins, 0, 0));
pnl.add(new JTextField("Muster"),
    gbc(1, 1, 1, 1, 0.8d, 0.0d, base, ins, 0, 0));
 
Ich danke euch schon einmal, werde das mal testen und dann eine Rückmeldung geben 🙂 Da habe ich den ein oder anderen Parameter doch tatsächlich etwas falsch interpretiert.

Und danke für den Tipp mit den Methoden zum GBC oder hinzufügen, darauf hätte ich auch selber kommen können.
 
Ich danke euch vielmals. Das hat mir sehr viel geholfen. Habe es nun hinbekommen. "Anchor" und "weightx" bzw "weighty" haben mir sehr weiter geholfen.
byte-welt.net war auch ein sehr guter Tipp 🙂
 

Zurück
Oben