LayoutManager GUI skalieren und deren Komponenten mit Grid(Bag)Layout-Manager.

DefconDev

Bekanntes Mitglied
Hallo zusammen,

ich bräuchte mal einen dezenten Hinweis, wie ich am besten meine Layoutmanager so einstelle dass die Komponenten innerhalb des Frame automatisch angepasst werden , wenn entweder der Frame vergrößert/verkleinert wird oder sich die Bildschirmauflösung ändert.

Das JFrame selber bestimme ich folgend:
Java:
JFrame jf = new MyJFrame();
		
Dimension screen = java.awt.Toolkit.getDefaultToolkit().getScreenSize(); 
jf.getSize(screen);
jf.pack();
jf.setLocationRelativeTo(null); 
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setVisible(true);

Für die Meisten Komponenten innerhalb eines Panels benutze ich den GridBagLayout-Manager, teilweise kommt aber auch der GridLayout-Manager zur Geltung.

Mit setPreferedSize bestimme ich die wichtigsten Komponenten, die Dimension wird aus einer extra Klasse gelesen.

Java:
public class ScreenSize {
	
	
	private int jButton_xSize = 120;
	private int jButton_ySize = 30;
	
	private int jListSpieler_xSize = 100;
	private int jListSpieler_ySize = 400;
	
	private int jListMap_xSize = 100;
	private int jListMap_ySize = 1200;
	
	private int jListNation_xSize = 100;
	private int jListNation_ySize = 800;
	
	private int jScrollbar_xSize = 150; 
	private int jScrollbar_ySize = 290;
	
	private int jCheckBox_xSize = 160;
	private int jCheckBox_ySize = 30;
	
	private int jScrollbarMatch_xSize = 650;
	private int jScrollbarMatch_ySize = 215;
	
	private int jScrollbarRangliste_xSize = 700;
	private int jScrollbarRangliste_ySize = 300;
	
	private int jScrollbarElo_xSize = 265;
	private int jScrollbarElo_ySize = 120;
	
	private int jScrollbarPrevSpieler_xSize = 230;
	private int jScrollbarPrevSpieler_ySize = 211;
	
	private int jChartPanelPrevSpieler_xSize = 350;
	private int jChartPanelPrevSpieler_ySize = 250;

Die restlichen Komponenten wie zB. JTables werden gar nicht erst bestimmt, werden bei mir alle in Scrollpanes eingefügt, sollte das eine Rolle spielen.

Jetzt habe ich von dem ComponentListener kurz gelesen, müsste ich sowas in die Wege leiten? Oder zB mit den Methoden revalidate() oder repaint()? Wenn ja, wo setze ich da am besten an.

Den Versuch es über getMinimumSize und getMaximumSize zu lösen hat auch nicht ganz funktioniert.

Oder wird das alles bequemer direkt über den Layoutmanager gelöst? Eine typische Platzierung über diesen sieht in der Regel so aus:

Java:
GridBagConstraints layout = new GridBagConstraints();
	
        JPanel ui_1 = new JPanel(new GridBagLayout());
        layout.insets = new Insets(5,5,5,5);
		
	layout.gridx = 0;
	layout.gridy = 0;
	layout.gridheight = 1;
	ui_1.add(chartPanel_1, layout);
        layout.gridx = 1;
	layout.gridy = 0;
	layout.gridheight = 1;
	ui_1.add(chartPanel_2, layout);
	layout.gridx = 0;
	layout.gridy = 1;
	layout.gridheight = 1;
	ui_1.add(chartPanel_3, layout);
        layout.gridx = 1;
	layout.gridy = 1;
	layout.gridheight = 1;
	ui_1.add(chartPanel_4, layout);
 
Ok, ich konnte jetzt das Problem eingrenzen warum setMinimumSize bei keiner Componente überhaupt nicht funktioniert hat.

Das Problem liegt in der Schachtelung meiner Panels und meiner JTabbedPanes.

Sobald ein JPanel, welches vom JFrame geaddet wird, ein JTabbedPane aufnimmt ist die Skalierung futsch. Er ignoriert dann komplett die setMinimum Methoden.

Anders herum, wenn ein JTabbed ein Panel aufnimmt und nur das JTabbedPane vom JFrame geaddet wird, kann ich wie gewünscht alles resizen/skalieren.

Jemand eine Idee was ich machen könnte?

Das einzige was mir jetzt noch einfiele, ist jedes mal beim Start des Programms die Auflösung des Bildschirms abzufragen und dann die getPreferedSize anhand einer if-Bedingung zu skalieren. Das ist aber nur halb so schön , weil während der Laufzeit sich nichts ändern kann. Und ich dann ein paar Standard Auflösungen nur nehmen könnte, jedenfalls hätte ich keine Lust alle erdenklichen Auflösungen in eine Bedingung zu setzen.

if(Auflösung == 800*600){
halbiere setPreferedsize
}
 
Zuletzt bearbeitet:
Sobald ein JPanel, welches vom JFrame geaddet wird, ein JTabbedPane aufnimmt ist die Skalierung futsch. Er ignoriert dann komplett die setMinimum Methoden.
Ich verstehe dich nicht???:L
Es wäre hilfreich, wenn du das in einem SSCCE demonstrieren könntest.

Hört sich so an, das du dem JFrame keinen Layout-Manager zugewiesen hast, aber ohne Code...:noe:
 
Ich verstehe dich nicht???:L
Es wäre hilfreich, wenn du das in einem SSCCE demonstrieren könntest.

Hört sich so an, das du dem JFrame keinen Layout-Manager zugewiesen hast, aber ohne Code...:noe:

Du hattest recht, dem letzten Panel der das TabbedPane aufnimmt, habe ich keinen Layoutmanager hinzugefügt.
Bzw. ich hatte dem letzten Panel den GridLayout Manager gesetzt, und nicht den GridBagLayout-Manager.

Aus irgendwelchen gründen ignoriert der GridLayout Manager die preferredSize.

Java:
public class TestGui {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		JFrame frame = new JFrame("TestGui");
		
		JPanel panel_1 = new JPanel(new GridBagLayout());
		JPanel panel_2 = new JPanel(new GridBagLayout());
		
		JPanel main = new JPanel(new GridLayout(2,0));
		JButton button_1 = new JButton("Hallo");
		JButton button_2 = new JButton("Guten Tag");
		
		
		button_1.setPreferredSize(new Dimension(400,100));
		button_2.setPreferredSize(new Dimension(100,100));
		
		
		
		String ds[] ={"Deutschland", "Holland"};
		JList<String> list = new JList<String>(ds);
		
		JTabbedPane tab_1 = new JTabbedPane();
		JTabbedPane tab_2 = new JTabbedPane();
		
		JScrollPane bar = new JScrollPane(list);
		bar.setPreferredSize(new Dimension(200,400));
		bar.setMinimumSize(new Dimension(100,200));
		
		GridBagConstraints layout = new GridBagConstraints();
		
		layout.insets = new Insets(10,10,10,10);
		layout.gridx = 0;
		layout.gridy = 1;
		layout.gridheight = 1;
		//layout.gridwidth = 2;
		panel_1.add(button_1, layout);
		layout.gridx = 0;
		layout.gridy = 2;
		layout.gridheight = 1;
		//layout.gridwidth = 2;
		panel_1.add(button_2, layout);
		layout.gridx = 1;
		layout.gridy = 0;
		layout.gridheight = 1;
		//layout.gridwidth = 2;
		panel_1.add(bar,layout);
		
		
		panel_1.setPreferredSize(new Dimension(400,400));
		panel_2.setPreferredSize(new Dimension(400,400));
		tab_1.add(panel_1,"TEST TAB1");
		tab_2.add(panel_2,"TEST TAB2");
		
		main.add(tab_1);
		main.add(tab_2);
		
		Dimension screen = java.awt.Toolkit.getDefaultToolkit().getScreenSize(); 
		frame.setSize(screen);
		
		frame.add(main);
		frame.pack();
		frame.setLocationRelativeTo(null); 
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
	}

}
 
Zuletzt bearbeitet:
Jetzt verstehe ich deine Code nicht😀

Du machst ein setSize UND ein pack. Das widerspricht sich.

Aus der Doku
public void pack()
Causes this Window to be sized to fit the preferred size and layouts of its subcomponents. The resulting width and height of the window are automatically enlarged if either of dimensions is less than the minimum size as specified by the previous call to the setMinimumSize method.
If the window and/or its owner are not displayable yet, both of them are made displayable before calculating the preferred size. The Window is validated after its size is being calculated.

Also wird hiermit die Grösse eines Frames so berechnet, das "möglichst viel" von den Komponenten sichtbar ist.
Das ist IMHO die bevorzugte Weise ein JFrame anzuzueigen. Dagegen sagst du bei setSize dem System, das du es besser weisst und das JFrame GENAU in der angegebenen Grösse angezeigt werden soll.

Also, entweder pack oder setSize aber nicht beides.
 
Zuletzt bearbeitet:
Also das setSize und pack() hat bisher wunderbar funktioniert.

1. Muss ich nicht die Fenster Größe des Frames selber bestimmen und ich kann einzelne Componenten eine preferredSize geben.

Abseits dessen habe ich habe das Problem lösen können. Ich habe das GridLayout gegen das GridbagLayout getauscht. Jetzt wird nichts mehr ignoriert.


Was mich jetzt noch am Rand interessieren müsste, gibt es auch eine Möglichkeit mehrere Stufen der Skalierung umzusetzen? Momentan skaliert er bei Verkleinerung direkt auf die setMinimumSize
 

Zurück
Oben