I\'m using GWT 2.1\'s CellBrowser with a custom TreeViewModel
. The TreeViewModel in turn uses an AsyncDataProvider
to fetch data dynamically. This all
It looks like a lot of people are having this same issue. Here's how I handled refreshing the data from an AsyncDataProvider.
First, create an interface that adds the ability to refresh data provider by wrapping the AsyncDataProvider's protected onRangeChanged method. For example...
HasRefresh.java
public interface HasRefresh<HasData<T>>{
/**
* Called when a display wants to refresh
*
* @param display the display to refresh
*/
void refresh(HasData<T> display);
}
Then the CellTable needing to be refreshed can then call into it through an Activity or however your controller logic is setup.
/**
* A custom {@link AsyncDataProvider}.
*/
public class MyAsyncDataProvider extends
AsyncDataProvider<Entity> implements HasRefresh<Entity> {
public void refresh(Entity display){
onRangeChanged(display);
}
/**
* {@link #onRangeChanged(HasData)} is called when the table requests a
* new range of data. You can push data back to the displays using
* {@link #updateRowData(int, List)}.
*/
@Override
protected void onRangeChanged(
HasData<Entity> display) {
currentRange = display.getVisibleRange();
final int start = currentRange.getStart();
dataServiceQuery = context.getEntities();
dataServiceQuery
.execute(new DataServiceQueryHandler<Entity>() {
@Override
public void onQueryResponse(
DataServiceQueryResponse<Entity> response) {
updateRowCount(response.getCount(), true);
updateRowData(start, response.getEntities());
}
});
}// end onRangeChanged()
}// end MyAsyncDataProvider class
I don't understand why affablebloke's answer is marked as "correct" and upvoted so much!?
Caffeine Coma asked about updating a Cell Browser and not a Cell Table, that are totally different things!
For me, the following trick worked:
I define the DataProvider
s outside of the TreeViewModel
and pass them as an argument to the constructor. In my case they provide empty data structures at the beginning.
Now you have a reference to the DataProvider
s from "outside" in order to update the Cell Browser.
Example:
private class MyTreeViewModel implements TreeViewModel {
AbstractDataProvider<MyDataStructure> myDataProvider;
public MyTreeViewModel(AbstractDataProvider<MyDataStructure> myDataProvider)
{
this.myDataProvider = myDataProvider;
}
@Override
public <T> NodeInfo<?> getNodeInfo(T value) {
if(value == null)
{
// Level 0
return new DefaultNodeInfo<MyDataStructure>(myDataProvider, new MyCellImpl());
}
}
}
AbstractDataProvider<MyDataStructure> myDataProvider = new ListDataProvider<MyDataStructure>(new ArrayList<MyDataStructure>()); // or AsyncDataProvider
MyTreeViewModel myModel = new MyTreeViewModel(myDataProvider);
CellBrowser<MyDataStructure> cellBrowser = new CellBrowser.Builder<MyDataStructure>(myModel, null).build();
/*
here you can do some stuff, for example, bind the CellBrowser to a template with UiBinder
*/
/*
if you use a ListDataProvider, do
*/
myDataProvider.setList(myDataStructureFromSomewhere);
myDataProvider.refresh();
/*
if you use an AsyncDataProvider, do
*/
myDataProvider.updateRowData(..., myDataStructureFromSomewhere);
myDataProvider.updateRowCount(...);
I had the same problem and this worked for me:
List<TreeGridRecord> dataToTable = ....
int firstPosition = this.pager.getDisplay().getVisibleRange().getStart();
this.dataProvider.updateRowData(firstPosition, dataToTable);
int rowCount = this.pager.getPageStart() + dataToTable.size();
this.dataProvider.updateRowCount(rowCount, exactCount);
Where the "pager" is a SimplePager to control the table pagination.
Hope this helps!
Found out now, the following code is basically the same but from the HasData interface instead of using AsyncDataProvider.
HasData<T> display;
...
display.setVisibleRangeAndClearData(display.getVisibleRange(), true);