如何使GWT Datagrid的第一列固定并水平和垂直滚动
目前,GWT DataGrid header在垂直滚动期间使用固定的标题行执行此操作。有没有一种方法可以在整个(第一)列上实现相同的功能?我已经实现了ScrolleGrid,它可以冻结DataGrid中的第一列。为了冻结第一列,您需要使用它而不是DataGrid如何使GWT Datagrid的第一列固定并水平和垂直滚动,gwt,datagrid,Gwt,Datagrid,目前,GWT DataGrid header在垂直滚动期间使用固定的标题行执行此操作。有没有一种方法可以在整个(第一)列上实现相同的功能?我已经实现了ScrolleGrid,它可以冻结DataGrid中的第一列。为了冻结第一列,您需要使用它而不是DataGrid import com.google.gwt.dom.client.*; import com.google.gwt.event.dom.client.ScrollEvent; import com.google.gwt.event.do
import com.google.gwt.dom.client.*;
import com.google.gwt.event.dom.client.ScrollEvent;
import com.google.gwt.event.dom.client.ScrollHandler;
import com.google.gwt.user.cellview.client.DataGrid;
import com.google.gwt.user.client.ui.HeaderPanel;
import com.google.gwt.user.client.ui.ScrollPanel;
/**
*
* @author Yuri Plaksyuk
*/
public class ScrolledGrid extends DataGrid {
private final Text cssText;
private boolean addedClass = false;
private int currentScrollLeft = 0;
public ScrolledGrid() {
cssText = Document.get().createTextNode("");
StyleElement styleElement = Document.get().createStyleElement();
styleElement.setType("text/css");
styleElement.appendChild(cssText);
HeaderPanel headerPanel = (HeaderPanel) getWidget();
headerPanel.getElement().insertFirst(styleElement);
final ScrollPanel scrollPanel = (ScrollPanel) headerPanel.getContentWidget();
scrollPanel.addScrollHandler(new ScrollHandler() {
@Override
public void onScroll(ScrollEvent event) {
int scrollLeft = scrollPanel.getHorizontalScrollPosition();
if (scrollLeft != currentScrollLeft) {
StringBuilder css = new StringBuilder();
if (scrollLeft > 0) {
css.append(".ScrolledGrid-frozen {");
css.append("background-color: inherit;");
css.append("}");
css.append(".ScrolledGrid-frozen div {");
css.append("position: absolute;");
css.append("left: ").append(scrollLeft).append("px;");
css.append("width: ").append(getColumnWidth(getColumn(0))).append(";");
css.append("padding-left: 1.3em;");
css.append("padding-right: 0.5em;");
css.append("margin-top: -0.7em;");
css.append("white-space: nowrap;");
css.append("background-color: inherit;");
css.append("}");
}
else
css.append(".ScrolledGrid-frozen { }");
css.append("th.ScrolledGrid-frozen { background-color: white; }");
cssText.setData(css.toString());
if (!addedClass) {
NodeList<TableRowElement> rows;
TableRowElement row;
TableCellElement cell;
rows = getTableHeadElement().getRows();
for (int i = 0; i < rows.getLength(); ++i) {
row = rows.getItem(i);
cell = row.getCells().getItem(0);
cell.setInnerHTML("<div>" + cell.getInnerHTML() + "</div>");
cell.addClassName("ScrolledGrid-frozen");
}
rows = getTableBodyElement().getRows();
for (int i = 0; i < rows.getLength(); ++i) {
row = rows.getItem(i);
cell = row.getCells().getItem(0);
cell.addClassName("ScrolledGrid-frozen");
}
addedClass = true;
}
currentScrollLeft = scrollLeft;
}
}
});
}
}
import com.google.gwt.dom.client.*;
导入com.google.gwt.event.dom.client.ScrollEvent;
导入com.google.gwt.event.dom.client.ScrollHandler;
导入com.google.gwt.user.cellview.client.DataGrid;
导入com.google.gwt.user.client.ui.HeaderPanel;
导入com.google.gwt.user.client.ui.ScrollPanel;
/**
*
*@作者Yuri Plaksyuk
*/
公共类ScrolleGrid扩展了DataGrid{
私人最终文本cssText;
私有布尔加法类=false;
private int currentScrollLeft=0;
公共ScrolleGrid(){
cssText=Document.get().createTextNode(“”);
StyleElement=Document.get().createStyleElement();
setType(“text/css”);
appendChild(cssText);
HeaderPanel HeaderPanel=(HeaderPanel)getWidget();
headerPanel.getElement().insertFirst(styleElement);
final ScrollPanel ScrollPanel=(ScrollPanel)headerPanel.getContentWidget();
addScrollHandler(新的ScrollHandler(){
@凌驾
public void onScroll(滚动事件){
int scrollLeft=scrollPanel.getHorizontalScrollPosition();
如果(scrollLeft!=当前scrollLeft){
StringBuilder css=新的StringBuilder();
如果(向左滚动>0){
追加(“.scrollegrid{”);
追加(“背景色:继承;”);
css.append(“}”);
追加(“.ScrolleGrid冻结div{”);
css.append(“位置:绝对;”);
css.append(“左:”).append(滚动左)。append(“px;”);
css.append(“宽度:”).append(getColumnWidth(getColumn(0))).append(;”);
追加(“左填充:1.3em;”);
追加(“右边填充:0.5em;”);
css.追加(“页边空白顶部:-0.7em;”;
追加(“空白:nowrap;”);
追加(“背景色:继承;”);
css.append(“}”);
}
其他的
追加(“.ScrolleGrid冻结{}”);
append(“th.scrollegrid-freezed{背景色:白色;}”);
cssText.setData(css.toString());
if(!addedClass){
节点列表行;
TableRowElement行;
表细胞;
rows=getTableHeadElement().getRows();
对于(int i=0;i
不幸的是,一些CSS值是硬编码的。我采用了Yuri的解决方案来实现以下目标:
- 不闪烁
- 处理任意行高度
- 适用于SelectionModel
- 更均匀的解
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.dom.client.*;
import com.google.gwt.event.dom.client.ScrollEvent;
import com.google.gwt.event.dom.client.ScrollHandler;
import com.google.gwt.user.cellview.client.DataGrid;
import com.google.gwt.user.cellview.client.DefaultCellTableBuilder;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.HeaderPanel;
import com.google.gwt.user.client.ui.ScrollPanel;
/**
* @author Daniel Lintner
*
* A DataGrid extension with the ability to display some row-level-information
* when scrolling left (horizontal), hence important columns out of sight of the user.
*/
public class FrozenDataGrid extends DataGrid
{
//textnode getting updated dynamically when scolling horizontally
private Text cssText;
//the latest scroll-position
private int currentScrollLeft = 0;
//an object extracting String-info from your rowdata
private FrozenValueProvider valueProvider;
//inject basic styling into the document - once
//this is how the frozen row-info looks like
static
{
Text baseCss = Document.get().createTextNode("");
StyleElement styleElement = Document.get().createStyleElement();
styleElement.setType("text/css");
styleElement.appendChild(baseCss);
StringBuilder css = new StringBuilder();
css.append(".ScrolledGrid-base {");
css.append("position: absolute;");
css.append("background-color: gray;");
css.append("padding: .3em;");
css.append("padding-left: .5em;");
css.append("padding-right: .5em;");
css.append("border-radius: 3px 3px;");
css.append("transition: opacity 500ms;");
css.append("color: white;");
css.append("margin-top: 2px;");
css.append("white-space: nowrap;");
css.append("}");
baseCss.setData(css.toString());
Document.get().getBody().insertFirst(styleElement);
}
public FrozenDataGrid()
{
super();
init();
}
public FrozenDataGrid(int pageSize, DataGrid.Resources resources)
{
super(pageSize, resources);
init();
}
public void init()
{
//create a css textnode
cssText = Document.get().createTextNode("");
//create dynamic css Style
StyleElement styleElement = Document.get().createStyleElement();
styleElement.setType("text/css");
styleElement.appendChild(cssText);
//append the initial style condition
//todo the name of this style might be built dynamically per instance - if multiple grid-instances exist/not the use-case by now
StringBuilder css = new StringBuilder();
css.append(".ScrolledGrid-frozen {");
css.append("opacity:0;");
css.append("}");
cssText.setData(css.toString());
//set a custom CellTableBuilder in order to inject the info-div to the row
setTableBuilder(new DefaultCellTableBuilder(this)
{
@Override
public void buildRowImpl(final Object rowValue, final int absRowIndex)
{
//do what DefaultCellTableBuilder does
super.buildRowImpl(rowValue, absRowIndex);
//only do something if there is a valueProvider
if(valueProvider != null) {
//we do this deferred because this row has to created first in order to access it
Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand()
{
@Override
public void execute()
{
createInfoDiv(getTableBodyElement().getRows().getItem(absRowIndex % getPageSize()), rowValue);
}
});
}
}
});
//fetch the ScrollPanel from the grid
HeaderPanel headerPanel = (HeaderPanel) getWidget();
headerPanel.getElement().insertFirst(styleElement);
final ScrollPanel scrollPanel = (ScrollPanel) headerPanel.getContentWidget();
//setup a timer handling the left-offset-css thing
//we use a timer to be able to cancel this operation -> e.g. continuous scroll
final Timer timer = new Timer(){
@Override
public void run() {
StringBuilder css = new StringBuilder();
//we need to left-offset the info-divs
if (scrollPanel.getHorizontalScrollPosition() > 100)
{
css.append(".ScrolledGrid-frozen {");
css.append("left: ").append(3 + scrollPanel.getHorizontalScrollPosition()).append("px;");
css.append("opacity: 1;");
css.append("}");
}
//we are close to the leftmost scroll position: info hidden
else
{
css.append(".ScrolledGrid-frozen {");
css.append("opacity:0;");
css.append("}");
}
cssText.setData(css.toString());
}
};
//track scrolling
scrollPanel.addScrollHandler(new ScrollHandler()
{
@Override
public void onScroll(ScrollEvent event)
{
//cancel previous actions to scroll events
if(timer.isRunning())
timer.cancel();
//actual horizontal scrollposition
int scrollLeft = scrollPanel.getHorizontalScrollPosition();
//a horizontal scroll takes places
if (scrollLeft != currentScrollLeft)
{
//first we hide the row-info
StringBuilder css = new StringBuilder();
css.append(".ScrolledGrid-frozen {");
css.append("opacity:0;");
css.append("}");
cssText.setData(css.toString());
//render left offset after a delay
timer.schedule(500);
//remember the current horizontal position
currentScrollLeft = scrollLeft;
}
}
});
}
private void createInfoDiv(TableRowElement row, Object value)
{
//create a div element and add value and style to it
DivElement div = Document.get().createDivElement();
div.setInnerText(valueProvider.getFrozenValue(value));
div.addClassName("ScrolledGrid-base");
div.addClassName("ScrolledGrid-frozen");
//we add it to the first child of the row, because added as child of the row directly
// confuses the CellTable with coordinating header positions
row.getFirstChildElement().insertFirst(div);
}
public void setFrozenValueProvider(FrozenValueProvider valueProvider) {
this.valueProvider = valueProvider;
}
public interface FrozenValueProvider<T>{
String getFrozenValue(T data);
}
}
import com.google.gwt.core.client.Scheduler;
导入com.google.gwt.dom.client.*;
导入com.google.gwt.event.dom.client.ScrollEvent;
导入com.google.gwt.event.dom.client.ScrollHandler;
导入com.google.gwt.user.cellview.client.DataGrid;
导入com.google.gwt.user.cellview.client.DefaultCellTableBuilder;
导入com.google.gwt.user.client.Timer;
导入com.google.gwt.user.client.ui.HeaderPanel;
导入com.google.gwt.user.client.ui.ScrollPanel;
/**
*@作者丹尼尔·林特纳
*
*一个DataGrid扩展,能够显示一些行级信息
*当向左(水平)滚动时,用户看不到重要列。
*/
公共类FrozenDataGrid扩展了DataGrid
{
//水平扫描时动态更新textnode
私有文本cssText;
//最新的滚动位置
private int currentScrollLeft=0;
//从行数据中提取字符串信息的对象
私人FrozenValueProvider valueProvider;
//将基本样式注入文档-一次
//这就是冻结行信息的外观
静止的
{
Text baseCss=Document.get().createTextNode(“”);
StyleElement=Document.get().createStyleElement();
setType(“text/css”);
appendChild(baseCss);
StringBuilder css=新的StringBuilder();
追加(“.ScrolleGrid基{”);
css.append(“位置:绝对;”);
追加(“背景色:灰色;”);
追加(“填充:.3em;”);
追加(“左填充:.5em;”;
追加(“填充右侧:.5em;”);
css.append(“边框半径:3px 3px;”);
css.append(“过渡:不透明度500ms;”);