Carissimi del forum, per motivi di lavoro sto operando con Google Web Toolkit per creare un'agenda telefonica virtuale tramite l'oggetto Store. Il codice che allego estrae i contatti da mySQL e li salva in un oggetto di tipo List<ContattoModel>. Ho messo un checkbox per selezione contatti, paginazione e filtri. Il grouping, però, non mi funziona: dove sbaglio?

P.S. gli "import" non li ho messi per motivi di spazio

codice:
public class ContattiGrid extends ContentPanel {

    // toolbar
    private ToolBar toolbarFiltro = new ToolBar();
    private final SimpleComboBox<String> filterUsing = new SimpleComboBox<String>();
    private Label selezionatiLabel = new Label("Selezionati: 0");
    // paging
    private PagingToolBar toolbar = new PagingToolBar(50);
    private final Boolean isCached;
    private final Boolean showToolBar;
    private final Boolean showRowNumberer;
    private final Boolean showCheckBoxSelection;
    private final Boolean collapsible;
    private CheckBox pagingCheck = new CheckBox();
    private final BaseFilterPagingLoadConfig pagingConfig = new BaseFilterPagingLoadConfig();
    //filter
    private String text = null;
    private String name_property_to_filter = "nome";
    // grid    
    private Grid<ContattoModel> grid = null;
    private boolean beforeRender = true;

    // remote service proxy per gestione della chiamata asincrona
    private final ServiceAsync serviceAsyncCallback = GWT.create(Service.class);

    public ContattiGrid() {
        super();
        this.isCached = false;
        this.showToolBar = true;
        this.showRowNumberer = false;
        this.showCheckBoxSelection = true;
        this.collapsible = true;
        this.pagingConfig.setOffset(0);
        this.pagingConfig.setLimit(50);
        setCollapsible(collapsible);
        setLayout(new FitLayout());
        setIcon(Resources.ICONS.contatti());
        setHeading("Elenco Contatti");
        setSize(200, 300);
        renderGrid(beforeRender, "azienda");
    }

    private void renderGrid(Boolean beforeRender, String groupBy) {
        //proxy
        final RpcProxy<PagingLoadResult<ContattoModel>> proxy = new RpcProxy<PagingLoadResult<ContattoModel>>() {
            @Override
            protected void load(Object loadConfig, AsyncCallback<PagingLoadResult<ContattoModel>> callback) {
                serviceAsyncCallback.getContattiPaging((FilterPagingLoadConfig) loadConfig, text, name_property_to_filter, callback);
            }
        };        
        //loader
        final BasePagingLoader<PagingLoadResult<ContattoModel>> loader = new BasePagingLoader<PagingLoadResult<ContattoModel>>(proxy) {
            @Override
            protected Object newLoadConfig() {
                BasePagingLoadConfig config = new BaseFilterPagingLoadConfig();
                return config;
            }
        };
        loader.setRemoteSort(true);
        ListStore<ContattoModel> store = null;
        if ( groupBy!=null ) {
            GroupingStore<ContattoModel> groupingStore = new GroupingStore<ContattoModel>(loader);
            groupingStore.groupBy(groupBy);
            groupingStore.setGroupOnSort(true);
            groupingStore.setRemoteGroup(true);
            store = groupingStore;
        } else {
            store = new ListStore<ContattoModel>(loader);
        }        
        //grid
        List<ColumnConfig> configs = new ArrayList<ColumnConfig>();
        PagingRowNumbered numberer = null;
        if (showRowNumberer) {
            numberer = new PagingRowNumbered(25);
            numberer.setHeader("Lp");
            configs.add(numberer);
        }
        final CheckBoxSelectionModel<ContattoModel> checkBoxSelection = new CheckBoxSelectionModel<ContattoModel>();
        if (showCheckBoxSelection) {            
            //checkBoxSelection.setSelectionMode(SelectionMode.MULTI);//SIMPLE
            configs.add(checkBoxSelection.getColumn());
        }
        ColumnConfig column = new ColumnConfig();
        column = new ColumnConfig("cognome", "Cognome", 150);
        column.setAlignment(HorizontalAlignment.LEFT);
        configs.add(column);
        column = new ColumnConfig("nome", "Nome", 150);
        column.setAlignment(HorizontalAlignment.LEFT);
        configs.add(column);
        column = new ColumnConfig("azienda", "Azienda", 150);
        column.setAlignment(HorizontalAlignment.LEFT);
        configs.add(column);
        ColumnModel columnsModel = new ColumnModel(configs);
        grid = new Grid<ContattoModel>(store, columnsModel);
        grid.setStateId("pagingGridContatti");
        grid.setStateful(true);
        if (groupBy != null) {
            grid.setView(createGroupingView(columnsModel));
        }
        if (showCheckBoxSelection) {
            grid.setSelectionModel(checkBoxSelection);
        }
        if (showCheckBoxSelection && beforeRender) {
            grid.addPlugin(checkBoxSelection);
        }
        grid.addListener(Events.Attach, new Listener<GridEvent<ContattoModel>>() {
            public void handleEvent(GridEvent<ContattoModel> be) {
                Map<String, Object> state = grid.getState();
                if (state.containsKey("offset")) {
                    int offset = (Integer) state.get("offset");
                    int limit = (Integer) state.get("limit");
                    pagingConfig.setOffset(offset);
                    pagingConfig.setLimit(limit);
                }
                if (state.containsKey("sortField")) {
                    pagingConfig.setSortField((String) state.get("sortField"));
                    pagingConfig.setSortDir(SortDir.valueOf((String) state.get("sortDir")));
                }
                loader.load(pagingConfig);
            }
        });
        grid.getSelectionModel().addSelectionChangedListener(new SelectionChangedListener<ContattoModel>() {
            @Override
            public void selectionChanged(SelectionChangedEvent<ContattoModel> se) {
                selezionatiLabel.setText("Selezionati: "+se.getSelection().size());
            }
        });
        grid.setColumnLines(true);
        grid.setLoadMask(true);
        // grid.setStripeRows(true);
        grid.getView().setEmptyText("Contatti...");
        // aggiunge grid al panel
        add(grid);
        // aggiunge filtro
        addFilter(store);
        // aggiunge toolbar paging
        addToolbar(beforeRender, loader);
    }

    private void addFilter(ListStore<ContattoModel> store) {
        final RemoteStoreFilterField<ContattoModel> filterField = new RemoteStoreFilterField<ContattoModel>() {
            @Override
            protected void handleOnFilter(String filter) {
                if (filter == null || filter.equals(""))
                    text = null;
                else
                    text = filter.toLowerCase();
                if(filterUsing.getSelectedIndex()>-1) {
                    name_property_to_filter = filterUsing.getSimpleValue();
                }                
                // Call to the RPC
                grid.getStore().getLoader().load(); // loader.load();
            }
            @Override
            protected boolean doSelect(Store<ContattoModel> store, ContattoModel parent, ContattoModel record, String property, String filter) {                
                switch (filterUsing.getSelectedIndex()) {
                case 0:
                    if (record.getNome() != null) {
                        String nome = record.getNome().toLowerCase();
                        if (nome.startsWith(filter.toLowerCase())) {
                            return true;
                        }
                    }
                    if (record.getCognome() != null) {
                        String cognome = record.getCognome().toLowerCase();
                        if (cognome.startsWith(filter.toLowerCase())) {
                            return true;
                        }
                    }
                    break;
                case 1:
                    if (record.getAzienda() != null) {
                        String azienda = record.getAzienda().toLowerCase();
                        if (azienda.startsWith(filter.toLowerCase())) {
                            return true;
                        }
                    }
                    break;             
                }
                return false;
            }
        };
        filterField.setWidth(200);
        filterField.bind(store);
        // toolbar
        filterUsing.setEditable(false);
        filterUsing.setWidth(100);
        filterUsing.add("Nome/Cognome");
        filterUsing.add("Azienda");
        filterUsing.setTriggerAction(TriggerAction.ALL);
        //filterUsing.setSimpleValue("Nome");
        toolbarFiltro.add(new LabelToolItem("Cerca:"));
        toolbarFiltro.add(filterField);
        toolbarFiltro.add(new LabelToolItem("Filtro:"));
        toolbarFiltro.add(filterUsing);
        toolbarFiltro.add(selezionatiLabel);
        setTopComponent(toolbarFiltro);
    }
    
    private void addToolbar(boolean beforeRender, PagingLoader<PagingLoadResult<ContattoModel>> loader) {
        if (showToolBar) {
            toolbar.bind(loader);
            toolbar.refresh();
        }
        if (showToolBar && beforeRender) {
            setBottomComponent(toolbar);
        }
        toolbar.setEnabled(true);
        pagingCheck.setBoxLabel("Paging");
        pagingCheck.setValue(true);
        pagingCheck.addListener(Events.OnClick, new Listener<BaseEvent>() {
            @Override
            public void handleEvent(BaseEvent be) {
                if(pagingCheck.getValue()==true) {
                    toolbar.setPageSize(50);
                    pagingConfig.setOffset(0);
                    pagingConfig.setLimit(50);
                    grid.getStore().getLoader().load(pagingConfig); // loader.load(pagingConfig);                    
                }
                else {
                    toolbar.setPageSize(300000);
                    pagingConfig.setOffset(0);
                    pagingConfig.setLimit(300000);
                    grid.getStore().getLoader().load(pagingConfig); // loader.load(pagingConfig);
                }
            }
        });
        toolbar.add(pagingCheck);
        setBottomComponent(toolbar);
    }
        
    private GroupingView createGroupingView(final ColumnModel cm) {
        GroupingView groupingView = new GroupingView();
        groupingView.setShowGroupedColumn(false);
        groupingView.setForceFit(true);
        groupingView.setGroupRenderer(new GridGroupRenderer() {
            public String render(GroupColumnData data) {
                String f = cm.getColumnById(data.field).getHeader();
                String l = data.models.size() == 1 ? "Item" : "Items";
                return f + ": " + data.group + " (" + data.models.size() + " " + l + ")";
                }
        });
        return groupingView;
    }

    public Grid<ContattoModel> getGrid() {
        return grid;
    }

}
Grazie e cari saluti
Matteo