Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    live ListGrid and updating

    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:

    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();
    	}
    }
    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?
    Last edited by sunnyl; 3 Aug 2010, 15:29.
Working...
X