GridBagLayout - Größenverhältnisse bleiben nicht stabil

Status
Nicht offen für weitere Antworten.
Hallo,
ich habe folgendes Problem. Ich habe mein Hauptfenster unterteilt in 3 verschiedene JPanel sowie mehrere JButton.
In den 3 JPanels werden nu im Laufe des Programms verschiedene Komponenten zugefügt, diese wieder entfernt rumgezeichnet etc.
Der Code für meine Methode Hauptfenster.einrichten ist folgender:
Code:
public void einrichten(){
		 //Layout setzen und Komponenten hinzufügen
	    GridBagLayout gbl = new GridBagLayout();
	    GridBagConstraints gbc;
	    getContentPane().setLayout(gbl);
	    
	    //TextPanel hinzufügen
	    gbc = LayoutMethoden.makegbc(0, 0, 6, 1, 15, 5, true);
	    gbl.setConstraints(tPanel, gbc);
	    getContentPane().add(tPanel);
	    
	    //ZeichenPanel hinzufügen
	    gbc = LayoutMethoden.makegbc(0, 1, 3, 1, 15, 15, true);
	    gbl.setConstraints(zPanel, gbc);
	    zPanel.setBackground(Color.WHITE);
	    getContentPane().add(zPanel);
		    
	    // ArbeitsPanel hinzufügen
	    gbc = LayoutMethoden.makegbc(3, 1, 3, 1, 15, 15, true);
	    gbl.setConstraints(aPanel, gbc);
	    aPanel.setBackground(Color.LIGHT_GRAY);
	    getContentPane().add(aPanel);
			    
	    //Button hinzufügen
	    for (int i=0; i<5; i++){
	        gbc = LayoutMethoden.makegbc(i, 2, 1, 1, 3, 1, false);
	        gbl.setConstraints(playButtonGroup[i], gbc);
	        getContentPane().add(playButtonGroup[i]);
	    }
	    
	    //Geschwindigkeitsregler hinzufügen
	    gbc = LayoutMethoden.makegbc(5, 2, 1, 1, 3, 1, true);
        gbl.setConstraints(geschwindigkeitsRegler, gbc);
        getContentPane().add(geschwindigkeitsRegler);

	    //Dialogelemente layouten
	    validate();
	    //pack();
	  }
Die statische Methode LayoutMethoden.makegbc(int x, int y, int width, int height, double wx,
double wy, boolean fill) setzt die GridBagConstraints wie folgt:
Code:
//Methoden zur Festlegung von GridBagLayout-Bedingungen
	public static GridBagConstraints makegbc(int x, int y, int width, int height, double wx,
			double wy, boolean fill) {
		return makegbc(x, y, width,height,  wx, wy, GridBagConstraints.CENTER, fill);
	}

public static GridBagConstraints makegbc(int x, int y, int width, int height, double wx,
			double wy, int anchor, boolean fill) {
		GridBagConstraints gbc = new GridBagConstraints();
		gbc.gridx = x;
		gbc.gridy = y;
		gbc.gridwidth = width;
		gbc.gridheight = height;
		gbc.weightx= wx;
		gbc.weighty = wy;
		gbc.anchor = anchor;
		gbc.insets = new Insets(2, 2, 2, 2);
	
		if (fill)
			gbc.fill = GridBagConstraints.BOTH;
		else
			gbc.fill = GridBagConstraints.NONE;
		return gbc;
	}
Mein Problem ist das folgende: Eigentlich erwarte ich dass mein textPanel ein Drittel der Höhe einnimmt wie mein zeichenPanel und mein arbeitsPanel. (gbc.weighty ist beim textPanel 5, bei den anderen 2 Paneln 15.)
Das passt auch anfangs so ungefähr. Aber je nachdem, was ich in meine Panels einfüge, verändert sich dieses Verhältnis!?!?
Meinem Textpanel wird während des Programmverlaufs jeweils eine JEditorPane mit unterschiedlichem html-Text zugefügt, auf meinem zeichenPanel und arbeitsPanel diverse Zeichnungn vollführt.
Hat jemand eine Ahnung, warum sich die Größenverhältnisse ändern? Ich dachte, die sollten unabhängig davon sein, was eingefügt wird. Zum Teil wächst aber das textpanel auf fast die gesamte Seitenhöhe an, während auf meinem ZeichenPanel die Zeichnungen gequetscht werden.
Für 'nen Tip, wär ich dankbar.
 
Das GridBagLayout richtet sich immer nach der PreferredSize der Komponenten, es sei denn, das Panel ist zu klein (entweder zu wenig hoch oder zu wenig breit oder beides) als dass alle mit PreferredSize drauf passen. In dem Fall nimmt das GridBagLayout die MinimumSize der Komponenten. Das Gewicht bestimmt, in welchem Maßstab die Komponenten sich bzgl. der PrefferedSize (oder MinimumSize) vergrößern, wenn das Panel größer wird.

Ein Beispiel: Ein JLabel 1 hat den Text "Hallo", ein zweites JLabel 2 hat den Text "Ich bin ein JLabel". Beide JLabels liegen mit gleichem Gewicht 1.0 nebeneinander auf einem JPanel mit GridBagLayout. Das JLabel 1 möchte gern 100px breit sein, das JLabel 2 möchte gern 200px breit sein, das JPanel ist 300px breit. Beide JLabels haben genau ihre Lieblingsgröße. Vergrößert sich nun das JPanel auf das Doppelte seiner Größe (600px), dann vergrößert sich das erste JLabel auf 200px und das zweite JLabel auf 400px. Setzt man nun das Gewicht des zeiten JLabels auf 3.0, dann haben bei 300px JPanel-Breite die JLabels wie oben 100px und 200px, bei 600px JPanel-Breite hat des erste JLabel nun aber eine Breite von 150px und das zweite eine Breite von 450px.

Verkleinert man das Panel aber auf 200px, dann interessieren die PreferredSizes nicht mehr (denn die passen ja nicht mehr auf's JPanel). Dann werden die MinimumSizes genommen ─ ich erfinde bei beiden JLabels 10px. Dann wird das erste JLabel 50px breit und das zweite JLabel 150px breit sein.

Jetzt ändern wir die Größe des JPanels auf 300px. Alles wird in Lieblingsgröße angezeigt. Und nun ändern wir den Text des ersten JLabels auf "Ich bin jetzt länger". Schon passen nicht mehr beide Komponenten auf das JPanel. Und schon wird wieder die MinimumSize genommen.

Genau des selbe passiert in dem oben bezeichneten Beispiel. Ändert sich der Inhalt einer JTextArea, dann ändert sich auch seine PreferredSize. Und schon sieht das Layout komisch aus.

Lösungsvorschläge: Man kann alle PreferredSizes und MinimumSizes auf feste Werte setzen. Oder man kann auf die Spalte/Zeile -1 (Zelle -1×-1 nicht vergessen) Platzhalter in der richtigen Größe setzen (mit Box.createRigidArea() oder sowas) und bei allen anderen Komponenten weightx und weighty auf 0.0 setzen. Oder man nimmt ein anderes Layout?

Viel Erfolg in jedem Fall,
Ebenius
 
Zuletzt bearbeitet:
Hallo Ebenius,
ich glaube, ich habe das erste Mal die Wirkungsweise des GridBagLayout-Mangers verstanden. 😀 Warum steht das in keinem Java-Buch so drin?
Mal schauen, wie ich das jetzt umsetze.
Ich denk, ich werde die MinimumSize- und PreferredSize Werte auf fest vorgegebene Werte einstellen und dann mal schauen.
Danke für die konstruktive Antwort.
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben