package org.basex.gui.layout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.LayoutManager;
/**
* This LayoutManager is similar to the GridLayout. The added components
* keep their minimum size even when the parent container is resized.
*
* @author BaseX Team 2005-12, BSD License
* @author Christian Gruen
*/
public final class TableLayout implements LayoutManager {
/** Number of columns. */
private final int cols;
/** Number of rows. */
private final int rows;
/** Horizontal inset. */
private final int insetX;
/** Vertical inset. */
private final int insetY;
/** Panel width. */
private int width;
/** Panel height. */
private int height;
/** Horizontal position. */
private final int[] posX;
/** Vertical position. */
private final int[] posY;
/**
* Creates a grid layout with the specified number of rows and columns.
* When displayed, the grid has the minimum size.
* @param r number of rows
* @param c number of columns
*/
public TableLayout(final int r, final int c) {
this(r, c, 0, 0);
}
/**
* Creates a grid layout with the specified number of rows and columns.
* When displayed, the grid has the minimum size.
* @param r number of rows
* @param c number of columns
* @param ix horizontal inset size
* @param iy vertical inset size
*/
public TableLayout(final int r, final int c, final int ix, final int iy) {
rows = r;
cols = c;
insetX = ix;
insetY = iy;
posX = new int[c];
posY = new int[r];
}
@Override
public void addLayoutComponent(final String name, final Component comp) { }
@Override
public void removeLayoutComponent(final Component comp) { }
@Override
public Dimension preferredLayoutSize(final Container parent) {
synchronized(parent.getTreeLock()) {
final Insets in = parent.getInsets();
final int nr = parent.getComponentCount();
int maxW = 0;
int maxH = 0;
for(int i = 0; i < cols; ++i) {
posX[i] = maxW;
final int w = maxW;
int h = 0;
for(int j = 0; j < rows; ++j) {
final int n = j * cols + i;
if(n >= nr) break;
final Component c = parent.getComponent(n);
final Dimension d = c.getPreferredSize();
if(maxW < w + d.width) maxW = w + d.width;
if(posY[j] < h) posY[j] = h;
else h = posY[j];
h += d.height;
}
if(maxH < h) maxH = h;
}
width = in.left + maxW + (cols - 1) * insetX + in.right;
height = in.top + maxH + (rows - 1) * insetY + in.bottom;
return new Dimension(width, height);
}
}
@Override
public Dimension minimumLayoutSize(final Container parent) {
return preferredLayoutSize(parent);
}
@Override
public void layoutContainer(final Container p) {
preferredLayoutSize(p);
synchronized(p.getTreeLock()) {
final Insets in = p.getInsets();
final int nr = p.getComponentCount();
for(int j = 0; j < rows; ++j) {
for(int i = 0; i < cols; ++i) {
final int n = j * cols + i;
if(n >= nr) return;
final Dimension cs = p.getComponent(n).getPreferredSize();
final int x = in.left + posX[i] + i * insetX;
final int y = in.top + posY[j] + j * insetY;
final int w = cs.width > 0 ? cs.width : width - in.left - in.right;
final int h = cs.height > 0 ? cs.height : height - in.top - in.bottom;
p.getComponent(n).setBounds(x, y, w, h);
}
}
}
}
}