SWT ScrolledComposite mag mich nicht

Bernd Hohmann

Top Contributor
Ich versuche mich hier gerade an einer Gallerie für Icons 160x100.
Dazu erzeuge ich ein ScrolledComposite in das ich ein Composite mit RowLayout packe.
In das Composite werden dann Labels gelegt und mit den Icon-Images bestückt.

Das funktioniert soweit, nur verweigert sich das ScrolledComposite zu erkennen dass sein Child um einiges grösser ist.

Was tun, sprach Zeus?

Java:
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.RowLayout;

public class GalleryTest {
	protected static ScrolledComposite scrlMain;
	protected static Composite cmpGallery;

	public static void main(String[] args) {
		Display display = Display.getDefault();
		Shell shell = new Shell();
		shell.setSize(530, 153);
		shell.setText("SWT Application");
		//
		scrlMain = new ScrolledComposite(shell, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
		scrlMain.setAlwaysShowScrollBars(true);
		scrlMain.setBounds(0, 0, 524, 126);
		scrlMain.setExpandHorizontal(true);
		scrlMain.setExpandVertical(true);
		//
		cmpGallery = new Composite(scrlMain, SWT.NONE);
		RowLayout rl_cmpGallery = new RowLayout(SWT.HORIZONTAL);
		rl_cmpGallery.justify = true;
		rl_cmpGallery.fill = true;
		rl_cmpGallery.wrap = false;
		cmpGallery.setLayout(rl_cmpGallery);
		scrlMain.setContent(cmpGallery);
		scrlMain.setMinSize(cmpGallery.computeSize(SWT.DEFAULT, SWT.DEFAULT));

		shell.open();
		shell.layout();

		// -------------
		for (int i = 0; i < 5; i++) {
			Image img = new Image(display, 160, 100);

			GC gcImg = new GC(img);
			gcImg.drawRectangle(0, 0, 160 - 1, 100 - 1);
			gcImg.drawLine(0, 0, 160 - 1, 100);
			gcImg.drawLine(160 - 1, 0, 0, 100 - 1);
			gcImg.drawString("#" + i, 5, 40);
			gcImg.dispose();
			//
			Label lbl = new Label(cmpGallery, SWT.NONE);
			lbl.setImage(img);
			lbl.setSize(160, 100);
		}
		cmpGallery.pack();
		//scrlMain.pack();
		//scrlMain.layout();
		// -------------

		while (!shell.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}
	}
}
 

Anhänge

  • Bildschirmfoto.png
    Bildschirmfoto.png
    7,8 KB · Aufrufe: 48
Ansonsten solltest du die RowLayout richtig setzen und der Shell natürlich auch ein Layout mitgeben
Java:
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;

public class GalleryTest {
	protected static ScrolledComposite scrlMain;
	protected static Composite cmpGallery;

	public static void main(String[] args) {
		Display display = Display.getDefault();
		Shell shell = new Shell();
		shell.setSize(530, 153);
		shell.setText("SWT Application");
		shell.setLayout(new FillLayout());
		//
		scrlMain = new ScrolledComposite(shell, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
		//
		cmpGallery = new Composite(scrlMain, SWT.NONE);
		RowLayout rl_cmpGallery = new RowLayout(SWT.HORIZONTAL);
		cmpGallery.setLayout(rl_cmpGallery);
		scrlMain.setContent(cmpGallery);

		shell.open();
		shell.layout();

		// -------------
		for (int i = 0; i < 5; i++) {
			Image img = new Image(display, 160, 100);

			GC gcImg = new GC(img);
			gcImg.drawRectangle(0, 0, 160 - 1, 100 - 1);
			gcImg.drawLine(0, 0, 160 - 1, 100);
			gcImg.drawLine(160 - 1, 0, 0, 100 - 1);
			gcImg.drawString("#" + i, 5, 40);
			gcImg.dispose();
			//
			Label lbl = new Label(cmpGallery, SWT.NONE);
			lbl.setImage(img);
			lbl.setSize(160, 100);
		}
		cmpGallery.pack();
		// scrlMain.pack();
		// scrlMain.layout();
		// -------------

		while (!shell.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}
	}
}
 
Ich habe Deinen Vorschlag grob durchgesehen und getestet - er macht das gewollte, aber meine Shell hat leider kein FillLayout aktiv.

Was willst du mir damit sagen? Wo liegt das Problem?
Deine Shell brauch ein LayoutManager GridLayout oder FillLayout sonst geht es nicht

Die für einzeilige Gallerien nicht so recht funktioniert und darüber hinaus auch ein Lizenzproblem für mich hat.

Was für ein Lizenzsproblem?
 
Was willst du mir damit sagen? Wo liegt das Problem?
Deine Shell brauch ein LayoutManager GridLayout oder FillLayout sonst geht es nicht

Ich steh halt bisserl auf dem Schlauch: Warum braucht der Parent einen Layoutmanager? Ich dachte, das das Scrolling im ScrolledComposite stattfindet.

Mein Problem ist, dass ich das später als eigenes Widget nutzen möchte. Reicht es, wenn ich da nochmal eine Component mit FillLayout drunterlege (also zwischen ScrolledComposite und Shell)?

Bernd
 
Ich steh halt bisserl auf dem Schlauch: Warum braucht der Parent einen Layoutmanager? Ich dachte, das das Scrolling im ScrolledComposite stattfindet.
Ja klar brauch der parent eine LayoutManger wie soll er sonst die richtigen Größen definieren.
Eclipse Corner Article: Understanding Layouts in SWT


Mein Problem ist, dass ich das später als eigenes Widget nutzen möchte. Reicht es, wenn ich da nochmal eine Component mit FillLayout drunterlege (also zwischen ScrolledComposite und Shell)?

Klar kannst ein Composite dafür verwenden.
 
Jede Komponente braucht eine Größe und eine Position.
Entweder du gibst diese fest vor oder du nutzt einen Layoutmanager.

Ja Problem ist wenn er Sie fest mit gibt, muss er die Größe des ScrollComposite selber berechnen.
Denk mal das war sein Problem im 1. Beispiel, kann mich aber auch irren.
 
Jo, wollte nur nochmal klarmachen, warum der Parent ein Layout braucht. Klingt so, als hätte der TO noch nicht ganz verstanden was es mit Layouting auf sich hat.
 
Jo, wollte nur nochmal klarmachen, warum der Parent ein Layout braucht. Klingt so, als hätte der TO noch nicht ganz verstanden was es mit Layouting auf sich hat.

Was Layoutmanager machen weiss ich schon (irgendwann hab ich ja auch welche geschrieben).

Meine Shell hat im Orginalcode einen Layoutmanager: nämlich keinen ("Absolute Layout") und Position und Größe des ScrolledComposite wird fix mit "scrlMain.setBounds(0, 0, 524, 126);" definiert.

Das ScrolledComposite wird ja auch in der gewünschten Größe angezeigt, nur das darin liegende Composite (mit seinem RowLayout) will partout nicht über die Bounds seines Parents wachsen.

Deshalb bin ich irritiert warum das nicht geht - es sei denn, SWT ist an dieser Stelle ganz anders als ich denke.

Bernd

PS: Interessanterweise geht es auch nicht, wenn die Shell ein GroupLayout hat. Da muss ich mal forschen gehen.
 
Also ich hab mal deinen code angeschaut, den du im ersten Post drin hast.
Dein Problem scheint ja zu sein, dass die Scrollbars nicht erscheinen. (bzw. deaktiviert sind)

Das liegt weder am Layout, noch an der Composite oder ähnlichem.
Das liegt in deinem Fall schlicht an der Reihenfolge der Tätigkeiten.

Deine Reihenfolge:

1. ScrolledComposite erstellen
2. Child Composite erstellen
3. Größe der Child Composite berechnen und als MinSize an die ScrolledComposite übergeben.
4. Inhalt des Child Composite erstellen.

Hier ist auch dein Fehler.
Du berechnest die Größe des Child Composites zu einem Zeitpunkt an dem es gar nicht weiß, wie groß es denn sein muss. Zu diesem Zeitpunkt hat es keine Children und somit keine Größe!

Die richtige Reihenfolge wäre also, wenn du Schritt 3 und 4 tauschst

Dein Code müsste also in etwa so aussehen um Scrollbalken anzuzeigen

Java:
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.RowLayout;

public class GalleryTest {

	protected static ScrolledComposite	scrlMain;
	protected static Composite			cmpGallery;

	public static void main(String[] args) {
		Display display = Display.getDefault();
		Shell shell = new Shell();
		shell.setSize(530, 153);
		shell.setText("SWT Application");
		//
		scrlMain = new ScrolledComposite(shell, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
		scrlMain.setAlwaysShowScrollBars(true);
		scrlMain.setBounds(0, 0, 524, 126);
		scrlMain.setExpandHorizontal(true);
		scrlMain.setExpandVertical(true);
		//
		cmpGallery = new Composite(scrlMain, SWT.NONE);
		RowLayout rl_cmpGallery = new RowLayout(SWT.HORIZONTAL);
		rl_cmpGallery.justify = true;
		rl_cmpGallery.fill = true;
		rl_cmpGallery.wrap = false;
		cmpGallery.setLayout(rl_cmpGallery);
		scrlMain.setContent(cmpGallery);

		shell.open();
		shell.layout();

		// -------------
		for (int i = 0; i < 5; i++) {
			Image img = new Image(display, 160, 100);

			GC gcImg = new GC(img);
			gcImg.drawRectangle(0, 0, 160 - 1, 100 - 1);
			gcImg.drawLine(0, 0, 160 - 1, 100);
			gcImg.drawLine(160 - 1, 0, 0, 100 - 1);
			gcImg.drawString("#" + i, 5, 40);
			gcImg.dispose();
			//
			Label lbl = new Label(cmpGallery, SWT.NONE);
			lbl.setImage(img);
			lbl.setSize(160, 100);
		}
		cmpGallery.pack();
		// scrlMain.pack();
		// scrlMain.layout();
		// -------------
		scrlMain.setMinSize(cmpGallery.computeSize(SWT.DEFAULT, SWT.DEFAULT));

		while (!shell.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}
	}
}
 
Also ich hab mal deinen code angeschaut, den du im ersten Post drin hast.
Dein Problem scheint ja zu sein, dass die Scrollbars nicht erscheinen. (bzw. deaktiviert sind)

Das liegt weder am Layout, noch an der Composite oder ähnlichem.
Das liegt in deinem Fall schlicht an der Reihenfolge der Tätigkeiten.

Problem lag wo ganz anders nachdem ich in den Source der Komponente geschaut habe:

Java:
scrlMain.setExpandHorizontal(true);
scrlMain.setExpandVertical(true);

ist an dieser Stelle völliger Käse und darf nicht gesetzt werden.

Ich werde zu alt für diesen Kram 😳

Bernd
 
sicher darf das angewendet werden. Es ist auch nicht völliger Käse.
Nur muss dann eben über setMinSize gearbeitet werden und das eben zu den richtigen Zeitpunkten.
 
Danke für die Hilfe, ich habe es nun verstanden und anhand von paar Testcases memoriert.

Leider hat sich herausgestellt, dass ich die Konstruktion nicht nehmen kann - bei vielen Bildern wird das unhandlich wenn da hunderte von Labels drinstecken und ganz arg wirds, wenn ein resize durchgeführt werden muss.

Der weise Mann folgt nur sich selbst - ich schnapp mir jetzt ein Composite und überleg mir was.

Bernd
 
Danke für die Hilfe, ich habe es nun verstanden und anhand von paar Testcases memoriert.

Leider hat sich herausgestellt, dass ich die Konstruktion nicht nehmen kann - bei vielen Bildern wird das unhandlich wenn da hunderte von Labels drinstecken und ganz arg wirds, wenn ein resize durchgeführt werden muss.

Der weise Mann folgt nur sich selbst - ich schnapp mir jetzt ein Composite und überleg mir was.

Bernd

Schau dir doch den Code von der Gallery an du darfst nur die Bilder anzeigen, die der Benutzer sieht und beim Scrollen nachladen (siehe SWT.VIRTUAL)
 
Schau dir doch den Code von der Gallery an du darfst nur die Bilder anzeigen, die der Benutzer sieht und beim Scrollen nachladen (siehe SWT.VIRTUAL)

Ich werde mich mal einlesen, danke!

Hast Du zufällig einen Tip für folgendes Problem: Ein Label im Seitenverhältnis 16:10 zeigt normalerweise Bilder im Landscape-Modus an. Portraits werden auf die Höhe des Labels skaliert. Wenn ich ein Portrait-Image dem Label zuweise, wird das an die linke Seite geklatscht angezeigt. Gibts eine einfache Methode, Images auf einem Label zu horizontal zu zentrieren oder muss ich das Image erst in einen eigenen Kontext mittig kopieren und dann im Label setzen?

LG,
Bernd
 

Neue Themen


Zurück
Oben