Hi Janak
I have actually managed to create a GridLayoutManager, that will calculate
coordinates and return a GridBagConstraints.
You give the manager the number of columns that the grid has within the
constructor and then call the getConstraints for the items you wish to add to
the grid (in the correct order). The manager will calculate the next horizontal
and vertical position where the required item will fit.
I need to build it into my application, but my first tests worked well. Copy
the code below (the full class), and give it a test ;-)
Paul
import java.util.ArrayList;
import com.ulcjava.base.application.GridBagConstraints;
import com.ulcjava.base.application.util.Insets;
public class GridLayoutManager
{
private int _numCols;
private ArrayList<int[]> _rows;
private int _currRow = -1;
private int _currCol = 0;
public GridLayoutManager(int numCols)
{
_numCols = numCols;
_rows = new ArrayList<int[]>();
addNewRow(true);
}
public GridBagConstraints getConstraints(int colSpan, int rowSpan, boolean
expandHorizontally, boolean expandVertically)
{
return getConstraints(colSpan, rowSpan, expandHorizontally, expandVertically,
GridBagConstraints.NORTHWEST);
}
public GridBagConstraints getConstraints(int colSpan, int rowSpan, boolean
expandHorizontally, boolean expandVertically, int anchor)
{
// The component can only span to the maximum number of columns defined
// for its container
if (colSpan > _numCols)
{
colSpan = _numCols;
}
setStartingPos(colSpan);
growTableToFit(rowSpan);
markTable(colSpan, rowSpan);
int xpos = _currCol;
int ypos = _currRow+(rowSpan-1);
updateCurrentColumn(colSpan);
GridBagConstraints constraints = new GridBagConstraints();
// Create a constraints object to be used when adding items to the item
// pane. The insets are used to add a small invisible border around
// the item. This ensures that there is always a small gap between items
constraints.setInsets(new Insets(2, 2, 2, 2));
constraints.setAnchor(anchor);
constraints.setGridX(xpos);
constraints.setGridY(ypos);
constraints.setGridWidth(colSpan);
constraints.setGridHeight(rowSpan);
if (expandHorizontally && expandVertically)
{
constraints.setFill(GridBagConstraints.BOTH);
constraints.setWeightX(1.0);
constraints.setWeightY(1.0);
}
else if (expandHorizontally)
{
constraints.setFill(GridBagConstraints.HORIZONTAL);
constraints.setWeightX(1.0);
constraints.setWeightY(0.0);
}
else if (expandVertically)
{
constraints.setFill(GridBagConstraints.VERTICAL);
constraints.setWeightX(0.0);
constraints.setWeightY(1.0);
}
return constraints;
}
private void updateCurrentColumn(int colSpan)
{
if ((_currCol + colSpan) >= _numCols)
{
addNewRow(true);
}
else
{
_currCol += colSpan;
}
}
private void markTable(int colSpan, int rowSpan)
{
for (int row = 0; row < rowSpan; row++)
{
int[] rowData = _rows.get(_currRow+row);
for (int col = _currCol; col < _currCol+colSpan; col++)
{
rowData[col] = 1;
}
}
}
private void growTableToFit(int rowSpan)
{
int rowsToAdd = rowSpan - (_rows.size() - _currRow);
if (rowsToAdd > 0)
{
addRows(rowsToAdd);
}
}
private void setStartingPos(int colSpan)
{
// Set the column counter to the next free column
getNextFreeSpace();
if (!hasRoom(colSpan))
{
incrementCurrCol();
setStartingPos(colSpan);
}
}
private void incrementCurrCol()
{
if (_currCol + 1 == _numCols)
{
// I am on the last cell, so create a new record. This will also set
// the current column to 0
addNewRow(true);
}
else
{
_currCol++;
}
}
private boolean hasRoom(int colSpan)
{
int spaceCounter = 0;
int[] row = _rows.get(_currRow);
for (int i = _currCol; i < _numCols; i++)
{
if (row[i] == 0)
{
spaceCounter++;
if (spaceCounter == colSpan)
{
return true;
}
}
else if (row[i] == 1)
{
return false;
}
}
return false;
}
private void getNextFreeSpace()
{
int[] row = _rows.get(_currRow);
// First check if the current cell is free
if (row[_currCol] == 0)
{
return;
}
// Now find the next free cell
for (int i = _currCol; i < _numCols; i++)
{
if (row[i] == 0)
{
_currCol = i;
return;
}
}
// If I get this far, then the whole row has been set, so create a new
// row and check that one
addNewRow(true);
getNextFreeSpace();
}
private void addRows(int numRowsToAdd)
{
if (numRowsToAdd == 0)
{
return;
}
for (int i = 0; i < numRowsToAdd; i++)
{
addNewRow(false);
}
}
private void addNewRow(boolean incrementRowcounter)
{
int[] cols = new int[_numCols];
// Initialise the new row with 0, meaning that the space is not taken
for (int i = 0; i < _numCols; i++)
{
cols[i] = 0;
}
_rows.add(cols);
if (incrementRowcounter)
{
_currCol = 0;
_currRow++;
}
}
}
________________________________
Von: [EMAIL PROTECTED] im Auftrag von Janak Mulani
Gesendet: Mo 28.07.2008 17:55
An: [email protected]
Betreff: RE: [ULC-developer] ULCBoxLayout
Hi Paul,
ULCBoxPane is a simpler version of ULCGridBagLayoutPane.
The components are added from left to right.
If number of columns for the boxpane are not specied then all components
are laid out in one row.
If the number of columns for the boxpane are specified then the row and
column of the next component to be added are determined by division (row
= fColumns != 0 ? fNextIndex / fColumns : 0) and mod (column = fColumns !=
0 ? fNextIndex % fColumns : fNextIndex) operation respectively on the
specified column by the index of the next cell. If horizontal span is
specified then the next index is incremented by that many cells.
verticalSpan cannot be specified for the add operation because it will
make the computation of next available cell difficult.
>Is there an easy way of implementing this? How can I give a component a
certain row span?
You can use set() method to specify vertical and horizontal spans and use
the above formulae to calculate row and column indices. However, since you
will be specifying the spans, you will know which cells will be occupied
and thus adjust the next cell co-ordinates to avoid overlaps.
Thanks and regards,
Janak
-----------------------------------------
Janak Mulani
email: [EMAIL PROTECTED]
url: http://www.canoo.com <http://www.canoo.com/>
Beyond AJAX - Java Rich Internet Applications
http://www.canoo.com/ulc
-----------------------------------------
________________________________
From: [EMAIL PROTECTED]
[mailto:[EMAIL PROTECTED] On Behalf Of Paul Harrison
Sent: Wednesday, July 23, 2008 2:32 AM
To: [email protected]
Subject: [ULC-developer] ULCBoxLayout
Hi All
I have been developing a dynamic GUI where I only know the layout
of the items at run time. Up until now I have been using the GridBagLayout
and getting my users (other developers) to specify X and Y coordinates,
horizontal and vertical spanning, weights etc. I have had to move from the
GridBagLayout to specifying a Grid for the layout of the items. SWT
implements a GridData where items will be added to a grid without
specifying x or y coordinates, and it allows the addition of spanning
parameter.
I have been checking out the ULCBoxPane and it should allow me to
do exactly what I want, but the add(.) method only allows me to add a
horizontal span. I need to be able to add an item to the layout giving its
column & row span, their weights and the item.
Is there an easy way of implementing this? How can I give a
component a certain row span?
Paul Harrison
_______________________________________________
ULC-developer mailing list
[email protected]
http://lists.canoo.com/mailman/listinfo/ulc-developer