Is there a DataProvider that can have a new collection set?

I’m in the process of translating a vaadin 7 application (with TouchKit) to vaadin 8.3.3.

I would like to have a DataProvider that can be set from a collection, where it is possible to set a new collection and where setting a new collection will cause the grid (or whatever) to update.

Is there a suitable standard DataProvider where one can set a new collection into an existing DataProvider (that is bound to a Grid)?

Am I misunderstanding how DataProviders should be used?

See: https://vaadin.com/download/release/8.3/8.3.3/docs/api/com/vaadin/data/provider/ListDataProvider.html

public ListDataProvider(Collection items)

Constructs a new ListDataProvider.

Tatu Lund:
See: https://vaadin.com/download/release/8.3/8.3.3/docs/api/com/vaadin/data/provider/ListDataProvider.html

public ListDataProvider(Collection items)

Constructs a new ListDataProvider.

This provider has no method where I can set a new collection and thereby updating the grid listening to the provider.

To use this I would have to replace the dataprovider with a new one and that defeats the purpose of the dataprovider

For that specific there is convenience method in Grid

Grid.setItems(…)

which accepts Collection as parameter. Which is equivalent to setDataProvider(DataProvider.[ofCollection]
(https://vaadin.com/download/release/8.3/8.3.3/docs/api/com/vaadin/data/provider/DataProvider.html#ofCollection-java.util.Collection-)(items));

Or you can do something like this:

dataProvider.getItems().clear();
dataProvider.getItems().addAll(…);

So there are many ways.

Tatu Lund:
For that specific there is convenience method in Grid

Grid.setItems(…)

which accepts Collection as parameter. Which is equivalent to setDataProvider(DataProvider.[ofCollection]
(https://vaadin.com/download/release/8.3/8.3.3/docs/api/com/vaadin/data/provider/DataProvider.html#ofCollection-java.util.Collection-)(items));

So far I’ve gone for this approach (which I’m not really happy about because that makes GUI components part of the data model).

Or you can do something like this:

dataProvider.getItems().clear();
dataProvider.getItems().addAll(…);

Ah, thanks! That would be the approach I was searching for.

Seems similar to the BeanItemContainer stuff I have been replacing?
Hm… perhaps I should roll back a few changes and go for this intead of using the UI componenents as data model?

Two steps forward and two steps back…:slight_smile:

Calling clear() and addAll() on the underlying collection doesn’t seem to update the grid (not suprising, since a collection, without any extras, is all it is).

I tried adding a call to refreshAll(), eg. like this

            recentJobs.getItems().clear();
            recentJobs.getItems().addAll(getJobsFromAccount(provider, account, getClass()));
            recentJobs.refreshAll();

But it didn’t make anything update.

I found the forum thread [ListDataProvider refreshAll() does not update the grid]
(https://vaadin.com/forum/thread/15586695) which says that the problem is the equals() and/or hashCode() implementation of the bean.

The bean in question has a [hashCode()]
(https://github.com/steinarb/ukelonn/blob/b9e284fd873c57a8d996bddc3f3e93aa6856c8bd/ukelonn.bundle/src/main/java/no/priv/bang/ukelonn/impl/Transaction.java#L84)

    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + id;
        long temp;
        temp = Double.doubleToLongBits(transactionAmount);
        result = prime * result + (int) (temp ^ (temp >>> 32));
        result = prime * result + ((transactionTime == null) ? 0 : transactionTime.hashCode());
        result = prime * result + ((transactionType == null) ? 0 : transactionType.hashCode());
        return result;
    }

and [equals()]
(https://github.com/steinarb/ukelonn/blob/b9e284fd873c57a8d996bddc3f3e93aa6856c8bd/ukelonn.bundle/src/main/java/no/priv/bang/ukelonn/impl/Transaction.java#L98)

    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Transaction other = (Transaction) obj;
        if (id != other.id)
            return false;
        if (Double.doubleToLongBits(transactionAmount) != Double.doubleToLongBits(other.transactionAmount))
            return false;
        if (transactionTime == null) {
            if (other.transactionTime != null)
                return false;
        } else if (!transactionTime.equals(other.transactionTime))
            return false;
        if (transactionType == null) {
            if (other.transactionType != null)
                return false;
        } else if (!transactionType.equals(other.transactionType))
            return false;
        return true;
    }

autogenerated by eclipse back in October 2016, and has been unchanged since then.

The problem was a bug in my code: I had missed all of the places where the update should be called.

I’m not sure I’ve managed to modify all places where clear()/addAll()/refreshAll() should be called, but now at least, this particular Grid is updated as it should, when a NativeSelect is selected.