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?