Komponenten vergrößern sich nicht trotz Layoutmanager

Gucky

Top Contributor
Hallo liebes Forum,

ich habe ein Programm geschrieben, in dem ein JDialog an ein JFrame angedockt werden soll. Das funktioniert auch sehr gut. Allerdings soll sich dieser JDialog zusammen mit dem JFrame vergrößern und verkleinern. Das funktioniert auch. Aber die Komponenten auf diesem JDialog vergrößern sich nicht mit. Nur verkleinern funktioniert.

Der JDialog hat das BorderLayout und das JScrollPane das dafür vorgesehene Layout.

Ich habe schon versucht die Bounds der beiden Komponenten (ein JScrollPane und eine JList) jedes mal anzupassen, jedoch hat das nur beim Verkleinern funktioniert.

Ich weiß leider nicht mehr weiter. Hat jemand von euch eine Idee?
Unten findet ihr den Code, in dem die Vergrößerung bzw. die Verkleinerung stattfindet.
Ich habe eine Klasse geschrieben, die den JDialog erweitert und ComponentListener implementiert.

LG
Gucky



Java:
	@Override
	public void componentResized(ComponentEvent arg0) {
		Rectangle paramRect = arg0.getComponent().getBounds();
		this.setBounds(new Rectangle(paramRect.x - this.getWidth(), paramRect.y, this.getWidth(), (int) paramRect.getHeight()));
		list.setBounds(new Rectangle (0, 0, this.getWidth(), this.getHeight()));
		scrollPane.setBounds(new Rectangle (0, 0, this.getWidth(), this.getHeight()));
	}
 
Zuletzt bearbeitet:
Dann funktioniert es noch schlechter.

Rechts ist ein grauer Rand und es vergrößert/verkleinert sich nicht mehr.


Auch setSize() funktioniert nicht.
 
Zuletzt bearbeitet:
Was ist mit preferredSize, und oder min und max size ? Schau mit das morgen nochmal am Rechner an, vielleicht findet ich noch was 🙂
 
Bitteschön 😉

EDIT: Ich musste die Methode nochmal umbennen , da gab es namenskonflikte mit der als Deprecated markierten Methoden der klasse Component

Java:
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import javax.swing.JDialog;
import javax.swing.JFrame;


public class Foo extends JFrame implements ComponentListener{
	
	ResizeableChild child;
	
	public Foo(){
		super("Container");
		setSize(300,300);
		setLocationRelativeTo(null);
		setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		
		child = new ResizeableChild(this);
		
		addComponentListener(this);
		

	}


	@Override
	public void componentResized(ComponentEvent e){
		child.resizeComponent(getWidth() / 2, getHeight() / 2);
	}

	@Override
	public void componentMoved(ComponentEvent e){}

	@Override
	public void componentShown(ComponentEvent e){}

	@Override
	public void componentHidden(ComponentEvent e){}
	
	class ResizeableChild extends JDialog{
		
		public ResizeableChild(JFrame frame){
			super(frame);
			setPreferredSize(new Dimension(WIDTH, HEIGHT));
			pack();
			setLocationRelativeTo(frame);
			setVisible(true);
		}
		
		public void resizeComponent(int width, int height){
			
			int x = getParent().getX() + width / 2 ;
			int y = getParent().getY() + height / 2;
			
			setBounds(new Rectangle(x, y, width, height));
		}
	}
	
	public static void main(String[] args){
		new Foo().setVisible(true);
	}
}
 
Zuletzt bearbeitet:
Also meinst du, ich sollte den angedockten Dialog nicht ComponentListener implementieren lassen sondern das Event vom Hauptframe abfangen lassen und dann an den Dialog weitergeben lassen?

Deinen Code verstehe ich aber irgendwie den Unterschied zu meiner Version nicht so ganz. entweder das Event wird direkt weitergegeben oder erst abgefangen und dann nur zwei Werte weitergegeben.


PS: Ich glaube, es liegt an der JList. Das ScrollPane vergrößert sich automatisch aber die JList nicht. Das muss ich aber noch mal überprüfen.

EDIT: Ich hab jetzt mit MouseClickedEvents geguckt, was sich nicht vergrößert. Es ist das ScrollPane. Das MouseClickedEvent wird vom Dialog abgefangen. Oder vom ContentPane und dann ohne Zwischenstopp weiter an den Dialog gereicht. Fakt ist, dass ich vom Dialog die Reaktion bekomme.

EDIT2: Ich kann es noch mal im NullLayout versuchen aber das ist ja nicht im Sinne des Erfinders. Auch ein eigenes Layout ist nicht in meinem Sinne. Schließlich gibt es das BorderLayout, welches meinen Ansprüchen eigentlich zu genügen hat.
 
Zuletzt bearbeitet:
Also ist / war nicht das eigentliche Problem das sich keien Komponente Größentechnisch anpasst, ( das hab ich dann überlesen)

EDIT :
Allerdings soll sich dieser JDialog zusammen mit dem JFrame vergrößern und verkleinern. Das funktioniert auch

Jap, ich habs überlesen :lol:

sondern das sich die JScollpane nicht anpasst, und somit die ihr zugewiesenen Komponenten , zumindest optisch nicht anpasen ( JList)
 
Zuletzt bearbeitet:
Java:
public class Foo extends JDialog{

	JScrollPane pane;
	JList<Object> list;
	Object[] data = {"item1","item2","item3"};
	
	
	public Foo(){
		
		setSize(300,300);
		setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		setLocationRelativeTo(null);
		
		
		list = new JList<>(data);
		pane = new JScrollPane(list);
		
		
		add(pane);
		
		setVisible(true);
	}
	
	public static void main(String[] args){
		new Foo();
	}
}

meinst du das sich dann die JScrollPane und die JList nicht an Breite und Höhe des JDialogs anpassen ?

mal unabhängig von der Position des JDialog, sollte sich der inhalt des Dialoges doch ( insofern Borderlayout ) wie in dem snippet oben doch sowieso immer dessen größe anpassen?! Oder meinst du was anderes ?

kannst du vielleicht einen screen machen ? damit ich weiß was du meinst, falls ich es gerade falsch verstehen sollte, Nachtschichtwoche und sooooo.... da dauerts bei mir immer etwas :lol:
 
Zuletzt bearbeitet:
Mein Problem ist es, dass sich das ScrollPane nicht in der Höhe verändert. Die Breite ist mir egal. Eine Änderung der Breite soll wenn überhaupt im Code vorgenommen werden.
Vielleicht habe ich mich nicht klar genug ausgedrückt. 🙂

Anbei die Screenshots

Vergrößert.JPGUnvergrößert.JPGVerkleinert.JPG
 
Zuletzt bearbeitet:
Sehe ich das Richtig das der Dialog undecorated ist ? also sprich der Bereich links des Schaltpulttimers ?
 
Zuletzt bearbeitet:
Ja das siehst du vollkommen richtig.

Jetzt ist noch ein Problem hinzugekommen. Wenn ich den JDialog erst sichtbar mache, wenn schon ein Element in der JList ist, dann passt sich das JScrollPane der erforderlichen Größe, um dieses Element anzuzeigen, an.
 
Zuletzt bearbeitet:
Hälst du in deiner Gui eine Referenz auf den Dialog oder erzeugst du einfach eine neue istanz , z.B per button ?

Also ist der Dialog fester Bestandteil der Gui ?
 
Es existieren drei Referenzen. Zwei als Listener und eine um den Dialog sichtbar oder unsichtbar zu machen. Letztere ist im Hauptframe.

Er lässt sich zwar unsichtbar machen aber er ist von Start an vorhanden. Nur halt unsichtbae.
 
Zuletzt bearbeitet:
Jetzt kann ich genau nachvollziehen was du meinst :



Das tritt erst auf sobald die Scrollpane hinzugefügt wird.

ich schau mir das mal genauer an da ich jetzt die Situation nachstellen kann 🙂

EDIT :

Das hier hat zumindest soweit geklappt das sich nun auch die scrollpane mit vergrößert

Java:
public void interact(){
	setBounds(parent.getX() - width	, parent.getY(), width, parent.getHeight());
	pane.setBounds(parent.getX() - width, parent.getY(), width, parent.getHeight());
}

EDIT EDIT :

Allerdings kannst werden dann keine Daten mehr in der List angezeigt :lol:

ABER :

Code:
* This method changes layout-related information, and therefore,
* invalidates the component hierarchy.

also ... müsste eigentlich :

Java:
revalidate();

abhilfe schaffen , und ja funktioniert auch !

Java:
@Override
public void componentResized(ComponentEvent e){
	dialog.interact();
}

public void interact(){
  setBounds(parent.getX() - width	, parent.getY(), width, parent.getHeight());
  pane.setBounds(parent.getX() - width	, parent.getY(), width, parent.getHeight());
  revalidate();
}

Daten werden angezeigt , scrollpane 'wächst' mit dem Frame mit, du musst also beim ändern der größe das layout neu validieren.

 
Zuletzt bearbeitet:
Nicht dafür , klappts denn jetzt ? 🙂

Es reicht sogar das hier :

Java:
public void interact(){
		setBounds(parent.getX() - width	, parent.getY(), width, parent.getHeight());
//		pane.setBounds(parent.getX() - width	, parent.getY(), width, parent.getHeight());
		revalidate();
}

durch das validieren werden die bounds der Scrollpane dann automatisch mit angeglichen.
 
Zuletzt bearbeitet:
Jaaaaaaa. Es klappt 😀
Vielen Dank. Das Problem hab ich schon, seit ich diesen Dialog eingebaut habe. 😀


Aber jetzt hab ich leider noch ein anderes Problem. Ich denke, ein Bild wird eher zeigen können, was ich meine.
Beim ersten Bild wurde der Dialog erst sichtbar gemacht, als mindestens ein Element schon in der JList war. Beim Zweiten wurde er sofort sichtbar gemacht. Ich denke, beim setVisible(true) wird auch etwas Vergleichbares zu pack() aufgerufen.

Dialog nachher sichtbar.JPGDialog vorher sichtbar gemacht.JPG


EDIT: Ich habs jetzt mit einer Größenanpassung des JScrollPanes mit setSize(...) nach jedem setVisible(true) hinbekommen. Gibt es da noch etwas Besseres?
 
Zuletzt bearbeitet:
du musst über setMinimumSize, die eine Minimalgröße definieren, welche schon die , wie du sagtest festgelegte breite enthält

oder beim initialisieren schon einmal die bounds setzen .

ich habe dazu bei mir direkt schon einmal setbounds im konstruktor aufgerufen

Java:
		public PlainDialog(JFrame parent){
			this.parent = parent;
			width = 200;
			
//			daten simmulieren
			data = new Object[]{"sdf","sdf","sdfsdf","sdf","sdfsdf"};
			
			list = new JList<>(data);
			pane = new JScrollPane(list);
			
			add(pane);
			
			
			setBounds(parent.getX() - width, parent.getY(), width , parent.getHeight());
			setUndecorated(true);
		}

so müsste sich auch wenn es noch nicht sichtbar ist zumindest schon die von dir gewünschte Position und breite haben
 
Zuletzt bearbeitet:
Es funktioniert. Aber nur so lange, bis ich das Frame vergrößere oder verkleinere. Kann ich dem JScrollPane nicht irgendwie verbieten die Breite zu ändern? Also sowas, wie lockY() oder lockWidth()?
 
Zuletzt bearbeitet:
Warum solltest du das tun, wenn du die Breite als variable im Dialog deklariest, und beim Größe ändern lediglich die Methode aufrufst welche x, y Koordinate und höhe anhand des Frames bestimmt und die vorher festgelegte Breite verwendet, ändert sich ätsch nur die Höhe, oder verstehe ich da Grad was falsch 🙂?

Schau dir die interact Methode mal an die ich vorhin gepostet habe, da verwende ich nur die fest definierte Breite beim resizen.
Ansonsten muss ich mir das morgen nochmal anschauen wenn ich am Rechner bin.
 
Zuletzt bearbeitet:
Ich hab dich zwar nicht verstanden aber ich kann noch mal sagen, was genau passiert 😀

Ich hab den Dialog. Dieser ist an das JFrame angedockt. Er macht alle Höhenänderungen und Bewegungen mit, die dieses JFrame auch macht. Also mit dem Dialog läuft alles super.

Jetzt hab ich aber dieses JScrollPane. Wenn ich revalidate() nicht aufrufe, dann wird das JScrollPane zwar nicht in der Höhe verändert, dafür aber auch nicht in der Höhe.
Wenn ich revalidate() aufrufe, dann wird das JScrollPane so lange dem längsten Text in der JList angepasst, bis es über die Grenzen des JDialogs hinausgehen würde. Dann tut es das, was JScrollPanes am besten können.
Jetzt hab ich mal versucht das JScrollPane in der Breite nachdem ich revalidate() aufgerufen habe anzupassen. Das funktioniert. Allerdings flackert das JScrollPane jetzt.
Irgendwie meint Java es nicht gut mit mir 😀


Und warum zur Hölle nimmt dieses dämliche ScrollPane meine Änderung an der Breite bereitwillig hin aber die Änderung an der Höhe nicht.

Einen Trumpf hab ich noch: Das NullLayout aber WARUM FUNKTIONIERT DAS BORDERLAYOUT NICHT?!!!😡

EDIT: Es war die ganze Zeit das GroupLayout aber auch das BorderLayout funktioniert nicht.


EDITEDIT: Ich hab es jetzt endlich hinbekommen. Es war ein harter Kampf Mensch gegen Maschine aber der Mensch hat gesiegt. Das BorderLayout in Verbindung mit dem revalidate() hat es gebracht.

Vielen vielen Dank kaoZ, für deine Mühen. Jetzt hagelt es erst mal Tops für dich. 😀
 
Zuletzt bearbeitet:
Nene. Ich meinte das in dem Dialog. Der Dialog hat sich angepasst. Nicht aber das JScrollPane darauf.
Das BorderLayout plus revalidate() haben es jetzt aber geschafft. 😀

Wenn ich mal Zeit hab, implementiere ich einen eigenen Layoutmanager, der genau das tut, was ich von ihm verlange. 😀
 
Zuletzt bearbeitet:

Neue Themen


Zurück
Oben