use like: * new TableLayout(cols) * add(comp, new TableOption(..)) * .. *
*/ public class TableLayout implements LayoutManager,LayoutManager2 { private Hashtable options = new Hashtable(); private TableOption defaultOption; private int nrows=0, ncols=0; private int ncomponents=0; private Component[][] components=null; private int MinWidth=0, MinHeight=0, PrefWidth=0, PrefHeight=0; private int[] minWidth=null, minHeight=null, prefWidth=null, prefHeight=null; private int[] weight=null, columnWidth=null; private int hgap=0, vgap=0; /** * Construct a new table layout manager. * @param cols Number of columns, used when adding components to tell when to go to the next row * @param defaultAlignment Default defaultAlignment for cells if not specified at the time of adding the component * @param hgap Horizontal gap between cells and at edge (in pixels) * @param vgap Vertical gap between cells and at edge (in pixels) **/ public TableLayout(int cols, String defaultAlignment, int hgap, int vgap) { this(cols, new TableOption(defaultAlignment),hgap,vgap); } public TableLayout(int cols, TableOption defaultAlignment, int hgap, int vgap) { this.ncols = cols; // the number of columns is specified this.nrows = 0; // the number of rows is calculated this.components = new Component[cols][]; this.defaultOption=defaultAlignment; this.hgap = hgap; this.vgap = vgap; } public TableLayout(int cols, String alignment) { this(cols, alignment, 0, 0); } public TableLayout(int cols) { this(cols, "", 0, 0); } public void addLayoutComponent(String alignment, Component comp) { options.put(comp, new TableOption(alignment)); } public void removeLayoutComponent(Component comp) { options.remove(comp); } // Iterate through the components, counting the number of rows taking into account // row and column spanning, then initialise the components[c][r] matrix so that // we can retrieve the component at a particular row,column position. private void loadComponents(Container parent) { ncomponents = parent.getComponentCount(); // If we haven't allocated the right sized array for each column yet, do so now. // Note that the number of columns is fixed, but the number of rows is not know // and could in the worst case be up the number of components. Unfortunately this // means we need to allocate quite big arrays, but the alternative would require // complex multiple passes as we try to work out the effect of row spanning. if (components[0] == null || components[0].length < ncomponents) { for (int i=0; i
* @return the value 0.5f
to indicate centered
*/
public float getLayoutAlignmentX(Container parent) {
return 0.5f;
}
/**
* Returns the alignment along the y axis. This specifies how
* the component would like to be aligned relative to other
* components. The value should be a number between 0 and 1
* where 0 represents alignment along the origin, 1 is aligned
* the furthest away from the origin, 0.5 is centered, etc.
*
* @return the value 0.5f
to indicate centered
*/
public float getLayoutAlignmentY(Container parent) {
return 0.5f;
}
/**
* Invalidates the layout, indicating that if the layout manager
* has cached information it should be discarded.
*/
public void invalidateLayout(Container target) {
}
/**
* Returns the maximum dimensions for this layout given the components
* in the specified target container.
* @param target the container which needs to be laid out
* @see Container
* @see #minimumLayoutSize(Container)
* @see #preferredLayoutSize(Container)
* @return the maximum dimensions for this layout
*/
public Dimension maximumLayoutSize(Container target) {
return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
}
}
class TableOption{
public static final int CENTRE=1, FILL=2, LEFT=3, RIGHT=4, TOP=5, BOTTOM=6;
int horizontal = CENTRE;
int vertical = CENTRE;
int rowSpan=1, colSpan=1, skipColumns=0, forceColumn=-1, weight=-2;
/**
*
* @param horizontal one of CENTRE,FILL,LEFT,RIGHT,TOP,BOTTOM
* @param vertical
*/
public TableOption(int horizontal, int vertical) {
this.horizontal = horizontal;
this.vertical = vertical;
}
public TableOption(int horizontal, int vertical, int rowSpan, int colSpan) {
this.horizontal = horizontal;
this.vertical = vertical;
this.rowSpan = rowSpan;
this.colSpan = colSpan;
}
public TableOption(int horizontal, int vertical, int rowSpan, int colSpan, int skipColumns, int forceColumn, int weight) {
this.horizontal = horizontal;
this.vertical = vertical;
this.rowSpan = rowSpan;
this.colSpan = colSpan;
this.skipColumns = skipColumns;
this.forceColumn = forceColumn;
this.weight = weight;
}
TableOption(String alignment) {
StringTokenizer tk = new StringTokenizer(alignment, ",");
while (tk.hasMoreTokens())
{
String token = tk.nextToken();
boolean ok = false;
int delim = token.indexOf("=");
if (token.equals("NW") || token.equals("W") || token.equals("SW"))
{ horizontal = LEFT; ok=true; }
if (token.equals("NE") || token.equals("E") || token.equals("SE"))
{ horizontal = RIGHT; ok=true; }
if (token.equals("N") || token.equals("C") || token.equals("F"))
{ horizontal = CENTRE; ok=true; }
if (token.equals("F") || token.equals("FH"))
{ horizontal = FILL; ok=true; }
if (token.equals("N") || token.equals("NW") || token.equals("NE"))
{ vertical = TOP; ok=true; }
if (token.equals("S") || token.equals("SW") || token.equals("SE"))
{ vertical = BOTTOM; ok=true; }
if (token.equals("W") || token.equals("C") || token.equals("E"))
{ vertical = CENTRE; ok=true; }
if (token.equals("F") || token.equals("FV"))
{ vertical = FILL; ok=true; }
if (delim>0)
{
int val = Integer.parseInt(token.substring(delim+1));
token = token.substring(0,delim);
if (token.equals("CS") && val>0)
{ colSpan = val; ok=true; }
else if (token.equals("RS") && val>0)
{ rowSpan = val; ok=true; }
else if (token.equals("SKIP") && val>0)
{ skipColumns = val; ok=true; }
else if (token.equals("COL"))
{ forceColumn = val; ok=true; }
else if (token.equals("WT"))
{ weight = val; ok=true; }
}
if (!ok) throw new IllegalArgumentException("TableOption "+token);
}
}
}