LayoutManager Zeilenweise Anordnung von Panels

Bizarrus

Bekanntes Mitglied
Hallöchen.
Bin ein wenig am verzweifeln, da ich diverse JPanels anordnen möchte,...

Ich habe ein JFrame, aufdem ein JScrolledPanel hinzugefügt ist. In diesem ist ein JPanel vorhanden.
In diesem JPanel sollen nun X beliebige JPanels geadded werden, die untereinander angereiht werden. Die Anordnung sollte speziell sein:

Die Panels müssen eine 100-prozente breite haben, egal wie das Fenster nun vergrößert/verkleinert wird. Andersherum aber keine 100-prozente höhe. Habe schon einige LayoutManager ausprobiert, einige ziehen beispielsweise alle Panels auf die ganze Fensterhöhe und passt dementsprechend die Höhen der einzelnen Panels an, dies ist aber nicht gewollt.

Hat jemand vielleicht eine Idee, wie ich des anstelle?

Und so soll dies ausschauen:
 

Anhänge

  • scrollpanelundso85c7b.jpg
    scrollpanelundso85c7b.jpg
    67,3 KB · Aufrufe: 41
Zuletzt bearbeitet von einem Moderator:
Did'nt work.
Genau das selbe wie sonst.

Die höhe passt sich immer wieder automatisch an (was es nicht soll).
Auch die Seite hatte ich bereits mehrfach auf gehabt ^^

Hier, Sofern das Fenster resized wird, soll sich die Breite zwar anpassen, aber die höhe der einzelnen Panels nicht: ‪screen.avi‬‏ - YouTube

Die Panels habe ich verschiedenfarbig eingefärbt...
 
Schon mal das TableLayout angeschaut?
TableLayout
Damit kannst du deinen Spalten-/Zeilenhöhen einen prozentualen Wert geben, oder, falls es komplett vorgegeben sein soll, auch eine absolute Höhe in Pixeln.
Achja, die Angaben kannst du natürlich auch mischen. Zum Beispiel erste Spalte 100% Breite, erste Zeile 40 Pixel.
 
In Eclipse gibt es anscheinend kein TableLayout. Zudem verstehe ich leider die Größen-Parameter nicht. Wie ist dies aufgebaut? Auf welche parameter muss ich da achten? Wie kann ich TableLayout in eclipse nutzen?

Oder gibts andere LayoutManager, die einfacher sind?

EDIT:
Gerade gesehen, dass dort eine JAR-File herunter geladen werden kann. Des muss ich wahrscheinlich im Projekt setzen, richtig? Sry, aber externe Jars bzw Libs darf ich/möchte ich leider nicht benutzen.
 

Bin gerade dabei hiermit herumzuwurschteln, sieht schon für den Anfang nicht schlecht aus.
Nun leider gibt es auch hier ein kleines Problem:
Obwohl ich den "Hauptpanel" eine größe zugewiesen habe, sind die inneren Panels Zentriert und klein (also beispeislweise von der breite niocht ausgefüllt). Das ausrichten auf NORTH bzw NORTHWEST funktioniert auch nicht.

Gibts da noch etwas zu beachten?
 
Zuletzt bearbeitet:
Ja,
Code:
gbc.weighty = 1.0;
z.B. Aber nur an der untersten Komponente.
Wenn das dann noch nicht funktioniert, solltest du die Einstellungen von
Code:
gbc.anchor = GridBagConstraints.NORTH;
auch an die anderen Komponenten hängen.
 
Das setzen von weighty (einmal bei allen Elementen, als auch nur beim aller letzten) bring leider nicht das gewünschte ergebniss. Auch das Setzen auf NORTH leider nicht.
 
Java:
	public static void main(String[] args) {
		final JFrame f = new JFrame();
		f.setPreferredSize(new Dimension(100,100));
		
		JPanel p = new JPanel();
		p.setLayout(new GridBagLayout());
		
		JPanel r = new JPanel();
		r.setBackground(Color.RED);
		r.setPreferredSize(new Dimension(100,100));
		JPanel g = new JPanel();
		g.setBackground(Color.GREEN);
		g.setPreferredSize(new Dimension(100,30));
		JPanel b = new JPanel();
		b.setBackground(Color.BLUE);
		b.setPreferredSize(new Dimension(100,60));
		
		GridBagConstraints gbc = new GridBagConstraints();
		
		gbc.fill=GridBagConstraints.HORIZONTAL;
		gbc.anchor=GridBagConstraints.NORTH;
		
		
		gbc.weightx=1;
		gbc.weighty=0;
		gbc.gridy=0;
		p.add(r,gbc);
	
		gbc.weightx=1;
		gbc.weighty=0;
		gbc.gridy=1;
		p.add(g,gbc);
		
		gbc.weightx=1;
		gbc.weighty=1;
		gbc.gridy=2;
		p.add(b,gbc);
		
		
		JScrollPane jsp = new JScrollPane(p);
		
	
		f.add(jsp);
		f.pack();
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		SwingUtilities.invokeLater(new Runnable(){
			@Override
			public void run() {
				f.setVisible(true);				
			}
		});
	}
 
So wie ich erkennen kann muss es dann wie folgt gesetz werden:

- weightx bleibt bei jedem Element auf 1
- weighty = 1 bekommt nur das letzte Element
- gridy wird für jedes Element hochgezählt (i++)

Oder verstehe ich dies falsch?
Danke für das Beispiel
 
Genau so. Wenn du jetzt in einer Reihe mehrere Elemente haben willst musst du das natürlich anpassen:

Java:
	public static void main(String[] args) {
		final JFrame f = new JFrame();
		f.setPreferredSize(new Dimension(100,100));
		
		JPanel p = new JPanel();
		p.setLayout(new GridBagLayout());
		
		JPanel r = new JPanel();
		r.setBackground(Color.RED);
		r.setPreferredSize(new Dimension(100,100));
		JPanel g = new JPanel();
		g.setBackground(Color.GREEN);
		g.setPreferredSize(new Dimension(100,30));
		JPanel b = new JPanel();
		b.setBackground(Color.BLUE);
		b.setPreferredSize(new Dimension(100,60));
		JPanel y = new JPanel();
		y.setBackground(Color.YELLOW);
		y.setPreferredSize(new Dimension(100,60));
		
		GridBagConstraints gbc = new GridBagConstraints();
		
		gbc.fill=GridBagConstraints.HORIZONTAL;
		gbc.anchor=GridBagConstraints.NORTH;
		
		
		gbc.weightx=1;
		gbc.weighty=0;
		gbc.gridwidth=2;
		gbc.gridy=0;
		p.add(r,gbc);
	
		gbc.weightx=1;
		gbc.weighty=0;
		gbc.gridwidth=2;
		gbc.gridy=1;
		p.add(g,gbc);
		
		gbc.weightx=0.5;
		gbc.weighty=1;
		gbc.gridwidth=1;
		gbc.gridy=2;
		p.add(b,gbc);
		
		gbc.weightx=0.5;
		gbc.weighty=1;
		gbc.gridwidth=1;
		gbc.gridy=2;
		p.add(y,gbc);
		
		
		
		JScrollPane jsp = new JScrollPane(p);
		
	
		f.add(jsp);
		f.pack();
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		SwingUtilities.invokeLater(new Runnable(){
			@Override
			public void run() {
				f.setVisible(true);				
			}
		});
	}
 
Okay, dann weiß ich schonmal wie es Theoretisch funktionieren würde. Nun leider gibts da aber anscheinend noch ein kleiner Denkfehler.

Habe des nun in einer for-Schleife gepackt um des zu testen. messages ist eine Vector mit X beliebigen Strings,...

Java:
// Main
		JPanel output = new JPanel();
		output.setLayout(new GridBagLayout());
		
		// Settings
		GridBagConstraints constraints = new GridBagConstraints();
		constraints.fill = GridBagConstraints.HORIZONTAL;
		constraints.gridheight = GridBagConstraints.RELATIVE;
		constraints.gridwidth = GridBagConstraints.REMAINDER;
		constraints.weightx = 1.0;
		//constraints.insets = new Insets( 5, 5, 5, 5 );
		 

		constraints.anchor = GridBagConstraints.NORTH;
		

    
		// Other
		Color cl = Color.WHITE;
		for(int i = 0; i < messages.size(); i++) {
			String element = messages.get(i);
			JPanel test = new JPanel();
			cl = cl.darker();
			test.setBackground(cl);
			test.setBorder(BorderFactory.createLineBorder(Color.black));
			test.add("West", new JTextArea(element));
			//test.setPreferredSize(new Dimension(Integer.parseInt(window_width) - Integer.parseInt(window_rightsize), 20));

	        
	        // last
			if(i == messages.size() - 2) {
				constraints.weighty = 1;
			} else {
				constraints.weighty = 0;
			}
			
	        constraints.gridy = i;
			output.add(test, constraints);
		}
		
		
		//output.setPreferredSize(new Dimension(Integer.parseInt(window_width) - Integer.parseInt(window_rightsize), Integer.parseInt(window_height) - Integer.parseInt(window_bottomsize) - Integer.parseInt(window_buttonsize)));
		
		JScrollPane scroll_main = new JScrollPane(output); // OUTPUT
 
Nein, in deinem Fall genügt, wenn eines der Panels
Code:
weightx = 1.0;
erhält. Es geht aber natürlich auch, wenn du es an allen Panels gesetzt hast.

Stimmt natürlich. Da man aber das eine Constraints-Objekt weiterverwendet schreib ich es lieber nochmal hin.
Das spart einem manchmal das Debuggen, weil man Fehler schneller sieht.😉
 
Okay, dann weiß ich schonmal wie es Theoretisch funktionieren würde. Nun leider gibts da aber anscheinend noch ein kleiner Denkfehler.

Habe des nun in einer for-Schleife gepackt um des zu testen. messages ist eine Vector mit X beliebigen Strings,...

Java:
// Main
		JPanel output = new JPanel();
		output.setLayout(new GridBagLayout());
		
		// Settings
		GridBagConstraints constraints = new GridBagConstraints();
		constraints.fill = GridBagConstraints.HORIZONTAL;
		constraints.gridheight = GridBagConstraints.RELATIVE;
		constraints.gridwidth = GridBagConstraints.REMAINDER;
		constraints.weightx = 1.0;
		//constraints.insets = new Insets( 5, 5, 5, 5 );
		 

		constraints.anchor = GridBagConstraints.NORTH;
		

    
		// Other
		Color cl = Color.WHITE;
		for(int i = 0; i < messages.size(); i++) {
			String element = messages.get(i);
			JPanel test = new JPanel();
			cl = cl.darker();
			test.setBackground(cl);
			test.setBorder(BorderFactory.createLineBorder(Color.black));
			test.add("West", new JTextArea(element));
			//test.setPreferredSize(new Dimension(Integer.parseInt(window_width) - Integer.parseInt(window_rightsize), 20));

	        
	        // last
			if(i == messages.size() - 2) {
				constraints.weighty = 1;
			} else {
				constraints.weighty = 0;
			}
			
	        constraints.gridy = i;
			output.add(test, constraints);
		}
		
		
		//output.setPreferredSize(new Dimension(Integer.parseInt(window_width) - Integer.parseInt(window_rightsize), Integer.parseInt(window_height) - Integer.parseInt(window_bottomsize) - Integer.parseInt(window_buttonsize)));
		
		JScrollPane scroll_main = new JScrollPane(output); // OUTPUT

Code:
test.add("West", new JTextArea(element));
<-- falsch herum: erst Komponente dann Constraint
Code:
if(i == messages.size() - 2) {
<-- ist die vorletzte Komponente, du willst aber die letzte
 
Es funktioniert nun. Es lag daran, dass noch gridheight mit RELATIVE gesetzt war. Ich danke euch vielmals für die sehr gute Hilfe 🙂
 

Zurück
Oben