Swing Layoutproblem

Dragonfire

Bekanntes Mitglied
Hi,
sorry für den schlechten Thread-Titel,
mir viel aber leider kein anderer ein ....

So langsam verzweifel ich an meinem Problem:

Ich habe ein Fenster mit zwei Panels ...
Das oberer (NORTH) Panel ändert die Höhe, wenn es breiter oder schmaler wird.

Das untere Panel (SOUTH-Panel) ist komplett dynamisch und verbraucht dem vom Layout-Manager zugewiesenen Platz.
Ich habe mal eine kleine Testmethode gebastelt:

Java:
public static void main(String[] args) {
		JPanel panel = new JPanel();
		panel.add(new JLabel("ein JLabel mit"));
		panel.add(new JLabel("ganz ganz langem Text"));

		JPanel p = new JPanel(new GridBagLayout());
		GridBagConstraints constraints = new GridBagConstraints();

		constraints.gridwidth = GridBagConstraints.REMAINDER;
		constraints.fill = GridBagConstraints.BOTH;
		constraints.weightx = 1.0;
		constraints.weighty = 0.0;
		p.add(panel, constraints);

		constraints.fill = GridBagConstraints.BOTH;
		constraints.weighty = 1.0;
		p.add(new JButton("dynamisches JPanel (hier Button)"), constraints);

		JFrame f = new JFrame("Panel");
		f.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
		f.add(p);
		f.pack();
		f.setSize(250, 150);
		f.setVisible(true);
	}

so soll es aussehen ...
nun mein Problem,
wenn ich das Fenster ein wenig schmaler mache,
dann verschwindet vom "NORTH"-Panel der untere Teil ...
(constraints.weighty = 0.0 .. ist in diesem Beispiel extra auf null gesetzt, nur um zu zeigen wie es später aussehen soll)

Wenn ich die weighty-Konstante ändere,
dann füllt das "SOUTH"-Panel nichtmehr den kompletten Bereich aus,
aber man kann das Fenster schmaler ziehen,
oder das das "NORTH"-Panel halb verschwindet:

Java:
public static void main(String[] args) {
		JPanel panel = new JPanel();
		panel.add(new JLabel("ein JLabel mit"));
		panel.add(new JLabel("ganz ganz langem Text"));

		JPanel p = new JPanel(new GridBagLayout());
		GridBagConstraints constraints = new GridBagConstraints();
		constraints.gridwidth = GridBagConstraints.REMAINDER;

		constraints.fill = GridBagConstraints.BOTH;
		constraints.weightx = 1.0;
		constraints.weighty = 1.0;
		p.add(panel, constraints);

		constraints.fill = GridBagConstraints.BOTH;
		constraints.weighty = 0.9;
		p.add(new JButton("dynamisches JPanel (hier Button)"), constraints);

		JFrame f = new JFrame("Panel");
		f.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
		f.add(p);
		f.pack();
		f.setSize(250, 150);
		f.setVisible(true);
	}

Gibt es eine Möglichkeit, dass die Höhe des "SOUTH"-Panel geändert wird,
wenn die sich auch ändert und man nicht einen Prozentsatz angeben muss, wieviel Platz die Komponente verbraucht?

Im Anhang sind zwei Bilder, wie das aussehen soll.
 

Dragonfire

Bekanntes Mitglied
Das Problem liegt wohl im "NORTH"-Panel
oder ich habe irgendwas falsch gemacht.
Folgender Code führt nämlich nicht zum gewünschten Ergebnis :-(
(Hab beim JPanel "panel" extra nochmal den LayoutManger mitgeben ...)

Java:
public static void main(String[] args) {
		final JPanel panel = new JPanel(new FlowLayout());
		panel.add(new JLabel("ein JLabel mit"));
		panel.add(new JLabel("ganz ganz langem Text"));

		double size[][] = { { TableLayoutConstants.FILL },
				{ TableLayoutConstants.MINIMUM, TableLayoutConstants.FILL } };

		final JPanel p = new JPanel(new TableLayout(size));
		p.add(panel, "0, 0");
		p.add(new JButton("dynamisches JPanel (hier Button)"), "0, 1");

		JFrame f = new JFrame("TableLayoutPanel");
		f.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
		f.add(p);
		f.pack();
		f.setSize(250, 150);
		f.setVisible(true);
	}
 

Dit_

Bekanntes Mitglied
hm probier mal das hier

Java:
public static void main(String[] args) {
		JFrame mainFrame = new JFrame("TableLayoutPanel");
		//start Dimension
		mainFrame.setSize(400, 300);
		//Layout fuer Frame. TableLayout.FILL hangt von mainFrame.setSize(x, y) ab.
		double size[][] = { { 10, TableLayout.FILL, 10 }, 
							{ 10, TableLayout.FILL, 10 } };
		mainFrame.setLayout(new TableLayout(size));
		
		//Layout fuer Panel
		int platzFuerTextAlsHoehe = 200;
		double[][] size2 = {{10, TableLayout.FILL, 10},
							{10, platzFuerTextAlsHoehe, 10, TableLayout.FILL, 10}};
		JPanel panel = new JPanel(new TableLayout(size2));
		//Farbe setzen um zu sehen wie genau Panel platziert wird.
		panel.setBackground(Color.GREEN);
		//Componente einfuegen
		panel.add(new TextArea("TextArea mit ganz ganz langem Text"), "1,1");
		panel.add(new JButton("Button"), "1,3");
		
		//Frame bekommt Panel.
		mainFrame.add(panel, "1,1");
		mainFrame.pack();
		mainFrame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
		mainFrame.setVisible(true);

	}


mit
mainFrame.getHeight() und mainFrame.getWidth()

kannst du zB einstellen wie hoch dein Button sein soll (zB 15 % von mainFrame.getHeight())
 

Dragonfire

Bekanntes Mitglied
Das ist ja genau mein Problem und ich glaube TableLayout hilft mir da nur bedingt weiter,
so wie ich das sehe muss ich die Größe vom "NORTH"-Panel selbst anpassen,
da die minimale benötigte Größe nicht aktualisiert wird ...

Ich habe jetzt für diesen Fall mal eine kleine Lösung gebastelt,
du hattest mich auf eine Idee gebracht.
Vielleicht hat wer noch eine bessere Idee,
wie man das Problem lösen kann:
(Performance wird noch optimiert ...)

Java:
public static void main(String[] args) {
		final FlowLayout fl = new FlowLayout();
		final JPanel panel = new JPanel(fl);
		panel.add(new JLabel("ein JLabel mit"));
		panel.add(new JLabel("ganz ganz langem Text"));
		panel.addComponentListener(new ComponentListener() {
			@Override
			public void componentShown(ComponentEvent e) {
				// do nothing
			}

			@Override
			public void componentResized(ComponentEvent e) {
				Dimension size = panel.getPreferredSize();
				if (panel.getSize().getWidth() < panel.getMinimumSize()
						.getWidth()) {
					int nH = 0;
					for (int i = 0; i < panel.getComponents().length; i++) {
						nH += panel.getComponents()[i].getSize().getHeight()
								+ fl.getVgap();
					}
					size = new Dimension((int) panel.getMinimumSize()
							.getWidth(), nH);
				}
				panel.setMinimumSize(size);
			}

			@Override
			public void componentMoved(ComponentEvent e) {
				// do nothing
			}

			@Override
			public void componentHidden(ComponentEvent e) {
				// do nothing
			}
		});

		double size[][] = { { TableLayoutConstants.FILL },
				{ TableLayoutConstants.MINIMUM, TableLayoutConstants.FILL } };

		final JPanel p = new JPanel(new TableLayout(size));
		p.add(panel, "0, 0");
		p.add(new JButton("dynamisches JPanel (hier Button)"), "0, 1");

		JFrame f = new JFrame("TableLayoutPanel");
		f.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
		f.add(p);
		f.pack();
		f.setSize(250, 150);
		f.setVisible(true);
	}

Nachtrag:

Habe jetzt meine Algorithmus ein wenig überarbeitet ...
werde den jetzt erstmal so verwenden ...
wenn wer eine besserr Lösung hat,
würde ich mich Freuen,
weil die Berechnung der Höhe noch ein wenig unsauber ist :-(

Java:
public static void main(String[] args) {
		final FlowLayout fl = new FlowLayout();
		final JPanel panel = new JPanel(fl);
		panel.add(new JLabel("Ein"));
		panel.add(new JLabel("JLabel"));
		panel.add(new JLabel("mit"));
		panel.add(new JLabel("ganz"));
		panel.add(new JLabel("ganz"));
		panel.add(new JLabel("langem"));
		panel.add(new JLabel("Text:"));
		for (int i = 65; i < 91; i++) {
			panel.add(new JLabel(new String(new char[] { (char) i, (char) i,
					(char) i, (char) i })));
		}

		panel.addComponentListener(new ComponentListener() {
			@Override
			public void componentShown(ComponentEvent e) {
				// do nothing
			}

			@Override
			public void componentResized(ComponentEvent e) {
				Dimension size = panel.getPreferredSize();
				if (panel.getSize().getWidth() < panel.getMinimumSize()
						.getWidth()) {
					int tmpWidth = (int) (panel.getSize().getWidth() - fl
							.getHgap());
					int newHeight = (int) (fl.getVgap()
							+ panel.getComponents()[0].getSize().getWidth() + fl
							.getVgap());
					for (int i = 0; i < panel.getComponents().length; i++) {
						tmpWidth -= (panel.getComponents()[i].getSize()
								.getWidth() + fl.getHgap());
						if (tmpWidth < 0
								|| (i + 1 < panel.getComponents().length && tmpWidth
										- panel.getComponents()[i + 1]
												.getSize().getWidth() < 0)) {
							tmpWidth = (int) (panel.getSize().getWidth() - fl
									.getHgap());
							newHeight += (int) (panel.getComponents()[0]
									.getSize().getWidth() + fl.getVgap());
						}
					}

					size = new Dimension((int) panel.getMinimumSize()
							.getWidth(), newHeight);
				}
				panel.setMinimumSize(size);
			}

			@Override
			public void componentMoved(ComponentEvent e) {
				// do nothing
			}

			@Override
			public void componentHidden(ComponentEvent e) {
				// do nothing
			}
		});
 
Zuletzt bearbeitet:

Ähnliche Java Themen

Neue Themen


Oben