package
{
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.geom.Point;
import mx.collections.ArrayCollection;
import mx.collections.CursorBookmark;
import mx.controls.DataGrid;
import mx.controls.dataGridClasses.DataGridColumn;
import mx.controls.listClasses.IListItemRenderer;
import mx.core.mx_internal;
use namespace mx_internal;
/**
* A DataGrid subclass that has faster horizontal scrolling
*/
public class BetterDataGrid extends DataGrid
{
/**
* draw ground color for every row
*/
override protected function drawRowBackground(s:Sprite, rowIndex:int, y:Number, height:Number, color:uint, dataIndex:int):void
{
super.drawRowBackground(s, rowIndex, y, height, color, dataIndex);
}
public function BetterDataGrid()
{
super();
}
/**
* remember the number of columns in case it changes
*/
private var lastNumberOfColumns:int;
/**
* a flag as to whether we can use the optimized scrolling
*/
private var canUseScrollH:Boolean;
/**
* when the horizontal scrollbar is changed it will eventually set horizontalScrollPosition
* This value can be set programmatically as well.
*/
override public function set horizontalScrollPosition(value:Number):void
{
// remember the setting of this flag. We will tweak it in order to keep DataGrid from
// doing its default horizontal scroll which essentially refreshes every renderer
var lastItemsSizeChanged:Boolean=itemsSizeChanged;
// remember the current number of visible columns. This can get changed by DataGrid
// as it recomputes the visible columns when horizontally scrolled.
lastNumberOfColumns=visibleColumns.length;
// reset the flag for whether we use our new technique
canUseScrollH=false;
// call the base class. If we can use our technique we'll trip that flag
super.horizontalScrollPosition=value;
// if the flag got tripped run our new technique
if (canUseScrollH)
{
scrollLeftOrRight();
configureScrollBars();
}
// reset the flag
itemsSizeChanged=lastItemsSizeChanged;
}
// remember the parameters to scrollHorizontally to be used in our new technique
private var pos:int;
private var deltaPos:int;
private var scrollUp:Boolean;
public function get attrColumnIndex():int
{
return _attrColumnIndex;
}
public function set attrColumnIndex(o:int):void
{
_attrColumnIndex=o;
}
protected var _attrColumnIndex:int=0;
// override this method. If it gets called that means we can use the new technique
override protected function scrollHorizontally(pos:int, deltaPos:int, scrollUp:Boolean):void
{
// just remember the args for later;
this.pos=pos;
this.deltaPos=deltaPos;
this.scrollUp=scrollUp;
if (deltaPos < visibleColumns.length)
{
canUseScrollH=true;
// need this to prevent DG from asking for a full refresh
itemsSizeChanged=true;
}
}
/**
* The new technique does roughly what we do vertically. We shift the renderers on screen and in the
* listItems array and only make the new renderers.
* Because we can't get internal access to the header, we fully refresh it, but that's only one row
* of renderers. There's significant gains to be made by not fully refreshing the every row of columns
*
* Key thing to note here is that visibleColumns has been updated, but the renderer array has not
* That's why we don't do this in scrollHorizontally as the visibleColumns hasn't been updated yet
* But because of that, sometimes we have to measure old renderers, and sometimes we measure the columns
*/
private function scrollLeftOrRight():void
{
// trace("scrollHorizontally " + pos);
var i:int;
var j:int;
var numCols:int;
var uid:String;
var curX:Number;
var rowCount:int=rowInfo.length;
var columnCount:int=listItems[0].length;
var cursorPos:CursorBookmark;
var moveBlockDistance:Number=0;
var c:DataGridColumn;
var item:IListItemRenderer;
var itemSize:Point;
var data:Object;
var xx:Number;
var yy:Number;
if (scrollUp) // actually, rows move left
{
// determine how many columns we're discarding
var discardCols:int=deltaPos;
// measure how far we have to move by measuring the width of the columns we
// are discarding
moveBlockDistance=sumColumnWidths(discardCols, true);
// trace("moveBlockDistance = " + moveBlockDistance);
// shift rows leftward and toss the ones going away
for (i=0; i < rowCount; i++)
{
numCols=listItems[i].length;
if (numCols == 0) //empty row
{
continue;
}
// move the positions of the row, the item renderers for the row,
// and the indicators for the row
moveRowHorizontally(i, discardCols, -moveBlockDistance, numCols);
// move the renderers within the array of rows
shiftColumns(i, discardCols, numCols);
truncateRowArray(i);
}
// generate replacement columns
cursorPos=iterator.bookmark;
var firstNewColumn:int=lastNumberOfColumns - deltaPos;
curX=listItems[0][firstNewColumn - 1].x + listItems[0][firstNewColumn - 1].width;
for (i=0; i < rowCount; i++)
{
if (iterator == null || iterator.afterLast || !iteratorValid)
continue;
data=iterator.current;
iterator.moveNext();
uid=itemToUID(data);
xx=curX;
yy=rowInfo[i].y;
for (j=firstNewColumn; j < visibleColumns.length; j++)
{
c=visibleColumns[j];
item=setupColumnItemRenderer(c, listContent, i, j, data, uid);
//if(!item) return;
itemSize=layoutColumnItemRenderer(c, item, xx, yy);
xx+=itemSize.x;
}
// toss excess columns
while (listItems[i].length > visibleColumns.length)
{
addToFreeItemRenderers(listItems[i].pop());
}
}
iterator.seek(cursorPos, 0);
}
else
{
numCols=listItems[0].length;
if (deltaPos > visibleColumns.length)
deltaPos=visibleColumns.length;
moveBlockDistance=sumColumnWidths(deltaPos, false);
// shift the renderers and slots in array
for (i=0; i < rowCount; i++)
{
numCols=listItems[i].length;
if (numCols == 0)
continue;
moveRowHorizontally(i, 0, moveBlockDistance, numCols);
// we add placeholders at the front for new renderers
addColumnPlaceHolders(i, deltaPos);
}
cursorPos=iterator.bookmark;
for (i=0; i < rowCount; i++)
{
data=iterator.current;
iterator.moveNext();
uid=itemToUID(data);
xx=0;
yy=rowInfo[i].y;
for (j=0; j < deltaPos; j++)
{
c=visibleColumns[j];
item=setupColumnItemRenderer(c, listContent, i, j, data, uid);
itemSize=layoutColumnItemRenderer(c, item, xx, yy);
xx+=itemSize.x;
}
// toss excess columns
while (listItems[i].length > visibleColumns.length)
{
addToFreeItemRenderers(listItems[i].pop());
}
}
iterator.seek(cursorPos, 0);
}
// force update the header
header.headerItemsChanged=true;
header.visibleColumns=visibleColumns;
header.invalidateDisplayList();
header.validateNow();
// draw column lines and backgrounds
drawLinesAndColumnBackgrounds();
}
/* override protected function addToFreeItemRenderers(item:IListItemRenderer):void
{
if (item) super.addToFreeItemRenderers(item);
} */
// if moving left, add up old renderers
// if moving right, add up new columns
private function sumColumnWidths(num:int, left:Boolean):Number
{
var i:int;
var value:Number=0;
if (left)
{
for (i=0; i < num; i++)
{
value+=listItems[0][i].width;
}
}
else
for (i=0; i < num; i++)
{
value+=visibleColumns[i].width;
}
return value;
}
// shift position of renderers on screen
private function moveRowHorizontally(rowIndex:int, start:int, distance:Number, end:int):void
{
for (; start < end; start++)
if (listItems[rowIndex][start])
{
listItems[rowIndex][start].x+=distance;
}
}
// shift renderer assignments in listItems array
private function shiftColumns(rowIndex:int, shift:int, numCols:int):void
{
var item:IListItemRenderer;
var uid:String=itemToUID(listItems[rowIndex][0].data);
for (var i:int=0; i < shift; i++)
{
item=listItems[rowIndex].shift();
if (item)
{
addToFreeItemRenderers(item);
}
}
//rebuild the listContent.visibleData map entry
listContent.visibleData[uid]=listItems[rowIndex][0];
}
// add places in front of row for new columns
private function addColumnPlaceHolders(rowIndex:int, count:int):void
{
for (var i:int=0; i < count; i++)
{
listItems[rowIndex].unshift(null);
}
}
// remove excess columns
private function truncateRowArray(rowIndex:int):void
{
while (listItems[rowIndex].length > visibleColumns.length)
{
var item:IListItemRenderer;
{
item=listItems[rowIndex].pop();
addToFreeItemRenderers(item);
}
}
}
override protected function drawVerticalLine(s:Sprite, colIndex:int, color:uint, x:Number):void
{
if (!attrColumnIndex)
{
super.drawVerticalLine(s, colIndex, color, x);
return;
}
if (colIndex == attrColumnIndex - pos)
{
var colour:uint=0xFF0000;
super.drawVerticalLine(s, colIndex, colour, x);
return;
}
super.drawVerticalLine(s, colIndex, color, x);
}
}
}
分享到:
相关推荐
Flex是Adobe公司推出的一种基于ActionScript 3.0的开源框架,主要用于构建富互联网应用程序(Rich Internet Applications,简称RIA)。这种技术允许开发者创建具有高度交互性和动态视觉效果的Web应用,提供比传统...
Flex Flex Flex Flex Flex Flex Flex Flex Flex Flex Flex Flex Flex Flex Flex Flex Flex Flex Flex Flex Flex Flex Flex Flex Flex Flex Flex Flex Flex Flex Flex Flex Flex Flex Flex Flex Flex Flex Flex ...
本资料大全包含了多个重要的Flex学习资源,如Flex白皮书、Flex Cookbook以及Flex编程指南,这些都是深入理解Flex开发不可或缺的文献。 1. **Flex白皮书**: Flex白皮书是Adobe官方发布的技术文档,通常包含Flex...
Flex是Adobe公司推出的一种用于构建富互联网应用程序(RIA)的技术,它基于ActionScript编程语言和Flex框架,可以创建交互性强、用户体验优秀的Web应用。本教程是作者精心编写的Flex学习资料,适合初学者入门,通过...
Flex是Adobe公司开发的一种富互联网应用(Rich Internet Application,RIA)框架,主要用于构建运行在浏览器上的交互式应用程序。Flex以其强大的MXML和ActionScript编程语言,以及基于Flash Player或Adobe AIR运行时...
【标题】"记事万年历flex源码"所涉及的知识点主要集中在Adobe Flex技术和日历应用程序开发上。Flex是一种基于ActionScript 3.0的开源框架,用于构建富互联网应用(RIA)。它允许开发者使用MXML和ActionScript来创建...
Flex是由Adobe公司开发的一种开放源码的富互联网应用程序(RIA)框架,主要用于构建和部署跨平台、跨浏览器的互动用户界面。本教程基于Flex官方文档,旨在为开发者提供中文版的详细学习指南,帮助理解并掌握Flex的...
Flex是开源的、高度可移植的词法分析器生成器,专门用于创建处理文本输入流的解析器。这个“flex-2.6.0.tar.gz”文件是一个针对Flex 2.6.0版本的源码压缩包,适用于Unix/Linux类操作系统。在Linux环境中,我们通常会...
Flex是Adobe公司推出的一种用于构建富互联网应用(RIA, Rich Internet Applications)的开源框架,它主要基于ActionScript编程语言和MXML标记语言。这个“Flex实战项目”可能是一个使用Flex技术构建的实际应用示例,...
Flex API 是一种软件开发接口,主要用于构建富互联网应用程序(Rich Internet Applications,简称RIA),它由Adobe公司开发,用于提供强大的图形和交互性功能。在本文中,我们将深入探讨Flex API的核心概念、主要...
Flex是Adobe公司开发的一种开放源代码的富互联网应用程序(RIA)框架,主要用于构建具有动态图形、交互性丰富的Web应用。Flex应用程序通常使用ActionScript编程语言,并基于Flash Player或Adobe AIR运行时环境。Java...
Flex相册 Flex图片
### Flex3与Flex4对比分析 #### 一、概述 随着技术的发展,Adobe Flex平台也在不断进化以满足日益增长的应用需求。本文旨在详细介绍Flex3与Flex4之间的主要区别,特别是Flex4相较于Flex3的新功能与改进之处。通过...
Flex是开源的、高度可移植的词法分析器生成器,用于创建处理结构化文本或二进制文件的扫描器。这个"flex-2.6.4.tar.gz"文件是Flex 2.6.4版本的源代码压缩包,遵循GNU General Public License (GPL)发布。在Linux和类...
Flex是Adobe公司开发的一种用于创建富互联网应用程序(RIA)的开放源代码框架,它主要基于ActionScript编程语言和MXML标记语言。这个“Flex中文教程”显然是为了帮助初学者掌握Flex开发技术,通过配合使用Flex...
Flex布局是一种强大的CSS布局模式,它允许开发者在不考虑元素的具体尺寸的情况下,创建灵活且响应式的用户界面。这个“flex特效 不错的flex样式生成器”是一个工具,可以帮助开发者更轻松地生成适用于Flex布局的CSS...
标题和描述都聚焦于对比Flex3与Flex4之间的差异,这是一种Adobe系统提供的开源框架,用于构建跨平台的桌面和移动应用程序。Flex4,其代号为Gumbo,是在Flex3的基础上进行了重大升级,旨在改进用户体验和开发效率。...
在IT行业中,FLEX(Flexible Learning Environment eXtension)是一种基于Adobe Flash技术的开发框架,主要用于构建富互联网应用程序(RIA)。本篇文章将详细介绍FLEX的安装与配置过程,帮助初学者快速上手。 首先...
这个名为"flex帮助文档--(flex学习文档)"的压缩包文件包含了关于Flex的详细学习资料,尤其是针对初学者或者希望深入理解Flex的开发者。 1. **Flex的基本概念** Flex是一个基于MXML和ActionScript的开源框架,...
Flex框架是一种基于Adobe Flash Player和Adobe AIR运行时的开源应用程序框架,主要应用于创建富互联网应用程序(Rich Internet Applications,简称RIA)。在Java-FLEX的结合中,Flex提供了前端用户界面的构建能力,...