Zum Inhalt springen

SWT Layout Problem


diesy

Empfohlene Beiträge

Hallo,

ich habe ein kleines Problem mit dem Layout in SWT, vielleicht weiss ja einer da die Lösung.

Ich habe folgenden Tab:

img.php?loc=loc217ℑ=02487_name.jpg

Mein Problem besteht darin, dass die erste Zeile aus zwei Elementen bestehen soll und die zweite dann aus vier Elementen.

Die Lösung mit dem GridLayout ist nicht wirklich perfekt. Da ich die nicht benötigten Zellen im GridLayout mit leeren Labels ausfühle, was zu dieser Darstellung führt.

Das ganze im Quellcode:


private Control tabName(TabFolder tabFolder)

    {

        gridLayout = new GridLayout();

        gridLayout.numColumns = 4;

        gridLayout.horizontalSpacing = gridLayout.verticalSpacing = 6;


        nameComposite = new Composite(tabFolder, SWT.NONE);

        nameComposite.setLayout(gridLayout);

        nameComposite.setLayoutData(new GridData(GridData.FILL_BOTH));     


        endungMess = new Label(nameComposite, SWT.NONE);

        endungMess.setText("Name ändern in: ");


        trick = new Label(nameComposite, SWT.NONE);

        trick = new Label(nameComposite, SWT.NONE);


        nameEingabe = new Text(nameComposite, SWT.BORDER);

        nameEingabe.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));                


        nummMess = new Label(nameComposite, SWT.NONE);

        nummMess.setText("Dateien nummerieren, beginnen mit: ");


        num1 = new Spinner(nameComposite, SWT.BORDER);        

        num2 = new Spinner(nameComposite, SWT.BORDER);


        stellen = new Label(nameComposite, SWT.NONE);

        stellen.setText("Stellen");  


        return nameComposite;      

    }

Gibt es eine Lösung, ohne das ich die Elemente mit fixen Positionen platzieren kann? Oder kann man irgendwie mehrere Layouts schachteln, damit man auf eine gute Darstellung kommt? Einfach ein neues GridLayout zu erzeugen bringt leider nicht viel.

Gruß diesy.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hab vor kurzem einen kleinen Layoutmanager geschrieben, hat zwar noch Bugs u.s.w., aber er ist leicht zu benutzen und hat trotzdem viele Möglichkeiten.

Ist an das von Swing bekannte TableLayout angelehnt.

Mit dem Code kannst du von mir aus machen was du willst, ich übernehme keine Verantwortung *g*

TableLayout.java


package de.tablelayout;


import org.eclipse.swt.*;

import org.eclipse.swt.graphics.*;

import org.eclipse.swt.widgets.*;

import org.eclipse.swt.layout.*;


public class TableLayout extends Layout {

	private double[] layoutRows;


	private double[] layoutCols;


	Point[] sizes;


	int maxWidth, totalHeight;


	public final static int FILL = -1;


	public TableLayout(double[] cols, double[] rows) {

		this.layoutCols = cols;

		this.layoutRows = rows;

	}


	protected Point computeSize(Composite composite, int wHint, int hHint,

			boolean flushCache) {

		Control children[] = composite.getChildren();


		if (flushCache || sizes == null || sizes.length != children.length) {


			initialize(children);


		}


		int width = wHint, height = hHint;


		if (wHint == SWT.DEFAULT)

			width = maxWidth;


		if (hHint == SWT.DEFAULT)

			height = totalHeight;


		TableData td = (TableData)composite.getLayoutData();


		if(td != null){

			return new Point(width + td.getMarginLeft() + td.getMarginRight(), height + td.getMarginBottom() + td.getMarginTop());

		}

		else{

			return new Point(width, height);

		}



	}


	protected void layout(Composite composite, boolean flushCache) {

		Control children[] = composite.getChildren();


		if (flushCache || sizes == null || sizes.length != children.length) {

			initialize(children);

		}

		Rectangle rect = composite.getClientArea();


		double onePercentWidth = (double) ((double) rect.width / (double) 100);

		double onePercentHeight = (double) ((double) rect.height / (double) 100);


		int x = 0, y = 0;

		int width = 0;

		int height = 0;


		for (int i = 0; i < children.length; i++) {

			TableData td = (TableData) children[i].getLayoutData();

			if (td != null) {

				x = td.getMarginLeft() + (int)sizeTo(td.getCol(), onePercentWidth, layoutCols);

				y = td.getMarginTop() + (int)sizeTo(td.getRow(), onePercentHeight, layoutRows);


				width = (int)sizeTo(td.getCol(), td.getCol() + td.getStretchX(), onePercentWidth,

								layoutCols) - td.getMarginLeft() - td.getMarginRight();

				height = (int)sizeTo(td.getRow(), td.getRow() + td.getStretchY(), onePercentHeight,

								layoutRows) - td.getMarginTop() - td.getMarginBottom();


				}


				children[i].setBounds(x, y, width, height);


		}


	}


	private double getRest(double pixelPerPercent, double[] arr) {

		double val = pixelPerPercent * 100;

		for (int i = 0; i < arr.length; i++) {

			if (arr[i] != FILL){

				if(arr[i] > 1){

					val = val - arr[i];

				} else{

					val = val - (arr[i] * pixelPerPercent);

				}

			}

		}

		return val;

	}


	private double sizeTo(int start, int end, double pixelPerPercent, double[] arr) {

		double val = 0.0;

		for (int i = start; i <= end; i++) {

			if (arr[i] == FILL) {

				val = val + getRest(pixelPerPercent, arr);

			} else if(arr[i] > 1){

				val += arr[i];

			} else{

				val += (double)arr[i] * 100 * pixelPerPercent;

			}

		}

		return val;

	}

	private double sizeTo(int index, double pixelPerPercent, double[] arr) {

		int i = 0;

		double val = 0.0;

		while (i < index) {

			if (arr[i] == FILL) {

				val = val + getRest(pixelPerPercent, arr);

			} else if(arr[i] > 1) {

				val += arr[i];

			} else{

				val += (double)arr[i] * 100 * pixelPerPercent;

			}

			i++;

		}

		return val;

	}


	void initialize(Control children[]) {


		maxWidth = 0;


		totalHeight = 0;


		sizes = new Point[children.length];


		for (int i = 0; i < children.length; i++) {

			sizes[i] = children[i].computeSize(SWT.DEFAULT, SWT.DEFAULT, true);


			maxWidth = Math.max(maxWidth, sizes[i].x);


			totalHeight += sizes[i].y;


		}


		totalHeight += (children.length - 1);


	}


}

TableData.java

package de.tablelayout;


public class TableData{

	private int row;

	private int col;

	private int stretchX;

	private int stretchY;

	private int marginLeft;

	private int marginTop;

	private int marginRight;

	private int marginBottom;


	/**

	 * 

	 * @param col The column where the component should be placed

	 * @param row The row where the component should be placed

	 */

	public TableData(int col, int row) {

		super();

		this.row = row;

		this.col = col;

	}

	/**

	 * 

	 * @param col The column where the component should be placed

	 * @param row The row where the component should be placed

	 * @param stretchX The number of columns where the component should be streched about

	 * @param stretchY The number of rows where the component should be streched about

	 */

	public TableData(int col, int row, int stretchX, int stretchY) {

		super();

		this.row = row;

		this.col = col;

		this.stretchX = stretchX;

		this.stretchY = stretchY;

	}


	/**

	 * 

	 * @param col The column where the component should be placed

	 * @param row The row where the component should be placed

	 * @param margin The margin of the component ([0] - left, [1] - top, [2] - right, [3] - bottom)

	 */

	public TableData(int col, int row, int[] margin) {

		if(margin.length < 4)

			throw new IllegalArgumentException("Size of array 'margin' must be 4");

		this.row = row;

		this.col = col;

		marginLeft = margin[0];

		marginTop = margin[1];

		marginRight = margin[2];

		marginBottom = margin[3];


	}


	/**

	 * 

	 * @param col The column where the component should be placed

	 * @param row The row where the component should be placed

	 * @param stretchX The number of columns where the component should be streched about

	 * @param stretchY The number of rows where the component should be streched about

	 * @param margin The margin of the component ([0] - left, [1] - top, [2] - right, [3] - bottom)

	 */

	public TableData(int col, int row, int stretchX, int stretchY, int[] margin) {

		if(margin.length < 4)

			throw new IllegalArgumentException("Size of array 'margin' must be 4");

		this.row = row;

		this.col = col;

		this.stretchX = stretchX;

		this.stretchY = stretchY;

		marginLeft = margin[0];

		marginTop = margin[1];

		marginRight = margin[2];

		marginLeft = margin[3];


	}

	public int getCol() {

		return col;

	}

	public void setCol(int col) {

		this.col = col;

	}

	public int getRow() {

		return row;

	}

	public void setRow(int row) {

		this.row = row;

	}

	public int getStretchX() {

		return stretchX;

	}

	public void setStretchX(int stretchX) {

		this.stretchX = stretchX;

	}

	public int getStretchY() {

		return stretchY;

	}

	public void setStretchY(int stretchY) {

		this.stretchY = stretchY;

	}


	public int getMarginBottom() {

		return marginBottom;

	}


	public void setMarginBottom(int marginBottom) {

		this.marginBottom = marginBottom;

	}


	public int getMarginLeft() {

		return marginLeft;

	}


	public void setMarginLeft(int marginLeft) {

		this.marginLeft = marginLeft;

	}


	public int getMarginRight() {

		return marginRight;

	}


	public void setMarginRight(int marginRight) {

		this.marginRight = marginRight;

	}


	public int getMarginTop() {

		return marginTop;

	}


	public void setMarginTop(int marginTop) {

		this.marginTop = marginTop;

	}



}

TestApp.java

package Testapp;


import org.eclipse.swt.SWT;

import org.eclipse.swt.graphics.Point;

import org.eclipse.swt.graphics.Rectangle;

import org.eclipse.swt.layout.FillLayout;

import org.eclipse.swt.layout.GridLayout;

import org.eclipse.swt.widgets.Button;

import org.eclipse.swt.widgets.Composite;

import org.eclipse.swt.widgets.Display;

import org.eclipse.swt.widgets.Menu;

import org.eclipse.swt.widgets.MenuItem;

import org.eclipse.swt.widgets.Shell;


import com.cloudgarden.resource.SWTResourceManager;


import de.tablelayout.TableData;

import de.tablelayout.TableLayout;




public class TestApp extends org.eclipse.swt.widgets.Composite {


	{

		SWTResourceManager.registerResourceUser(this);

	}


	public TestApp(Composite parent, int style) {

		super(parent, style);

		initGUI();

	}


	/**

	* Initializes the GUI.

	*/

	private void initGUI() {

		try {

			this.setSize(new org.eclipse.swt.graphics.Point(400,300));

			this.setBackground(SWTResourceManager.getColor(192, 192, 192));

			TableData td = new TableData(0, 1);

			double[] cols = {0.25, 0.25, 0.25, 0.25};

			double[] rows = {0.25, 0.25, 0.25, 0.25};

			int[] margin = {5, 5, 5, 5};


			TableLayout tl = new TableLayout(cols, rows);

			this.setLayout(tl);


			td = new TableData(0, 0, margin);

			Button btn = new Button(this, SWT.PUSH);

			btn.setLayoutData(td);

			td = new TableData(1, 0, margin);

			td.setMarginTop(20);

			td.setMarginBottom(10);

			btn = new Button(this, SWT.PUSH);

			btn.setLayoutData(td);


			this.layout();

			this.pack();

		} catch (Exception e) {

			e.printStackTrace();

		}

	}


	public static void main(String[] args) {

		Display display = Display.getDefault();

		Shell shell = new Shell(display);

		TestApp inst = new TestApp(shell, SWT.NULL);

		Point size = inst.getSize();

		shell.setLayout(new FillLayout());

		shell.layout();

		if(size.x == 0 && size.y == 0) {

			inst.pack();

			shell.pack();

		} else {

			Rectangle shellBounds = shell.computeTrim(0, 0, size.x, size.y);

			shell.setSize(shellBounds.width, shellBounds.height);

		}

		shell.open();

		while (!shell.isDisposed()) {

			if (!display.readAndDispatch())

				display.sleep();

		}

	}


}


Link zu diesem Kommentar
Auf anderen Seiten teilen

Hab das Problem gelöst indem ich die Layouts verschachtelt habe. Man muss dazu einfach neue Composites für jeweils eine "Zeile" erstellen.

Am Ende sieht das dann so aus:

th_36448_Clipboard01.jpg

@ksg9-sebastian

habe dein Layout noch nicht probiert. müsste ich mal bei gelegenheit mal machen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Servus,

es hat zwar nichts mit Deiner direkten Frage nach Layoutmanagern zu tun, aber Du könntest Dir bei Gelegenheit die hier oft verlinkte Seite von Karsten Lentzsch anschauen (www.jgoodies.com. Dort vor Allem die Artikel zu gutem GUI-Design und oft gemachten aber leicht vermeidbaren Fehlern. Ist zwar alles mit Swing erklärt, und sein Layoutmanager ist auch bis jetzt nur für Swing (obwohl es scheinbar einen SWT-Port geben soll), aber die Konzepte dahinter sind universell.

Langer Rede kurzer Sinn: Dein Layout tut jetzt vielleicht, was es soll, aber es ist nicht schön. Es hat keinen Aufbau, der sich an der Logik gliedert und die grundlegenden gestalterischen Merkmale sind nicht berücksichtigt (Gesetz der Gruppe, Gesetz der Mitte, usw.)

Für gute GUIs genügt es nicht, alles darzustellen, sondern es muss auch nach was aussehen.

Peter

Link zu diesem Kommentar
Auf anderen Seiten teilen

Servus,

Karsten Lentzsch hat in jeder seiner Präsentationen und Artikel hinten ein Quellenverzeichnis mit sehr guten Büchern.

Ansonsten kannst Du mal bei wikipedia mit dem Stichwort "GUI" anfangen und Dich über "Mensch-Computer-Interaktion" und "Benutzerfreundlichkeit" weiterarbeiten. Das Thema Benutzeroberfläche ist ein sehr weit gefächertes und deshalb sehr umfangreich. Für einen schnellen Einstieg ist mir bis jetzt nichts besseres als Karsten Lentzschs Präsentationen und Artikel untergekommen. Ich habe mit diesen auch fürs Studium (Fach Mensch-Computer-Kommunikation) den Bereich Benutzeroberflächen und Ergonomie bzw. gestalterische Elemente besser erarbeiten können als mit den teilweise sehr abstrakten und theoretischen Werken der Wissenschaft. :)

Peter

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...