1

The question was asked here: https://vaadin.com/forum/thread/18095407/how-to-create-a-grid-without-binder

However the vaadin's forum closed so i want to continue it here.

On Vaadin 14, Any recommendation on the best way to implement grid with dynamic varying number of columns. Using column Index (1,2,3...) is not a good choice for me. Let say I have a simple Json file (only 1 level: key-value) to map to a grid and this Json has an unknown list of properties.

which approach is better in term of performance ?:

[Option 1]

class Data {
    private Map<String, Object> values = new HashMap<>();
    
    public void set(String key, Object val) {
        values.put(key, val);
    }
    
    public Object get(String key) {
        return values.get(key);
    }
}

Grid<Data> myGrid = new Grid<>();

[Option 2]

public class GridDynamicValueProvider implements ValueProvider<GridDynamicRow, Object> {

    private int columnIndex;

    public GridDynamicValueProvider(int columnIndex) {
        this.columnIndex = columnIndex;
    }

    @Override
    public Object apply(GridDynamicRow dynamicRow) {
        return dynamicRow.getValue(columnIndex);
    }

}

public class GridDynamicRow {

    private List<Object> values = new ArrayList<>();

    public void addValue(String value) {
        values.add(value);
    }

    public Object getValue(int columnIndex) {
        return values.get(columnIndex);
    }
}
Tatu Lund
  • 9,949
  • 1
  • 12
  • 26
Thang Le
  • 1,419
  • 1
  • 17
  • 25
  • 1
    Please add the code you have tried and how it failed (e.g. errors, stacktraces, logs, ...) so we can improve on it. – cfrick May 23 '21 at 19:17
  • The linked Forum discussion already contains an answer. Check the GitHub link posted by me. The same method can be used with Vaadin 14 as well. – Tatu Lund May 24 '21 at 04:22
  • "which approach is better in term of performance" - no one will know unless you measure it for **your** workload. – cfrick May 24 '21 at 10:41

1 Answers1

4

The SerializablePredicate of Vaadin accepts both function references and Lambdas, thus it is possible to use non-POJO data types with Grid and Binder in Vaadin, although that is a bit unconventional. The key ingredients are:

Grid<Map<String, Integer>> grid = new Grid<>();
...
grid.addColumn(map -> map.get("column")).setHeader("Column");

You can also wrap the Map in custom class if you have need to protect the internals.

class Data {
    private Map<String, Object> values = new HashMap<>();
    
    public void set(String key, Object val) {
        values.put(key, val);
    }
    
    public Object get(String key) {
        return values.get(key);
    }
}

Grid<Data> myGrid = new Grid<>();

As for the performance, essentially, you're comparing between using a List where you fetch by index versus a HashMap where you fetch by key. Here's a related question: ArrayList .get faster than HashMap .get?

You can use also ArrayList as Grid's type if you can index the columns with a number.

The both approaches allow generating Grid's with varying dynamic number of columns, for example if you read the data directly from a file or have raw data backend queries.

Tatu Lund
  • 9,949
  • 1
  • 12
  • 26