Java Fenster resizen, Höhe einer MenuBar bestimmen

Krik

Fleet Admiral
Registriert
Juni 2005
Beiträge
11.980
Moin

Ich habe mehrere Probleme mit meiner GUI. Ich verwende Swing.



Erstes Problem:
Dieser Code soll dafür sorgen, dass der Frame nicht zu klein wird:
Code:
// ...
<beliebiges JFrame-Objekt>.addComponentListener(new ResizeEvent());
//...
private static class ResizeEvent extends ComponentAdapter {
	public void componentResized(ComponentEvent event) {
		if (event.getID() == ComponentEvent.COMPONENT_RESIZED) {
			JFrame frame = (JFrame) event.getComponent();
			if (frame.getWidth() < 640 || frame.getHeight() < 480)
				frame.setSize(Math.max(640, frame.getWidth()), Math.max(480, frame.getHeight()));
		}
	}
}
Das Problem ist, es funktioniert nicht. Ich kann die Fenstergröße mit der Maus kleiner als 640x480 machen. Hab ich an der Sache etwas falsch verstanden oder falsch angewendet?




Zweites Problem:
Das Fenster hat eine JMenuBar. Da ich keinen LayoutManager verwende, muss ich selber dafür sorgen, dass die Components auf dem JFrame richtig ausgerichtet sind und die richtigen Abmessungen. U. a. auch bei ResizeEvents.

Dazu benötige ich die Höhe der JMenuBar, damit ich die absoluten Koordinaten eines Components berechnen kann.
Die Methode <beliebiges JMenuBar-Objekt>.getHeight() gibt aber immer 0 zurück. Und ich hab keinen Plan warum.

Auch hier wieder: Habe ich da was falsch verstanden oder falsch angewendet?




Gruß, Laurin
 
Auf deiner Variable frame gibts sicherlich eine methode "setminimumsize()" - oder ?
http://download.oracle.com/javase/6...ponent.html#setMinimumSize(java.awt.Dimension)
Da kannst du die mindestgrösse easy einstellen..

Bezüglich dem 2. Problem kann ich dir nicht helfen. - Ich bin noch nie auf die Idee gekommen, kein WindowManager zu verwenden.. ;)

PS: Evtl. weisst du's ja auch: Von Google gibts ein WindowBuilder und von netbeans ebenfalls in dieser Art, mit dem du easy Gui's basteln kannst.. Nicht dass ich ein Fan von zusammenklicken wäre, aber teilweise ists doch auch hilfreich.. Wenn man gewisse Möglichkeiten auf dem Objekt nicht kennt und nicht immer in der API nachschauen möchte..
 
Vielleicht existiert die Menübar zu dem Augenblick, in dem Du getHeight() aufrufst noch gar nicht bzw. ist noch nicht gezeichnet worden.
 
SetMinimumSize() hat geholfen, danke schön. :)

Netbeans will ich eigentlich nicht verwenden, hab ja schon Eclipse. ;)
Der Window Builder ist mir neu (hab erst gestern nach GUI-Editoren gesucht). Ich werde ihn mal ausprobieren.

@Laz-Y
Du hast recht. Ich habe die Paint-Methode einmal manuell aufgerufen und dann habe ich die Höhe der JMenuBar bekommen. Danke schön. :)



Alle Probleme gelöst. Vielen Dank euch zweien. :)
 
Zuletzt bearbeitet:
Code:
public class Test {

	private static class ResizeEvent extends ComponentAdapter {

		private int minWidth, minHeight;

		public ResizeEvent(int minWidth, int minHeight) {
			this.minWidth = minWidth;
			this.minHeight = minHeight;
		}

		public ResizeEvent(Dimension minSize) {
			this.minWidth = minSize.width;
			this.minHeight = minSize.height;
		}

		public void componentResized(ComponentEvent event) {
			if (event.getID() == ComponentEvent.COMPONENT_RESIZED) {
				JFrame frame = (JFrame) event.getComponent();
				if (frame.getWidth() < minWidth || frame.getHeight() < minHeight)
					frame.setSize(Math.max(minWidth, frame.getWidth()), Math.max(minHeight, frame.getHeight()));
			}
		}
	}

	public static void main(String[] args) throws Exception {
		JFrame frame = new JFrame();
		frame.addComponentListener(new ResizeEvent(800, 640));
		frame.setVisible(true);
	}
}
Also der Code funktioniert bei mir einwandfrei und es ist bis auf die Parameterisierung derselbe, den auch du verwendest. Vielleicht hast du doch irgendwas in deinem Programm verwurstelt?



Zu deinem zweiten Problem schreib ich einfach mal ein bisschen mehr, weil ich glaube, dass du allgemein noch ein paar Problemchen mit der GUI, besonders in Java hast. Ging mir am Anfang aber auch so...

Also, es gibt ein paar sehr wichtige Methoden in dem ganzen Java GUI Verhau. Das sind einmal pack() und getPreferredSize().
Nehmen wir einmal an, wir haben ein sehr stark verschachteltes Fenster. Ein paar Reiter, in jedem ein paar Buttons, Listen, Tabellen, und so weiter und so fort. Damit Java nun weiß, wie groß es ein Component zeichnen soll, ruft es alle getPreferredSize()-Methoden seiner Kinder auf. Falls diese auch wieder Kinder haben, werden von diesen Kindeskindern auch wieder die getPreferredSize()-Methoden aufgerufen, bis man ganz unten angekommen ist. Damit kann man sozusagen die Größe von unten nach oben durchberechnen. Anschließend kann Java mit diesen Informationen unsere GUI aufbauen.

Doch wieso macht Java das so? Das liegt zum großen Teil daran, dass Java plattformunabhängig sein soll. Wenn ich ein Fenster ohne LayoutManager genau so groß mache, dass ich meine drei Knöpfe ordentlich reinbekomme, funktioniert das zwar auf meinem Windows. Aber wenn ein Macuser mein Programm ausführt, zeichnet dem seine JRE die Buttons ja komplett anders. Es kann also durchaus sein, dass meine GUI auf seinem System ganz furchtbar aussieht, bishin zur Unbenutzbarkeit. Also rechnet Java sich seine Größen lieber immer selber aus. Das ist auch der Grund, wieso NullLayoutManager tunlichst vermieden werden sollten. Ich habe in meinem ganzen Leben noch keinen gebraucht, und Hölle, ich habe schon wirklich viele verschiedene GUIs gebaut ;)

Die andere Methode, die ich angesprochen habe, pack(), bewirkt nun genau das, was ich oben beschrieben habe. Es berechnet einmal für alle Komponenten die Größe. Damit ist die Komponente displayable geworden und du kannst die Dimensionen mit den entsprechenden Methoden abfragen.

Hoffe, das hilft dir vielleicht ein bisschen. Du kannst mir auch gerne für den Anfang ein paar Skizzen einscannen und schicken von GUIs, die du nicht mit LayoutManagern hinbekommst, dann schuster ich sie dir zusammen, dann hast du ein wenig Sichtungsmaterial. Aber bitte bitte, gewöhn dir LayoutManager an ;)

// edit
Das "Windows" bitte nicht als mögliche Kränkung auffassen :D
 
Zuletzt bearbeitet: (Ort: /dev/eth0)
Geändert von Killkrog (Gestern um 23:11 Uhr) Grund: Ort: /dev/eth0
Nice one! :lol:



Danke für dein Angebot. Ich komme darauf gerne zurück.

Ich komme persönlich mit den LayoutManagern nicht klar. Ich weiß, dass sie einem helfen können, alle Components (automatisch) richtig auszurichten. Ich habe nur große Probleme die Components in der richtigen Größe am richtigen Fleck anzuordnen. Ich breche mir jedes Mal einen Ast ab, wenn ich versuche, die richtigen Abstände zwischen den Components einzustellen und die automatische Größenänderung zu beeinflussen.
 
Du solltest unbedingt Layoutmanager nutzen!
Setzt Du immer absolut, und der Benutzer hat eine andere Auflösung / ein anderes Theme (XP Classic, Aero, Ubuntu Theme, etc) / andere DPI-Einstellung / sonstwas, woran kein normaler Mensch denk, kann das Dein ganzes Layout durcheinander werfen.

Wenn Du mit GridbayLayout nicht zurecht kommst (ich mags auch nicht) dann versuch JGoodie Forms http://www.jgoodies.com/freeware/forms/
 
e-Laurin schrieb:
Zweites Problem:
Das Fenster hat eine JMenuBar. Da ich keinen LayoutManager verwende, muss ich selber dafür sorgen, dass die Components auf dem JFrame richtig ausgerichtet sind und die richtigen Abmessungen. U. a. auch bei ResizeEvents.

Wenn man keinen LayoutManager verwendet, funktioniert dann die setJMenuBar() von JFrame nicht mehr korrekt? Diese ist ja u.a. dazu da, eine JMenuBar automatisch zu platzieren und auszurichten, dachte ich.
 
Zurück
Oben