Swing Weight in GridBagLayout

Status
Nicht offen für weitere Antworten.

Hinde

Mitglied
Hallo Leute!
Ich bin neu hier und hab mich aus reiner Verzweiflung angemeldet,
ich Programmiere Java jetzt ca ein halbes Jahr so ein wenig Nebenher.
Jetzt wollte ich ne GUI mit dem GridBagLayout machen,
funktioniert auch alles ganz gut, nur diese Labels nehmen einfach zu viel Platz ein.

Hier mal der Quelltext:

Java:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JTextField;


public class GridBag extends JPanel implements AdjustmentListener, KeyListener, ActionListener {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	// alle Labels haben ein l als Kürzel vor dem Namen
	private JLabel lAbschusswinkel, lAnfangshoehe, lAnfangsgeschwindigkeit, lFallbeschleunigung, lFlugzeit, lAufprallgeschwindigkeit, lMaxHoehe, lMaxFlugweite;
	// alle Scrollbars haben ein sb als Kürzel vor dem Namen
	private JScrollBar sbAbschusswinkel, sbAnfangshoehe, sbAnfangsgeschwindigkeit, sbFallbeschleunigung;
	// alle TextFields haben ein tf als Kürzel vor dem Namen
	private JTextField tfAbschusswinkel, tfAnfangshoehe, tfAnfangsgeschwindigkeit, tfFallbeschleunigung, tfFlugzeit, tfAufprallgeschwindigkeit, tfMaxHoehe, tfMaxFlugweite;
	// alle Buttons haben ein b als Kürzel vor dem Namen
	private JButton bPlay, bReset;
	// alle Werte haben ein w als Kürzel vor dem Namen
	private double wAbschusswinkel, wAnfangshoehe, wAnfangsgeschwindigkeit, wFallbeschleunigung;
	private SchieferWurf s;
	
	/**
	 * Methode um die Objekte im GridBagLayout zu positionieren.
	 * Ist das Objekt von der Klasse JLabel, JScrollBar, JTextField, oder JButton,
	 * so wird das Objekt dem Layout direkt hinzugefügt.
	 * Ist das Objekt von der Klasse JScrollBar, JTextField, oder JButton,
	 * so wird dem Objekt direkt der entsprechende Listener hinzugewiesen.
	 * 
	 * @param o Ein Objekt der Klasse JLabel, JScrollBar, JTextField, oder JButton
	 * @param c Das entsprechende GridBagConstraints
	 * @param gridx Die X-Position des Elements im Feld
	 * @param gridy Die Y-Position des Elements im Feld
	 * @param gridwidth Wie viele Felder in X-Richtung belegt werden
	 * @param weightx Die Gewichtung in X-Richtung
	 */
	protected void defineConstraints(Object o, GridBagConstraints c, int gridx, int gridy, int gridwidth, int weightx) {
		c.gridx = gridx;
		c.gridy = gridy;
		c.gridwidth = gridwidth;
		c.gridheight = 1;
		c.weightx = weightx;
		c.weighty = 1;
		c.fill = GridBagConstraints.BOTH;
		String className = o.getClass().getSimpleName();
		if (className.equals("JLabel")) {
			add((JLabel)o, c);
		}
		if (className.equals("JScrollBar")) {
			add((JScrollBar)o, c);
			((JScrollBar)o).addAdjustmentListener(this);
		}
		if (className.equals("JTextField")) {
			add((JTextField)o, c);
			((JTextField)o).addKeyListener(this);
		}
		if (className.equals("JButton")) {
			add((JButton)o, c);
			((JButton)o).addActionListener(this);
		}
	}

	/**
	 * Konstruktor, baut die Oberfläche auf
	 */
	public GridBag() {
		GridBagLayout gridbag = new GridBagLayout();
		setLayout(gridbag);
		
		// Erste Zeile - Ab hier Eingaben
		lAbschusswinkel = new JLabel( "Abschusswinkel in °" );
		defineConstraints(lAbschusswinkel, new GridBagConstraints(), 0, 0, 1, 5);
		
		sbAbschusswinkel = new JScrollBar(0, 45, 0, 1, 90);
		defineConstraints(sbAbschusswinkel, new GridBagConstraints(), 1, 0, 1, 1);
		
		tfAbschusswinkel = new JTextField();
		defineConstraints(tfAbschusswinkel, new GridBagConstraints(), 2, 0, 1, 4);
		
		// Zweite Zeile
		lAnfangshoehe = new JLabel( "Anfangshöhe in m" );
		defineConstraints(lAnfangshoehe, new GridBagConstraints(), 0, 1, 1, 5);
		
		sbAnfangshoehe = new JScrollBar(0, 5, 0, 0, 100);
		defineConstraints(sbAnfangshoehe, new GridBagConstraints(), 1, 1, 1, 1);
		
		tfAnfangshoehe = new JTextField();
		defineConstraints(tfAnfangshoehe, new GridBagConstraints(), 2, 1, 1, 4);
		
		// Dritte Zeile
		lAnfangsgeschwindigkeit = new JLabel( "Anfangsgeschw. in m/s" );
		defineConstraints(lAnfangsgeschwindigkeit, new GridBagConstraints(), 0, 2, 1, 5);
		
		sbAnfangsgeschwindigkeit = new JScrollBar(0, 10, 0, 1, 100);
		defineConstraints(sbAnfangsgeschwindigkeit, new GridBagConstraints(), 1, 2, 1, 1);
		
		tfAnfangsgeschwindigkeit = new JTextField();
		defineConstraints(tfAnfangsgeschwindigkeit, new GridBagConstraints(), 2, 2, 1, 4);
		
		// Vierte Zeile
		lFallbeschleunigung = new JLabel( "Fallbeschl. in m/s²" );
		defineConstraints(lFallbeschleunigung, new GridBagConstraints(), 0, 3, 1, 5);
		
		sbFallbeschleunigung = new JScrollBar(0, 981, 0, 10, 5000);
		defineConstraints(sbFallbeschleunigung, new GridBagConstraints(), 1, 3, 1, 1);
		
		tfFallbeschleunigung = new JTextField();
		defineConstraints(tfFallbeschleunigung, new GridBagConstraints(), 2, 3, 1, 4);
		
		// Fünfte Zeile - Ab hier Ausgaben
		lFlugzeit = new JLabel( "Gesammte Flugzeit" );
		defineConstraints(lFlugzeit, new GridBagConstraints(), 0, 4, 1, 5);
		
		tfFlugzeit = new JTextField();
		defineConstraints(tfFlugzeit, new GridBagConstraints(), 1, 4, 2, 5);
		
		// Sechste Zeile
		lAufprallgeschwindigkeit = new JLabel( "Aufprallgeschw. in m/s" );
		defineConstraints(lAufprallgeschwindigkeit, new GridBagConstraints(), 0, 5, 1, 5);
		
		tfAufprallgeschwindigkeit = new JTextField();
		defineConstraints(tfAufprallgeschwindigkeit, new GridBagConstraints(), 1, 5, 2, 5);
		
		// Siebte Zeile
		lMaxHoehe = new JLabel( "max. Höhe" );
		defineConstraints(lMaxHoehe, new GridBagConstraints(), 0, 6, 1, 5);
		
		tfMaxHoehe = new JTextField();
		defineConstraints(tfMaxHoehe, new GridBagConstraints(), 1, 6, 2, 5);
		
		// Achte Zeile
		lMaxFlugweite = new JLabel( "max. Flugweite" );
		defineConstraints(lMaxFlugweite, new GridBagConstraints(), 0, 7, 1, 5);
		
		tfMaxFlugweite = new JTextField();
		defineConstraints(tfMaxFlugweite, new GridBagConstraints(), 1, 7, 2, 5);
		
		// Neunte Zeile - Buttons
		bPlay = new JButton( "Abspielen" );
		defineConstraints(bPlay, new GridBagConstraints(), 0, 8, 1, 5);
		
		bReset = new JButton( "Reset" );
		defineConstraints(bReset, new GridBagConstraints(), 1, 8, 2, 5);
		
		// ToolTipps setzen
		bPlay.setToolTipText("Startet bzw. pausiert die Animation des Projektils.");
		bReset.setToolTipText("Setzt die Animation zurück, um sie erneut starten zu können.");

		// Events das GridBag Objekt übergeben
		Events.setGridBag(this);
		// erstes Setup des Applets
		// TextFields werden aktualisiert und die erste Berechnung wird gemacht
		Events.updateTextFields();
		if(Events.pruefeUndSetzeEingaben()) {
			Events.berechnen();
		}
	}

	@Override
	public void keyReleased(KeyEvent arg0) {
		Events.keyReleased(arg0);
	}

	@Override
	public void adjustmentValueChanged(AdjustmentEvent arg0) {
		Events.adjustmentValueChanged(arg0);
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		Events.actionPerformed(e);
	}
	
	@Override
	public void keyTyped(KeyEvent arg0) {
		// nicht benötigt, muss aber überschrieben werden
		
	}
	
	@Override
	public void keyPressed(KeyEvent arg0) {
		// nicht benötigt, muss aber überschrieben werden
		
	}

/* Noch gaaanz viele Get und Set Methoden, sind aber hierfür unwichtig */

Das ganze soll dann so aussehen:

layoutstyv.png


Buttons,Labels,ScrollBars,TextFields.
Die Gewichtungen stehen jeweils drin.

So, nun zu meinem Problem:
Das ganze funktioniert einigermaßen,
wenn ich allerdings das Fenster kleiner zieh,
dann bleibt die Linke Spalte immer breiter als die Rechte Spalte.
Woran kann das liegen?
Ist das eventuell, weil die ScrollBars sich "minimieren" (was ich auch störend finde)?

So passt es:


So siehts es aus, wenn die rechte Spalte zu klein wird:
 
Das liegt mit ziemlicher Sicherheit daran, dass die Verhältnisse zwischen den [c]minimumSize[/c]s der Komponenten anders sind als die Verhältnisse zwischen den [c]preferredSize[/c]s.

Zur Erklärung verweise ich direkt mal in die FAQ: [post=544790]Wie das GridBagLayout die Komponentengrößen verteilt[/post]

HTH, Ebenius
 
Zuletzt bearbeitet:
Danke erstmal, ich hab mir das Ganze angeschaut,
aber selbst wenn ich die scrollbar.setMinimumSize(new Dimension 70,10)); setze,
werden die irgendwann so klein, dass man nur noch zwei Pfeile der ScrollBar sieht
und sobald die Scrollbar so schrumpft bekomm ich immer Probleme.
Gibt es eine Möglichkeit der ScrollBar zu befehlern dass sie nicht so schrumpfen darf?

Und noch ne ganz andere Frage, warum bekomme ich in der GridBag klasse bei
this.getSize(); immer 0 zurück? und this.setSize hat auch keine Wirkung?
 
Versuchs mal mit scrollbar.setPrefferedSize(new Dimension(int, int)). Vielleicht geht das.

Und zur anderen Frage.
Die Klasse hat ja selber nicht wirklich eine grösse. Du kanns zum Beispiel new JPanel().setSize() aurufen oder ähnliches. Aber das Layout selber hat ja keine Grösse.
 
Versuchs mal mit scrollbar.setPrefferedSize(new Dimension(int, int)). Vielleicht geht das.
Nein, leider nicht, auch da schrumpfen die ScrollBars irgendwann ganz klein zusammen.

Und zur anderen Frage.
Die Klasse hat ja selber nicht wirklich eine grösse. Du kanns zum Beispiel new JPanel().setSize() aurufen oder ähnliches. Aber das Layout selber hat ja keine Grösse.

Java:
// ich mach ja nicht
gridbag.getSize(); // also das layout
// sondern
this.getSize();
// und "this" ist ja ein JPanel, siehe
public class GridBag extends JPanel implements AdjustmentListener, KeyListener, ActionListener {
}
 
Ok, falls noch jemand ne Idee hat bin ich dankbar,
ich fahr aber morgen in Urlaub, werd also die nächste Woche nicht antworten können.
 
Ich hab auch nicht geschrieben, dass die [c]minimumSize[/c] eingehalten wird. Sie wird nur als neuer Maßstab genutzt. Bedeutet: Setze [c]minimumSize[/c] und [c]preferredSize[/c] aller Komponenten auf dieselben Werte und das GridbagLayout wird die Größenverhältnisse immer gleich halten; bezogen auf die angegebenen Gewichte, versteht sich.

Ebenius
 
Ich hab auch nicht geschrieben, dass die [c]minimumSize[/c] eingehalten wird. Sie wird nur als neuer Maßstab genutzt. Bedeutet: Setze [c]minimumSize[/c] und [c]preferredSize[/c] aller Komponenten auf dieselben Werte und das GridbagLayout wird die Größenverhältnisse immer gleich halten; bezogen auf die angegebenen Gewichte, versteht sich.

Ebenius

Danke,
das Ganze funktioniert soweit auch,
aber eben nicht mehr, wenn die ScrollBars auf einmal schrumpfen.
Ich find jetzt leider nichts um das zu vermeiden, auch nicht in der API.
Vielleicht hat ja noch jemand n Tipp für mich, ansonsten werd ichs
wohl einfach so lassen müssen.
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben