I've been working on getting the ListGrid to fulfill a particular scenario:
1) Behave as a "live" grid, possibly loading several thousand rows.
2) Update its cells/rows without completely refreshing via a timer every several seconds. In order to help performance it should only update the rows in the viewport.
The grid is backed by a GWT-RPC datasource (backed by hibernate+mssql) which observes the startRow/endRow requests of the grid. This works wonderfully and I've loaded up to 50,000 records before, so I can do #1 already.
#2 however I can only partially do. From what I've gathered there are two ways that the grid is being used:
1) It loads its data using the datasource and does its own thing caching using a ResultSet. Using a ResultSet will allow the grid to correctly fetch/not-fetch rows in/outside the current page.
2) I need to mess with the data returned in order to directly update the grid without refreshing it completely.
Here is my logic so far:
What I cannot figure out how to do it to add/remove rows from the ResultSet (addAt and removeAt methods cause "is not a function" errors) in the hopes of dynamically adding/removing rows without refreshing.
I've also tried another approach of working only with the grid.add/remove/update methods, but I was unable to have those methods add records in the grid in the correct sort order.
I'm also guessing dynamically adding/removing rows like this may cause issues with the ResultSet's cache (ie, the viewport gets refreshed with rows added/missing)
Is there another approach I can try?
1) Behave as a "live" grid, possibly loading several thousand rows.
2) Update its cells/rows without completely refreshing via a timer every several seconds. In order to help performance it should only update the rows in the viewport.
The grid is backed by a GWT-RPC datasource (backed by hibernate+mssql) which observes the startRow/endRow requests of the grid. This works wonderfully and I've loaded up to 50,000 records before, so I can do #1 already.
#2 however I can only partially do. From what I've gathered there are two ways that the grid is being used:
1) It loads its data using the datasource and does its own thing caching using a ResultSet. Using a ResultSet will allow the grid to correctly fetch/not-fetch rows in/outside the current page.
2) I need to mess with the data returned in order to directly update the grid without refreshing it completely.
Here is my logic so far:
Code:
private void refreshGrid(boolean forceRedraw) {
// ...create criteria
// force redraw will force the grid to completely reload
if (forceRedraw) {
grid.invalidateCache();
grid.fetchData(criteria, loadCallback);
} else {
// set the viewport for quick refreshing, returns -1 if no rows visible
int startRow = grid.getVisibleRows()[0];
int endRow = grid.getVisibleRows()[1];
if (startRow >= 0) {
reqProp.setStartRow(startRow);
reqProp.setEndRow(endRow);
} else {
reqProp.setStartRow(0);
reqProp.setEndRow(LiveGrid.DEFAULT_PAGE_SIZE);
}
System.out.println("quick refresh for "+startRow+"-"+endRow);
grid.getDataSource().fetchData(criteria, refreshCallback, reqProp);
}
}
private class LoadCallback implements DSCallback {
@Override
public void execute(DSResponse response, Object rawData, DSRequest request) {
for (int x=0; x<recordList.getLength(); x++)
recordList.removeAt(x);
recordList.addList(response.getData());
}
}
private class RefreshCallback implements DSCallback {
@Override
public void execute(DSResponse response, Object rawData, DSRequest request) {
Record[] newData = response.getData();
RecordList recordList = grid.getRecordList();
// populate from nothing to something
if (recordList.getLength() == 0 && newData.length != 0) {
// using an RS instead of the recordList will make the grid
// behave correctly wrt leaving space for rows that haven't
// been loaded yet
ResultSet rs = new ResultSet();
rs.setDataSource(StatusUpdateDS.getInstance());
rs.setInitialData(newData);
rs.setInitialLength(response.getTotalRows());
grid.setData(rs);
// populate from something to nothing
} else if (recordList.getLength() != 0 && newData.length == 0) {
grid.setData(new RecordList());
} else if (recordList.getLength() == 0 && newData.length == 0) {
// do nothing
} else {
// using this will cause the grid to completely refresh
// ResultSet rs = new ResultSet();
// rs.setDataSource(StatusUpdateDS.getInstance());
// rs.setInitialData(newData);
// rs.setInitialLength(response.getTotalRows());
// grid.setData(rs);
// the code below will update the rows to reflect the new data,
// however, I cannot find a way to add/remove new rows such that
// the new rows are in the correct order
RecordList rl = grid.getDataAsRecordList();
int viewStart = grid.getVisibleRows()[0];
int viewEnd = grid.getVisibleRows()[1];
Record[] visibleRecords = rl.getRange(viewStart, viewEnd);
System.out.println("there are "+visibleRecords.length+" visible records");
// more complex logic would go here to update the rows
for (Record record : visibleRecords) {
record.setAttribute(SomeField, "some new value");
}
// try removing existing rows, this fails
for (int x=0; x<10; x+=2) {
// grid.remove
// rl.removeAt(x);
}
}
grid.redraw();
}
}
I've also tried another approach of working only with the grid.add/remove/update methods, but I was unable to have those methods add records in the grid in the correct sort order.
I'm also guessing dynamically adding/removing rows like this may cause issues with the ResultSet's cache (ie, the viewport gets refreshed with rows added/missing)
Is there another approach I can try?