All Downloads are FREE. Search and download functionalities are using the official Maven repository.

mds.wave.RowColumnContainer Maven / Gradle / Ivy

There is a newer version: 7.139.60
Show newest version
package mds.wave;

import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.*;
import java.util.Vector;

import javax.swing.JComponent;

/**
 * RowColumnContainer object is a component that can contain other AWT
 * components in a grid disposition. This component create on the container a
 * RowColumnLayout manager, so no layout manager can be added to this component.
 *
 * @see RowColumnLayout
 */
public class RowColumnContainer extends JComponent
{
	class Btm extends Component
	{
		/**
		*
		*/
		private static final long serialVersionUID = 1L;

		Btm()
		{
			setBackground(Color.lightGray);
		}

		@Override
		public void paint(Graphics g)
		{
			final Rectangle d = getBounds();
			if (d.width > d.height)
				setCursor(new Cursor(Cursor.N_RESIZE_CURSOR));
			else
				setCursor(new Cursor(Cursor.W_RESIZE_CURSOR));
			g.draw3DRect(0, 0, d.width - 1, d.height - 1, true);
		}

		@Override
		public void print(Graphics g)
		{}

		@Override
		public void printAll(Graphics g)
		{}
	}
	/**
	 *
	 */
	private static final long serialVersionUID = 1L;
	/**
	 * RowColumnLayout
	 *
	 * @see RowColumnLayout
	 */
	protected RowColumnLayout row_col_layout;
	/**
	 * number of component in column
	 */
	protected int rows[] =
	{ 1, 0, 0, 0 };
	/**
	 * Normalize height of the components in column.
	 *
	 * @see RowColumnLayout
	 */
	protected float ph[];
	/**
	 * Normalized width of the columns.
	 *
	 * @see RowColumnLayout
	 */
	protected float pw[];
	private final Vector real_position = new Vector<>();
	private Point split_pos = null;

	private Component maximizeC = null;

	/**
	 * Constructs a new RowColumnContainer with one row an column.
	 */
	public RowColumnContainer()
	{
		setName("RowColumnContainer");
		row_col_layout = new RowColumnLayout(rows);
		setLayout(row_col_layout);
	}

	/**
	 * Constructs a new RowColumnContainer with a defined number of column and
	 * componet in column, and array of component to add.
	 *
	 * @param rows    an array of number of component in column
	 * @param columns number of columns
	 * @param c       an array of componet to add
	 */
	public RowColumnContainer(int rows[], Component c[])
	{
		int i;
		int num_component;
		setName("RowColumnContainer");
		if (rows == null || rows.length == 0)
			throw new IllegalArgumentException("Defined null or empty row column container");
		this.rows = new int[rows.length];
		for (i = 0; i < rows.length; i++)
			this.rows[i] = rows[i];
		row_col_layout = new RowColumnLayout(rows);
		setLayout(row_col_layout);
		num_component = getComponentNumber();
		Btm b;
		for (i = 0; i < num_component - 1; i++)
		{
			add(b = new Btm());
			setListener(b);
		}
		if (c != null)
		{
			if (num_component != c.length)
				throw new IllegalArgumentException("Invalid componet number");
			add(c);
			validate();
		}
	}

	/**
	 * Add componets to the container. The array componet length must be equals to
	 * the componet needed on the row column grid.
	 *
	 * @param c an array of component
	 */
	public void add(Component c[])
	{
		int i, j, k;
		if (c.length != getComponentNumber())
			throw new IllegalArgumentException("Invalid component number");
		for (i = 0, k = 0; i < rows.length; i++)
		{
			for (j = 0; j < rows[i]; j++)
			{
				super.add(c[k]);
				k++;
			}
		}
	}

	/**
	 * Adds a specific component in row column position, if row, col position
	 * position is not present in row column grid, the grid is modified to add new
	 * componet.
	 *
	 * @param c   the component to be added
	 * @param row component position in column
	 * @param col column position of the component
	 */
	public void add(Component c, int row, int col)
	{
		int new_rows[], cmp_idx = 0, i;
		Btm b;
		int rrow = row;
		final int rcol = col;
		if (getGridComponent(row, col) != null)
			throw new IllegalArgumentException("Component already added in this position");
		if (col > rows.length)
		{
			if (row != 1)
				rrow = 1;
			new_rows = new int[col];
			for (i = 0; i < rows.length; i++)
				new_rows[i] = rows[i];
			new_rows[col - 1] = 1;
			rows = new_rows;
			cmp_idx = -1;
		}
		else
		{
			rrow = rows[col - 1] + 1;
			cmp_idx = getComponentIndex(rrow - 1, col) + 1;
			for (i = 0; i < real_position.size(); i += 2)
			{
				final Point in_pos = real_position.elementAt(i);
				if (row < in_pos.y && col == in_pos.x)
				{
					cmp_idx--;
					rrow--;
				}
			}
			for (int j = 0; j < real_position.size(); j += 2)
			{
				final Point in_p = real_position.elementAt(j);
				if (row < in_p.y && col == in_p.x)
				{
					final Point real_p = real_position.elementAt(j + 1);
					real_p.y++;
					if (in_p.x == real_p.x && in_p.y == real_p.y)
					{
						real_position.removeElementAt(j);
						real_position.removeElementAt(j);
						j -= 2;
						continue;
					}
					if (rrow <= real_p.y && rcol == real_p.x)
					{
						real_position.setElementAt(new Point(real_p.x, real_p.y), j + 1);
					}
				}
			}
			rows[col - 1]++;
		}
		if (cmp_idx >= 0)
			super.add(c, cmp_idx);
		else
			super.add(c);
		super.add(b = new Btm(), 0);
		setListener(b);
		if (rrow != row || rcol != col)
			setRealPosition(new Point(col, row), new Point(rcol, rrow));
	}

	/**
	 * Get number of columns.
	 *
	 * @return number of columns
	 */
	public int getColumns()
	{
		int col = 0;
		for (int c = 0; c < rows.length; c++)
			if (rows[c] != 0)
				col++;
		return col;
	}

	/**
	 * Gets the index of the component in this container.
	 *
	 * @param c component
	 * @return index of the component in the container or -1 if not presentt
	 */
	public int getComponentIndex(Component c)
	{
		int idx;
		for (idx = 0; idx < getGridComponentCount() && getGridComponent(idx) != c; idx++);
		if (idx < getGridComponentCount())
			return idx + 1;
		else
			return -1;
	}

	/**
	 * Gets the (row, col) component index in this container.
	 *
	 * @param row component index in the column
	 * @param col column index of the component
	 * @return the index component in this container, -1 if the (row, col) value
	 *         does not exist. .
	 */
	public int getComponentIndex(int row, int col)
	{
		int cmp_idx = 0;
		if (col > rows.length || row > rows[col - 1])
			return -1;
		for (int i = 0; i < col - 1; i++)
			cmp_idx += rows[i];
		return (cmp_idx + row + getGridComponentCount() - 2);
	}

	/**
	 * Returns the number of componet to add to this container.
	 *
	 * @return number of componet to add to this container
	 */
	public int getComponentNumber()
	{
		int num = 0;
		for (int i = 0; i < rows.length && rows[i] != 0; i++)
			num += rows[i];
		return num;
	}

	/**
	 * Get (row , col) position of the component in the container
	 *
	 * @param c componet
	 * @return (row, col) position of the component or null if component not
	 *         presente in the container
	 */
	public Point getComponentPosition(Component c)
	{
		int col = 0, row = 0;
		if (c == null)
			return null;
		int idx = getComponentIndex(c);
		for (col = 0; col < rows.length; col++)
		{
			for (row = 0; row < rows[col] && idx != 0; row++)
				idx--;
			if (idx == 0)
				break;
		}
		final Point p = new Point(col + 1, row);
		return p;
	}

	/**
	 * Get defined number of component in column col.
	 *
	 * @param col number of column
	 * @return number of component in column ith.
	 */
	public int getComponentsInColumn(int col)
	{
		return rows[col];
	}

	/**
	 * Get defined number of component in columns
	 *
	 * @return an integer array ith element is number of component in columns ith
	 */
	public int[] getComponentsInColumns()
	{ return rows; }

	public int[] getComponetNumInColumns()
	{ return rows; }

	/**
	 * Gets the nth user added component in this container.
	 *
	 * @param n the index of the component to get.
	 * @return the nth component in this container.
	 * @exception ArrayIndexOutOfBoundsException if the nth value does
	 *                                           not exist. Need not be called from
	 *                                           AWT thread.
	 */
	/*
	 * Component cmp_xxx; int cmp_xxx_idx; public Component getGridComponent(int n)
	 * { cmp_xxx_idx = n; try { SwingUtilities.invokeAndWait(new Runnable() { public
	 * void run() { System.out.println(
	 * " get grid component e in dispatcher thread "+SwingUtilities.
	 * isEventDispatchThread()); cmp_xxx = getComponent(getGridComponentCount() - 1
	 * + cmp_xxx_idx); } }); } catch(InterruptedException e){}
	 * catch(InvocationTargetException e){} return cmp_xxx; }
	 */
	public Component getGridComponent(int n)
	{
		// System.out.println( " get grid component e in dispatcher thread
		// "+SwingUtilities.isEventDispatchThread());
		return getComponent(getGridComponentCount() - 1 + n);
	}

	/**
	 * Gets the (row, col) component in this container.
	 *
	 * @param row component index in the column
	 * @param col column index of the component
	 * @return the (row, col) component in this container, or null value if does not
	 *         exist.
	 */
	public Component getGridComponent(int row, int col)
	{
		int idx;
		Point curr_pos;
		final Point p = getRealPosition(curr_pos = new Point(col, row));
		if (p != null)
		{
			col = p.x;
			row = p.y;
		}
		else if (positionOverwrite(curr_pos))
			return null;
		idx = getComponentIndex(row, col);
		if (idx < 0)
			return null;
		return getComponent(idx);
	}

	/**
	 * Gets the number of components, added by user, in this panel.
	 *
	 * @return the number of components in this panel.
	 */
	public int getGridComponentCount()
	{
		// NOTE: return only the number of user added componet and not
		// internal resize button component.
		return (super.getComponentCount() + 1) / 2;
	}

	public Component getMaximizeComponent()
	{ return maximizeC; }

	public float[] getNormalizedHeight()
	{
		if (isMaximize())
			return ph;
		return row_col_layout.getPercentHeight();
	}

	public float[] getNormalizedWidth()
	{
		if (isMaximize())
			return ph;
		return row_col_layout.getPercentWidth();
	}

	private Point getRealPosition(Point in_pos)
	{
		for (int i = 0; i < real_position.size(); i += 2)
		{
			final Point p = real_position.elementAt(i);
			if (in_pos.x == p.x && in_pos.y == p.y)
				return real_position.elementAt(i + 1);
		}
		return null;
	}

	public Point getSplitPosition()
	{ return split_pos; }

	public boolean isMaximize()
	{ return (maximizeC != null); }

	public void maximizeComponent(Component c)
	{
		maximizeC = c;
		if (c == null)
		{
			update();
			return;
		}
		final int n_com = getGridComponentCount();
		if (n_com == 1)
			return;
		int i, j, k;
		final float m_ph[] = new float[n_com];
		final float m_pw[] = new float[rows.length];
		ph = new float[n_com];
		pw = new float[rows.length];
		final Point p = this.getComponentPosition(c);
		for (i = 0, k = 0; i < rows.length; i++)
		{
			if (rows[i] == 0)
				continue;
			pw[i] = row_col_layout.getPercentWidth(i);
			if (i == p.x - 1)
				m_pw[i] = 1;
			else
				m_pw[i] = 0;
			for (j = 0; j < rows[i]; j++)
			{
				if (i == p.x - 1 && j == p.y - 1)
					m_ph[k] = 1;
				else
					m_ph[k] = 0;
				ph[k] = row_col_layout.getPercentHeight(k);
				k++;
			}
		}
		row_col_layout.SetRowColumn(rows, m_ph, m_pw);
		invalidate();
		validate();
	}

	/*
	 *
	 * private void upadateRealPosition(Point p) { for(int j = 1; j <
	 * real_position.size(); j+=2) { Point real_pos =
	 * (Point)real_position.elementAt(j); if(rrow <= real_pos.y && rcol ==
	 * real_pos.x) { real_position.setElementAt(new Point(real_pos.x, real_pos.y++),
	 * j); } } }
	 */
	private boolean positionOverwrite(Point pos)
	{
		for (int i = 1; i < real_position.size(); i += 2)
		{
			final Point real_pos = real_position.elementAt(i);
			if (pos.x == real_pos.x && pos.y == real_pos.y)
			{
				// real_pos.y++;
				// Point in_pos = (Point)real_position.elementAt(i - 1);
				// if(in_pos.x == real_pos.x && in_pos.y == real_pos.y)
				// {
				// real_position.removeElementAt(i);
				// real_position.removeElementAt(i-1);
				// }
				return true;
			}
		}
		return false;
	}

	/**
	 * Removes the specified component from this container.
	 *
	 * @param c the component to be removed
	 */
	public void removeComponent(Component c)
	{
		if (c == null)
			return;
		final Point p = getComponentPosition(c);
		if (p == null)
			return;
		removeComponent(p.y, p.x);
	}

	/**
	 * Removes component in (row, col) position from this container.
	 *
	 * @param row component index in the column
	 * @param col column index of the component
	 */
	public void removeComponent(int row, int col)
	{
		final int idx = getComponentIndex(row, col);
		final int b_idx = idx - getGridComponentCount();
		// remove component
		remove(idx);
		// remove resize button
		if (b_idx >= 0)
			this.remove(b_idx);
		else
			this.remove(b_idx + 1);
		int size = real_position.size();
		for (int j = 0; j < size; j += 2)
		{
			final Point real_p = real_position.elementAt(j + 1);
			if (row == real_p.y && col == real_p.x)
			{
				real_position.removeElementAt(j);
				real_position.removeElementAt(j);
				break;
			}
		}
		size = real_position.size();
		boolean found;
		for (int i = row + 1; i <= rows[col - 1]; i++)
		{
			found = false;
			for (int j = 0; j < size; j += 2)
			{
				final Point real_p = real_position.elementAt(j + 1);
				if (i == real_p.y && col == real_p.x)
				{
					found = true;
					real_p.y--;
					real_position.setElementAt(new Point(real_p.x, real_p.y), j + 1);
					break;
				}
			}
			if (!found)
				setRealPosition(new Point(col, i + 1), new Point(col, i));
		}
		rows[col - 1]--;
		this.ph = this.pw = null;
		update();
	}

	/**
	 * Repaint all added component.
	 */
	public void repaintAll()
	{
		for (int i = 0; i < getGridComponentCount(); i++)
			getGridComponent(i).repaint();
	}

	public void resetMaximizeComponent()
	{
		maximizeC = null;
	}

	public void resetSplitPosition()
	{
		split_pos = null;
	}

	/**
	 * Enable event capability on resize button
	 *
	 * @param b a resize button
	 */
	private void setListener(Component b)
	{
		b.addMouseListener(new MouseAdapter()
		{
			@Override
			public void mouseClicked(MouseEvent e)
			{
				final Component ob = e.getComponent();
				if (ob instanceof Btm)
					if ((e.getModifiersEx() & InputEvent.BUTTON2_DOWN_MASK) == InputEvent.BUTTON2_DOWN_MASK)
						row_col_layout.ResizeRowColumn(ob);
			}

			@Override
			public void mouseReleased(MouseEvent e)
			{
				final Component ob = e.getComponent();
				if (ob instanceof Btm)
					if (!((e.getModifiersEx() & InputEvent.BUTTON2_DOWN_MASK) == InputEvent.BUTTON2_DOWN_MASK))
						row_col_layout.ResizeRowColumn(ob, e.getPoint().x, e.getPoint().y);
			}
		});
		b.addMouseMotionListener(new MouseMotionAdapter()
		{
			@Override
			public void mouseDragged(MouseEvent e)
			{
				final Component ob = e.getComponent();
				if (!((e.getModifiersEx() & InputEvent.BUTTON2_DOWN_MASK) == InputEvent.BUTTON2_DOWN_MASK))
					row_col_layout.DrawResize(ob, e.getPoint().x, e.getPoint().y);
			}
		});
	}

	private void setRealPosition(Point in_pos, Point real_pos)
	{
		if (in_pos == null || real_pos == null)
			return;
		if (in_pos.x != real_pos.x || in_pos.y != real_pos.y)
		{
			real_position.addElement(in_pos); // added position i
			real_position.addElement(real_pos); // real position i+1
		}
	}

	/**
	 * Set new grid configuration.
	 *
	 * @param rows an array of number of component in column
	 */
	public void setRowColumn(int rows[])
	{
		this.rows = rows;
		row_col_layout.SetRowColumn(rows);
	}

	/**
	 * Add component to the container. (row, col) position is automatic evaluated.
	 *
	 * @param c component to add
	 * @return index of the added component
	 */
	public int splitContainer(Component c)
	{
		int i, j, idx = 1, col = 0, row = 0;
		boolean not_add = true;
		for (j = rows.length; j <= rows.length * 4 && not_add; j++)
		{
			for (i = 0, idx = 0; i < rows.length; i++)
			{
				if (rows[i] < j && not_add)
				{
					row = rows[i] + 1;
					col = i + 1;
					not_add = false;
				}
				idx += rows[i];
			}
		}
		add(c, row, col);
		split_pos = new Point(col, row);
		update();
		return idx - 1;
	}

	/**
	 * Update RowColumnLayout.
	 *
	 * @see RowColumnLayout
	 */
	public void update()
	{
		row_col_layout.SetRowColumn(rows, ph, pw);
		invalidate();
		validate();
	}

	/**
	 * Update RowColumnLayout with defined row component height and column width.
	 *
	 * @param ph Vector of normalize height of component. The sum of ph[x] of the
	 *           objects in a column must be 1.
	 * @param pw Vector of normalize width of the culomn. The sum of pw[x] must be 1
	 *
	 * @see RowColumnLayout
	 */
	public void update(float ph[], float pw[])
	{
		this.ph = ph;
		this.pw = pw;
		update();
	}

	/**
	 * Update container with new vector of values of components in columns. Column
	 * number is equal to the number of the non zero element in array rows.
	 *
	 * @param rows an array of number of component in column
	 * @param c    an array of new componet to add
	 */
	public void update(int rows[], Component c[])
	{
		if (rows == null || rows.length == 0)
			throw new IllegalArgumentException("Defined null or empty row column container");
		final int curr_rows[] = this.rows;// row_col_layout.GetRows();
		int col;
		int idx_w = getGridComponentCount() - 1;
		Btm b;
		int idx = 0;
		if (curr_rows.length > rows.length)
			col = curr_rows.length;
		else
			col = rows.length;
		for (int i = 0; i < col; i++)
		{
			if (i > rows.length)
			{
				for (int k = 0; k < curr_rows[i]; k++)
				{
					remove(idx_w);
					remove(0);
					idx_w--;
				}
			}
			else
			{
				if (i > curr_rows.length - 1)
				{
					for (int k = 0; k < rows[i]; k++)
					{
						add(b = new Btm(), 0);
						setListener(b);
						add(c[idx++]);
					}
				}
				else
				{
					if (curr_rows[i] > rows[i])
					{
						idx_w += rows[i];
						for (int k = rows[i]; k < curr_rows[i]; k++)
						{
							if (idx_w > 0)
								remove(idx_w);
							remove(0);
							idx_w--;
						}
					}
					else
					{
						idx_w += curr_rows[i];
						for (int k = curr_rows[i]; k < rows[i]; k++)
						{
							add(c[idx++], idx_w);
							add(b = new Btm(), 0);
							setListener(b);
							idx_w++;
						}
					}
				}
			}
		}
		if (!rows.equals(this.rows))
		{
			this.rows = new int[rows.length];
			for (int i = 0; i < rows.length; i++)
				this.rows[i] = rows[i];
		}
		row_col_layout.SetRowColumn(rows);
		invalidate();
		validate();
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy