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

w00t

Grünschnabel
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 @ java-forum.org
 

Anhänge

  • fg_examplepic.JPG
    fg_examplepic.JPG
    12,2 KB · Aufrufe: 34

Fabio Hellmann

Erfahrenes Mitglied
Hi,
ich denke mal mit einem GridLayout/BorderLayout ist dir fast besser geholfen. Da das mit dem GridBagLayout sehr umständlich werden kann.

Gruß

Fabio
 

w00t

Grünschnabel
Hi Fabio,

in wie weit ist das denn mit den Layouts einfacher? Habe vorher immer Layouts ohne LayoutManager gemacht, und wollte das halt mal ändern. Hab das mit BorderLayout und GridLayout nicht annähernd so schnell so hinbekommen wie es aktuell ist.
 
Zuletzt bearbeitet:

Fabio Hellmann

Erfahrenes Mitglied
Also erstmal ich heiße Fabio. ;)
Da du das Panel1 statisch haben willst, kannst du im grunde genommen das GridBagLayout verwenden, oder eben über feste Positionsangaben die Komponenten setzen. Bei dem Panel2, welches dynamisch Größenveränderbar sein soll, würde ich je nachdem wie die Komponenten angeordnet werden sollen mich für ein Layout entscheiden.
Wenn du nur zwei Textfelder (linke klein, rechte groß) haben willst, kannst du das ganz einfach mit dem BorderLayout machen.

Java:
panel2.setLayout(new BorderLayout());

panel2.add(new Text(), BorderLayout.WEST);
panel2.add(new Text(), BorderLayout.CENTER);

Das nur mal so als Beispiel.

Dem BorderLayout kannst du bei Bedarf auch noch über den Konstruktor eine Patternangabe für den Abstand zum oberen und linken Rand.
 

w00t

Grünschnabel
Hi Fabio,
Sorry, richtig gelesen, falsch geschrieben ;)

Also das linke ist deshalb statisch, weil die Felder dort immer gleich sind.
Das rechte ist deshalb dynamisch, weil dort mal keine Felder sein können, oder auch mehr als die auf dem Screenshot zu sehenden 2 Felder. Das ist quasi eine Liste.

Dass BorderLayout auch so einen Abstand haben kann, das wusste ich nicht. Müsste ich mal nach schauen. Aber wie ist das mit der Anordnung des linken Panels? Dort sollen sich ja viele Felder auch automatisch mit vergrößern.
 

Fabio Hellmann

Erfahrenes Mitglied
Ich würde dir empfehlen dir mal das hier durchzulesen. Das ist eine gute Beschreibung, wie man die unterschiedlichen Layouts verwendet. Das kannst du dann auch ganz einfach auf dein Programm übertragen.

Wenn du danach immer noch Fragen zu den Layouts hast, nur zu. ;)