Hey guys,
I guess there is a bug in Flex code. When setting the
DataGridColumn.width property programmatically the setter method of
DataGridColumn.width calls the resizeColumn method of DataGrid.
public function set width(value:Number):void
{
// remove any queued equal spacing commands
explicitWidth = value;
// use this value for future measurements
preferredWidth = value;
if (owner != null)
{
// if we aren't resizing as part of grid layout, resize it's
column
var oldVal:Boolean = resizable;
// anchor this column to not accept any overflow width for
accurate sizing
resizable = false;
owner.resizeColumn(colNum, value);
resizable = oldVal;
}
else
{
// otherwise, just store the size
_width = value;
}
dispatchEvent(new Event("widthChanged"));
}
In this method the colNum is used as index for the visibleFields, which
contain the fields that are visible at the moment on the screen. So I
get a nullpointer exception when setting for example the width of the
5th column, when only 4 columns are shown in the grid because
Scrollpolicy is "auto" and all columns don't fit on one screen.
/**
* @private
* If there is no horizontal scroll bar, changes the display width
of other columns when
* one column's width is changed.
* @param col column whose width is changed
* @param w width of column
*/
mx_internal function resizeColumn(col:int, w:Number):void
{
// there's a window of time before we calccolumnsizes
// that someone can set width in AS
if (!visibleColumns || visibleColumns.length == 0)
{
columns[col].setWidth(w);
return;
}
if (w < visibleColumns[col].minWidth)
w = visibleColumns[col].minWidth;
// hScrollBar is present
if (_horizontalScrollPolicy == ScrollPolicy.ON ||
_horizontalScrollPolicy == ScrollPolicy.AUTO)
{
// adjust the column's width
visibleColumns[col].setWidth(w);
visibleColumns[col].explicitWidth = w;
columnsInvalid = true;
}
else
{
// we want all cols's new widths to the right of this to be
in proportion
// to what they were before the stretch.
// get the original space to the right not taken up by the
column
var totalSpace:Number = 0;
var n:int = visibleColumns.length;
var lastColumn:DataGridColumn;
var i:int;
var newWidth:Number;
//non-resizable columns don't count though
for (i = col + 1; i < n; i++)
{
if (visibleColumns[i].resizable)
totalSpace += visibleColumns[i].width;
}
var newTotalSpace:Number = visibleColumns[col].width - w +
totalSpace;
if (totalSpace)
{
visibleColumns[col].setWidth(w);
visibleColumns[col].explicitWidth = w;
}
var totX:Number = 0;
// resize the columns to the right proportionally to what
they were
for (i = col + 1; i < n; i++)
{
if (visibleColumns[i].resizable)
{
newWidth = Math.floor(visibleColumns[i].width
* newTotalSpace /
totalSpace);
if (newWidth < visibleColumns[i].minWidth)
newWidth = visibleColumns[i].minWidth;
visibleColumns[i].setWidth(newWidth);
totX += visibleColumns[i].width;
lastColumn = visibleColumns[i];
}
}
if (totX > newTotalSpace)
{
// if excess then should be taken out only from changing
column
// cause others would have already gone to their minimum
newWidth = visibleColumns[col].width - totX +
newTotalSpace;
if (newWidth < visibleColumns[col].minWidth)
newWidth = visibleColumns[col].minWidth;
visibleColumns[col].setWidth(newWidth);
}
else if (lastColumn)
{
// if less then should be added in last column
// dont need to check for minWidth as we are adding
lastColumn.setWidth(lastColumn.width - totX +
newTotalSpace);
}
}
itemsSizeChanged = true
invalidateDisplayList();
}
I use this to automatically set the width of the columns to fit their
entries. Does anyone else have the same problem? Is there a known
workaround for this problem?
Thanks,
Mane