mds.wave.RowColumnContainer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jscope Show documentation
Show all versions of jscope Show documentation
MDSplus data display program for waveforms, images and more.
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();
}
}