EasyGridLayout

Status
Nicht offen für weitere Antworten.

Ariol

Top Contributor
Hi,

ich hab mir gerade einen Layout-Manager geschrieben.

Code:
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.LayoutManager2;
import java.util.ArrayList;

public class EasyGridLayout implements LayoutManager2, java.io.Serializable
{

	private static final long	serialVersionUID	= -7699432214754795997L;

	private ArrayList<EasyGridComponent>	compList	= new ArrayList<EasyGridComponent>();

	private int								columns		= 1;

	private int								rows		= 1;

	private int								hGap		= 0;

	private int								vGap		= 0;

	public EasyGridLayout(int rows, int columns)
	{
		this(rows, columns, 0, 0);
	}

	public EasyGridLayout(int rows, int columns, int hGap, int vGap)
	{
		if (rows > 0 && columns > 0)
		{
			setRows(rows);
			setColumns(columns);
		}
		if (hGap >= 0 && vGap >= 0)
		{
			setHGap(hGap);
			setVGap(vGap);
		}

	}

	public int getColumns()
	{
		return columns;
	}

	public void setColumns(int columns)
	{
		if (columns > 0)
		{
			this.columns = columns;
		}
	}

	public int getHGap()
	{
		return hGap;
	}

	public void setHGap(int gap)
	{
		if (gap >= 0)
		{
			hGap = gap;
		}
	}

	public int getRows()
	{
		return rows;
	}

	public void setRows(int rows)
	{
		if (rows > 0)
		{
			this.rows = rows;
		}
	}

	public int getVGap()
	{
		return vGap;
	}

	public void setVGap(int gap)
	{
		if (vGap >= 0)
		{
			vGap = gap;
		}

	}

	public void addLayoutComponent(Component comp, Object constraints)
	{
		if (constraints instanceof EasyGridConstraints)
		{
			compList.add(new EasyGridComponent(comp, (EasyGridConstraints) constraints));
		}
	}

	public float getLayoutAlignmentX(Container target)
	{
		return 0;
	}

	public float getLayoutAlignmentY(Container target)
	{
		return 0;
	}

	public void invalidateLayout(Container target)
	{
	}

	public void addLayoutComponent(String name, Component comp)
	{
	}

	public void layoutContainer(Container parent)
	{
		int parentWidth = parent.getWidth();
		int parentHeight = parent.getHeight();

		int gridWidth = parentWidth;
		int gridHeight = parentHeight;

		int columns = getColumns();
		int rows = getRows();

		if (columns > 0)
		{
			gridWidth /= columns;
		}
		if (rows > 0)
		{
			gridHeight /= rows;
		}

		for (EasyGridComponent easyGridComponent : compList)
		{
			Component comp = easyGridComponent.getComponent();
			EasyGridConstraints easyGridConstraints = easyGridComponent.getConstraints();

			int constraintsColumns = easyGridConstraints.getColumns();
			int constraintsRows = easyGridConstraints.getRows();

			int x = easyGridConstraints.getColumn() * (gridWidth + getHGap());
			int y = easyGridConstraints.getRow() * (gridHeight + getVGap());
			int width = (constraintsColumns * gridWidth) + ((constraintsColumns - 1) * getHGap());
			int height = (constraintsRows * gridHeight) + ((constraintsRows - 1) * getVGap());

			comp.setBounds(x, y, width, height);
		}
	}

	public void removeLayoutComponent(Component comp)
	{
		for (EasyGridComponent easyGridComponent : compList)
		{
			if (easyGridComponent.getComponent().equals(comp))
			{
				compList.remove(easyGridComponent);
				break;
			}
		}
	}

	public Dimension minimumLayoutSize(Container parent)
	{
		synchronized (parent.getTreeLock())
		{
			Insets insets = parent.getInsets();
			int width = insets.left + insets.right;
			int height = insets.top + insets.bottom;

			for (EasyGridComponent easyGridComponent : compList)
			{
				Component c = easyGridComponent.getComponent();

				Dimension size = c.getMinimumSize();

				width += size.width;
				height += size.height;
			}

			Dimension gapSize = getGapSize();

			width += gapSize.width;
			height += gapSize.height;

			return new Dimension(width, height);
		}
	}

	public Dimension preferredLayoutSize(Container parent)
	{
		synchronized (parent.getTreeLock())
		{
			Insets insets = parent.getInsets();
			int width = insets.left + insets.right;
			int height = insets.top + insets.bottom;

			for (EasyGridComponent easyGridComponent : compList)
			{
				Component c = easyGridComponent.getComponent();

				Dimension size = c.getPreferredSize();

				width += size.width;
				height += size.height;
			}

			Dimension gapSize = getGapSize();

			width += gapSize.width;
			height += gapSize.height;

			return new Dimension(width, height);
		}
	}

	public Dimension maximumLayoutSize(Container parent)
	{
		synchronized (parent.getTreeLock())
		{
			Insets insets = parent.getInsets();
			int width = insets.left + insets.right;
			int height = insets.top + insets.bottom;

			for (EasyGridComponent easyGridComponent : compList)
			{
				Component c = easyGridComponent.getComponent();

				Dimension size = c.getMaximumSize();

				width += size.width;
				height += size.height;
			}

			Dimension gapSize = getGapSize();

			width += gapSize.width;
			height += gapSize.height;

			return new Dimension(width, height);
		}
	}

	private Dimension getGapSize()
	{
		int width = getHGap() * (getColumns() - 1);
		int height = getVGap() * (getRows() - 1);

		return new Dimension(width, height);
	}

	private class EasyGridComponent
	{
		Component			component;

		EasyGridConstraints	constraints;

		EasyGridComponent(Component comp, EasyGridConstraints constraints)
		{
			setComponent(comp);
			setConstraints(constraints);
		}

		private Component getComponent()
		{
			return component;
		}

		private void setComponent(Component component)
		{
			this.component = component;
		}

		private EasyGridConstraints getConstraints()
		{
			return constraints;
		}

		private void setConstraints(EasyGridConstraints constraints)
		{
			this.constraints = constraints;
		}

	}

}

Als Constraints benutzt man diese Klasse:
Code:
public class EasyGridConstraints
{
	int row = 0;
	int column = 0;
	int rows = 1;
	int columns = 1;
	
	

	public EasyGridConstraints(int row, int column)
	{
		this(row, column, 1, 1);
	}

	public EasyGridConstraints(int row, int column, int rows, int columns)
	{
		setRow(row);
		setColumn(column);
		setRows(rows);
		setColumns(columns);
	}

	public int getColumn()
	{
		return column;
	}

	private void setColumn(int column)
	{
		this.column = column;
	}

	public int getColumns()
	{
		return columns;
	}

	private void setColumns(int columns)
	{
		this.columns = columns;
	}

	public int getRow()
	{
		return row;
	}

	private void setRow(int row)
	{
		this.row = row;
	}

	public int getRows()
	{
		return rows;
	}

	private void setRows(int rows)
	{
		this.rows = rows;
	}
	
	
	
	
}

Und hier eine Testklasse:
Code:
import javax.swing.JButton;
import javax.swing.JFrame;

public class Test
{
	public static void main(String[] args)
	{
		final JFrame f = new JFrame();
		f.setLayout(new EasyGridLayout(5, 5));
		for (int i = 0; i < 5; i++)
		{
			f.add(new JButton(i + ""), new EasyGridConstraints(i, i));
		}
		f.add(new JButton("Woanders"), new EasyGridConstraints(2, 0, 3, 2));
		f.pack();
		f.setVisible(true);
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
}


Soweit funktioniert das alles schon so wie's soll, ABER beim einfügen von Gaps fehlt ein Teil.
Ich vermute stark, dass es an meinen LayoutSize()-Methoden liegt, aber ich kann den Fehler nicht finden....

Hier die Testklasse mit Gaps:
Code:
import javax.swing.JButton;
import javax.swing.JFrame;

public class TestMitGap
{
	public static void main(String[] args)
	{
		final JFrame f = new JFrame();
		f.setLayout(new EasyGridLayout(5, 5, 10, 10));
		for (int i = 0; i < 5; i++)
		{
			f.add(new JButton(i + ""), new EasyGridConstraints(i, i));
		}
		f.add(new JButton("Woanders"), new EasyGridConstraints(2, 0, 3, 2));
		f.pack();
		f.setVisible(true);
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
}

Danke schonmal im vorraus, an jeden der sich dran versucht :wink:


Ach ja, die Frage fehlt ja noch :bae: :

Was habe ich außer Acht gelassen. Was an meinen layoutSize()-Methoden ist falsch und wie kann ich es beheben?
 

Ariol

Top Contributor
Keiner eine Idee?

Ich hab mittlerweile den Code so zerpflügt, dass ich die Version von hier wiederherstellen musste.

Naja, wenigstens weiß ich jetzt sicher, dass es an den layoutSize-Methoden liegt. Erweitere ich diese um Konstanten funktioniert es - aber das ist natürlich keine akzeptable Lösung.
 

Ariol

Top Contributor
Hab' die Klasse jetzt noch insofern erweitert, dass man auch ohne Constraints Komponenten adden kann.

Außerdem ist nun eine Abfrage drin, dass Komponenten, die "aus dem Rahmen fallen" eine Exception werfen...

Aber das Problem ist immer noch vorhanden - der Frame ist immer (auch nach einer Größenänderung) zu klein.

Code:
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.LayoutManager2;
import java.awt.Point;
import java.util.ArrayList;

public class EasyGridLayout implements LayoutManager2, java.io.Serializable
{

	private static final long				serialVersionUID	= -7699432214754795997L;

	private ArrayList<EasyGridComponent>	compList			= new ArrayList<EasyGridComponent>();

	private int								columns				= 1;

	private int								rows				= 1;

	private int								hGap				= 0;

	private int								vGap				= 0;

	public EasyGridLayout(int rows, int columns)
	{
		this(rows, columns, 0, 0);
	}

	public EasyGridLayout(int rows, int columns, int hGap, int vGap)
	{
		if (rows > 0 && columns > 0)
		{
			setRows(rows);
			setColumns(columns);
		}
		if (hGap >= 0 && vGap >= 0)
		{
			setHGap(hGap);
			setVGap(vGap);
		}
	}

	public int getColumns()
	{
		return columns;
	}

	public void setColumns(int columns)
	{
		if (columns > 0)
		{
			this.columns = columns;
		}
	}

	public int getHGap()
	{
		return hGap;
	}

	public void setHGap(int gap)
	{
		if (gap >= 0)
		{
			hGap = gap;
		}
	}

	public int getRows()
	{
		return rows;
	}

	public void setRows(int rows)
	{
		if (rows > 0)
		{
			this.rows = rows;
		}
	}

	public int getVGap()
	{
		return vGap;
	}

	public void setVGap(int gap)
	{
		if (vGap >= 0)
		{
			vGap = gap;
		}

	}

	public void addLayoutComponent(Component comp, Object constraints)
	{
		EasyGridConstraints easyGridConstraints;

		if (constraints instanceof EasyGridConstraints)
		{
			easyGridConstraints = (EasyGridConstraints) constraints;
		}
		else
		{
			Point emptyField = getEmptyField();
			easyGridConstraints = new EasyGridConstraints(emptyField.y, emptyField.x);
		}

		int lastColumn = easyGridConstraints.getColumn() + easyGridConstraints.getColumns()-1;
		int lastRow = easyGridConstraints.getRow() + easyGridConstraints.getRows()-1;
		
		
		if(lastColumn < getColumns() && lastRow < getRows())
		{
			compList.add(new EasyGridComponent(comp, easyGridConstraints));
		}
		else
		{
			StringBuilder sb = new StringBuilder(easyGridConstraints.toString());
			sb.append(" out of bounds ");
			sb.append("(");
			sb.append("rows:");
			sb.append(getRows());
			sb.append(",");
			sb.append("colums:");
			sb.append(getColumns());
			sb.append(")");
			
			throw new IndexOutOfBoundsException(sb.toString());
		}
	}

	private Point getEmptyField()
	{

		boolean grid[][] = new boolean[getColumns()][getRows()];

		for (EasyGridComponent easyGridComponent : compList)
		{
			int row = easyGridComponent.getConstraints().getRow();
			int rows = easyGridComponent.getConstraints().getRows();
			int column = easyGridComponent.getConstraints().getColumn();
			int columns = easyGridComponent.getConstraints().getColumns();

			for (int i = column; i < column + columns; i++)
			{
				for (int j = row; j < row + rows; j++)
				{
					grid[i][j] = true;
				}
			}
		}
		for (int i = 0; i < grid.length; i++)
		{
			for (int j = 0; j < grid[i].length; j++)
			{
				if (grid[j][i] == false)
				{
					return new Point(j, i);
				}
			}
		}
		return new Point(getColumns(), getRows());
	}
	
	public float getLayoutAlignmentX(Container target)
	{
		return 0;
	}

	public float getLayoutAlignmentY(Container target)
	{
		return 0;
	}

	public void invalidateLayout(Container target)
	{
	}

	public void addLayoutComponent(String name, Component comp)
	{
	}

	public void layoutContainer(Container parent)
	{
		int parentWidth = parent.getWidth();
		int parentHeight = parent.getHeight();

		int gridWidth = parentWidth;
		int gridHeight = parentHeight;

		int columns = getColumns();
		int rows = getRows();

		if (columns > 0)
		{
			gridWidth /= columns;
		}
		if (rows > 0)
		{
			gridHeight /= rows;
		}

		for (EasyGridComponent easyGridComponent : compList)
		{
			Component comp = easyGridComponent.getComponent();
			EasyGridConstraints easyGridConstraints = easyGridComponent.getConstraints();

			int constraintsColumns = easyGridConstraints.getColumns();
			int constraintsRows = easyGridConstraints.getRows();

			int x = easyGridConstraints.getColumn() * (gridWidth + getHGap());
			int y = easyGridConstraints.getRow() * (gridHeight + getVGap());
			int width = (constraintsColumns * gridWidth);
			int height = (constraintsRows * gridHeight);

			comp.setBounds(x, y, width, height);
		}
	}

	public void removeLayoutComponent(Component comp)
	{
		for (EasyGridComponent easyGridComponent : compList)
		{
			if (easyGridComponent.getComponent().equals(comp))
			{
				compList.remove(easyGridComponent);
				break;
			}
		}
	}

	public Dimension minimumLayoutSize(Container parent)
	{
		synchronized (parent.getTreeLock())
		{
			Insets insets = parent.getInsets();
			int width = insets.left + insets.right;
			int height = insets.top + insets.bottom;

			for (EasyGridComponent easyGridComponent : compList)
			{
				Component c = easyGridComponent.getComponent();

				Dimension size = c.getMinimumSize();

				width += size.width;
				height += size.height;
			}

			Dimension gapSize = getGapSize();

			width += gapSize.width;
			height += gapSize.height;

			return new Dimension(width, height);
		}
	}

	public Dimension preferredLayoutSize(Container parent)
	{
		synchronized (parent.getTreeLock())
		{
			Insets insets = parent.getInsets();
			int width = insets.left + insets.right;
			int height = insets.top + insets.bottom;

			for (EasyGridComponent easyGridComponent : compList)
			{
				Component c = easyGridComponent.getComponent();

				Dimension size = c.getPreferredSize();

				width += size.width;
				height += size.height;
			}

			Dimension gapSize = getGapSize();

			width += gapSize.width;
			height += gapSize.height;

			return new Dimension(width, height);
		}
	}

	public Dimension maximumLayoutSize(Container parent)
	{
		synchronized (parent.getTreeLock())
		{
			Insets insets = parent.getInsets();
			int width = insets.left + insets.right;
			int height = insets.top + insets.bottom;

			for (EasyGridComponent easyGridComponent : compList)
			{
				Component c = easyGridComponent.getComponent();

				Dimension size = c.getMaximumSize();

				width += size.width;
				height += size.height;
			}

			Dimension gapSize = getGapSize();

			width += gapSize.width;
			height += gapSize.height;

			return new Dimension(width, height);
		}
	}

	private Dimension getGapSize()
	{
		int width = getHGap() * (getColumns() - 1);
		int height = getVGap() * (getRows() - 1);

		return new Dimension(width, height);
	}

	private class EasyGridComponent
	{
		Component			component;

		EasyGridConstraints	constraints;

		EasyGridComponent(Component comp, EasyGridConstraints constraints)
		{
			setComponent(comp);
			setConstraints(constraints);
		}

		private Component getComponent()
		{
			return component;
		}

		private void setComponent(Component component)
		{
			this.component = component;
		}

		private EasyGridConstraints getConstraints()
		{
			return constraints;
		}

		private void setConstraints(EasyGridConstraints constraints)
		{
			this.constraints = constraints;
		}

	}

}
 

Ariol

Top Contributor
Push! ;)

Hat sich bisher noch niemand an einem eigenen Layout versucht?
Bitte gebt mir doch wenigstens einen Hinweis was falsch ist.

Oder versucht den LayoutManager mal aus und sagt mir wie er euch gefällt (Die Variante ohne Gaps natürlich ;) )

Danke für alle Antworten.
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Oben