⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 variablegridlayout.java

📁 用于java swing的皮肤软件
💻 JAVA
字号:
package com.digitprop.tonic;


import java.awt.*;


/**
 * This layout manager is somewhat similiar to the GridLayout, with the
 * difference that the rows and columns need not all have the same size.
 * <p>
 * 
 * Each row has the height of highest component in it, and each column has the
 * width of the widest component in it, but neighbouring columns can (and will)
 * have different widths, and neighbouring rows can (and will) have different
 * heights.
 * <p>
 * 
 * In this way, it is easy to align components for tabular layouts, without
 * adding unwanted extra white space.
 * <p>
 * 
 * Other than that, this layout works similiar to the GridLayout.
 * 
 * @see GridLayout
 * 
 * @author Markus Fischer
 * 
 * This software is under the <a
 * href="http://www.gnu.org/copyleft/lesser.html">GNU Lesser General Public
 * License </a>
 */

/*
 * ------------------------------------------------------------------------
 * Copyright (C) 2004 Markus Fischer
 * 
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License version 2.1 as
 * published by the Free Software Foundation.
 * 
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
 * for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 * 
 * You can contact the author at: Markus Fischer www.digitprop.com
 * info@digitprop.com
 * ------------------------------------------------------------------------
 */
public class VariableGridLayout extends GridLayout
{
	/**
	 * This is the horizontal gap (in pixels) which specifies the space between
	 * columns. They can be changed at any time. This should be a non-negative
	 * integer.
	 */
	int	hgap;

	/**
	 * This is the vertical gap (in pixels) which specifies the space between
	 * rows. They can be changed at any time. This should be a non negative
	 * integer.
	 */
	int	vgap;

	/**
	 * This is the number of rows specified for the grid. The number of rows can
	 * be changed at any time. This should be a non negative integer, where '0'
	 * means 'any number' meaning that the number of Rows in that dimension
	 * depends on the other dimension.
	 */
	int	rows;

	/**
	 * This is the number of columns specified for the grid. The number of
	 * columns can be changed at any time. This should be a non negative
	 * integer, where '0' means 'any number' meaning that the number of Columns
	 * in that dimension depends on the other dimension.
	 */
	int	cols;


	/**
	 * Creates an instance with a default of one column per component, in a
	 * single row.
	 */
	public VariableGridLayout()
	{
		this(1, 0, 0, 0);
	}


	/**
	 * Creates an instance with the specified number of rows and columns.
	 * <p>
	 * 
	 * One, but not both, of <code>rows</code> and <code>cols</code> can be
	 * zero, which means that any number of objects can be placed in a row or in
	 * a column.
	 * 
	 * @param rows
	 *        The number of rows in this layout. Zero means that the layout can
	 *        have any number of rows
	 * @param cols
	 *        The number of columns in this layout. Zero means that the layout
	 *        can have any number of columns
	 */
	public VariableGridLayout(int rows, int cols)
	{
		this(rows, cols, 0, 0);
	}


	/**
	 * Creates an instance with the specified number of rows and columns.
	 * <p>
	 * 
	 * One, but not both, of <code>rows</code> and <code>cols</code> can be
	 * zero, which means that any number of objects can be placed in a row or in
	 * a column.
	 * 
	 * @param rows
	 *        The number of rows in this layout. Zero means that the layout can
	 *        have any number of rows
	 * @param cols
	 *        The number of columns in this layout. Zero means that the layout
	 *        can have any number of columns
	 * @param hgap
	 *        The gap (in pixels) between two columns
	 * @param vgap
	 *        The gap (in pixels) between two rows
	 * 
	 * @exception IllegalArgumentException
	 *            if the value of both <code>rows</code> and <code>cols</code>
	 *            is set to zero
	 */
	public VariableGridLayout(int rows, int cols, int hgap, int vgap)
	{
		if ((rows == 0) && (cols == 0))
		{
			throw new IllegalArgumentException("rows and cols cannot both be zero");
		}
		this.rows = rows;
		this.cols = cols;
		this.hgap = hgap;
		this.vgap = vgap;
	}


	/** Returns the number of rows in this layout */
	public int getRows()
	{
		return rows;
	}


	/** Sets the number of rows in this layout */
	public void setRows(int rows)
	{
		if ((rows == 0) && (this.cols == 0))
		{
			throw new IllegalArgumentException("rows and cols cannot both be zero");
		}
		this.rows = rows;
	}


	/** Returns the number of columns in this layout */
	public int getColumns()
	{
		return cols;
	}


	/** Sets the number of columsn in this layout */
	public void setColumns(int cols)
	{
		if ((cols == 0) && (this.rows == 0))
		{
			throw new IllegalArgumentException("rows and cols cannot both be zero");
		}
		this.cols = cols;
	}


	/** Returns the horizontal gap between columns */
	public int getHgap()
	{
		return hgap;
	}


	/** Sets the horizontal gap between columns */
	public void setHgap(int hgap)
	{
		this.hgap = hgap;
	}


	/** Returns the vertical gap between rows */
	public int getVgap()
	{
		return vgap;
	}


	/** Sets the vertical gap between rows */
	public void setVgap(int vgap)
	{
		this.vgap = vgap;
	}


	/**
	 * Adds the specified component to the layout.
	 * 
	 * @param name
	 *        The name of the component
	 * @param comp
	 *        The component to be added
	 */
	public void addLayoutComponent(String name, Component comp)
	{
		// Does nothing
	}


	/** Removes the specified component from the layout */
	public void removeLayoutComponent(Component comp)
	{
		// Does nothing
	}


	/**
	 * Returns the preferred size of the specified container, using this layout.
	 * <p>
	 * 
	 * This is the sum of all column widths, and the sum of all row heights.
	 * Each column has the width of the widest contained component, and each row
	 * has the height of the highest contained component.
	 * 
	 * @param parent
	 *        The container in which to do the layout
	 * 
	 * @return The preferred dimensions to lay out the subcomponents of the
	 *         specified container
	 */
	public Dimension preferredLayoutSize(Container parent)
	{
		synchronized (parent.getTreeLock())
		{
			Insets insets = parent.getInsets();
			int ncomponents = parent.getComponentCount();
			int nrows = rows;
			int ncols = cols;

			if (nrows > 0)
			{
				ncols = (ncomponents + nrows - 1) / nrows;
			}
			else
			{
				nrows = (ncomponents + ncols - 1) / ncols;
			}

			int w = 0;
			int h = 0;

			// Calculate column widths
			int colWidths[] = getColWidths(ncols, nrows, parent);
			for (int i = 0; i < colWidths.length; i++)
				w += colWidths[i];

			// Calculate row heights
			int rowHeights[] = getRowHeights(ncols, nrows, parent);
			for (int i = 0; i < rowHeights.length; i++)
				h += rowHeights[i];

			return new Dimension(insets.left + insets.right + w + (ncols - 1) * hgap, insets.top
						+ insets.bottom + h + (nrows - 1) * vgap);
		}
	}


	/**
	 * Returns the heights of all rows.
	 * 
	 * @param ncols
	 *        Number of columns
	 * @param nrows
	 *        Number of rows
	 * @param parent
	 *        The parent container for which to calculate the row heights.
	 * 
	 * @return An array with the height of each row in the parent container
	 */
	private int[] getRowHeights(int ncols, int nrows, Container parent)
	{
		int result[] = new int[nrows];

		int ncomponents = parent.getComponentCount();

		// Calculate row heights
		for (int y = 0; y < nrows; y++)
		{
			int currHeight = 0;
			for (int x = 0; x < ncols; x++)
			{
				if (x + y * ncols < ncomponents)
				{
					Component c = parent.getComponent(x + y * ncols);
					int h = c.getPreferredSize().height;
					currHeight = Math.max(currHeight, h);
				}
			}

			result[y] = currHeight;
		}

		return result;
	}


	/**
	 * Returns the widths of all columns.
	 * 
	 * @param ncols
	 *        Number of columns
	 * @param nrows
	 *        Number of rows
	 * @param parent
	 *        The parent container for which to calculate the column widths.
	 * 
	 * @return An array with the width of each column in the parent container
	 */
	private int[] getColWidths(int ncols, int nrows, Container parent)
	{
		int result[] = new int[ncols];

		int ncomponents = parent.getComponentCount();

		// Calculate column widths
		for (int x = 0; x < ncols; x++)
		{
			int currWidth = 0;
			for (int y = 0; y < nrows; y++)
			{
				if (x + y * ncols < ncomponents)
					currWidth = Math.max(currWidth, parent.getComponent(x + y * ncols)
								.getPreferredSize().width);
			}

			result[x] = currWidth;
		}

		return result;
	}


	/**
	 * Returns the minimum size of the specified container, using this layout.
	 */
	public Dimension minimumLayoutSize(Container parent)
	{
		return preferredLayoutSize(parent);
	}


	/** Does a layout for the specified parent container */
	public void layoutContainer(Container parent)
	{
		synchronized (parent.getTreeLock())
		{
			Insets insets = parent.getInsets();
			int ncomponents = parent.getComponentCount();
			int nrows = rows;
			int ncols = cols;
			boolean ltr = parent.getComponentOrientation().isLeftToRight();

			if (ncomponents == 0)
			{
				return;
			}

			if (nrows > 0)
			{
				ncols = (ncomponents + nrows - 1) / nrows;
			}
			else
			{
				nrows = (ncomponents + ncols - 1) / ncols;
			}

			int colWidths[] = getColWidths(ncols, nrows, parent);
			int rowHeights[] = getRowHeights(ncols, nrows, parent);

			int w = parent.getWidth() - (insets.left + insets.right);
			int h = parent.getHeight() - (insets.top + insets.bottom);
			w = (w - (ncols - 1) * hgap) / ncols;
			h = (h - (nrows - 1) * vgap) / nrows;

			int xp = insets.left;
			for (int x = 0; x < ncols; x++)
			{
				int yp = insets.top;
				for (int y = 0; y < nrows; y++)
				{
					int index = x + y * ncols;
					if (index < ncomponents)
					{
						parent.getComponent(index).setBounds(xp, yp, colWidths[x], rowHeights[y]);
						yp += vgap + rowHeights[y];
					}
				}

				xp += hgap + colWidths[x];
			}
		}
	}


	/** Returns a String representation of this layout. */
	public String toString()
	{
		return getClass().getName() + "[hgap=" + hgap + ",vgap=" + vgap + ",rows=" + rows + ",cols="
					+ cols + "]";
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -