Close
Back

Mission RIP Table: Migrate to Grid! - Basic

As promised earlier, here is the first and most basic example. As a reference, Gridv7 is the Grid component from Framework 7, while Grid is the latest Grid component in Framework 8. Naturally, you can also migrate straight from Table to the Framework 8 style Grid.

Migrate from Table to Framework 7 Grid

Before starting, we need to remember that the fundamental difference between Table and Grid is that Grid is a pure Component, while Table is a mixture of a Component and a Container at the same time. So whenever we have a Table without an external declaration of Container, we must create one first to be able to use it with Grid:

IndexedContainer container = new IndexedContainer();

 

The declaration of Table and Grid is pretty similar, so replacing:

Table table = new Table("The Brightest Stars");

With:

Gridv7 table = new Gridv7("The Brightest Stars", container);

 

And here I defined the container in the constructor. We can do that in a separate line as well using setContainerDataSource. The important step now is to replace all Container-related calls that were directly using Table, to use container, for example replace:

table.addContainerProperty("Name", String.class, null);

With:

container.addContainerProperty("Name", String.class, null);

 

There is no addItem() API anymore in the Containers. You can not do something like this:

table.addItem(new Object[]{"Canopus", -0.72f}, 2);

But instead:

itemId = container.addItem(2);
itemId.getItemProperty("Name").setValue("Canopus");
itemId.getItemProperty("Mag").setValue(-0.72f);

 

While this sounds like a drawback at first, the main reason behind this architecture was to get rid of manual filling of data components and make them all based on Containers. Basically you should not fill any data components one by one using addItem, that’s why it has disappeared completely in Framework 8.

 

The setPageLength API specifies the height of the Table. Grid’s height can be specified using different methods, that’s why this line:

table.setPageLength(table.size());

Needs to be replaced with two lines:

table.setHeightMode(HeightMode.ROW);
table.setHeightByRows(container.size());
 

Before you feel like you have done everything, there is one small thing missing if you want an exact migration from Table to Grid. You must disable the selection because that was the case by default in Table:

table.setSelectionMode(Gridv7.SelectionMode.NONE);

But in future examples I will ignore this extra line.

 

Related commit: Basic: To Grid v7 first method

 

A perfect migration would involve architecture modernization as well, that’s why I prefer not to stop at this point, and change the way how the data is populated inside this basic Grid. This will also help in future migration to Framework 8.

 

So I define a simple hard coded data and populate it inside the container:

Object[][] data = {
  {"Sirius", -1.46f},
  {"Canopus", -0.72f},
  {"Arcturus", -0.04f},
  {"Alpha Centauri", -0.01f}
};

IndexedContainer container
    = new IndexedContainer(Arrays.asList(data));
 

And this will make it easy to iterate over them while giving values:

for(Object[] item: data) {
  container.getItem(item).getItemProperty("Name")
      .setValue(item[0]);
  container.getItem(item).getItemProperty("Mag")
      .setValue(item[1]);
}
 

This replaces the manual hard coded definition of items. Note that we don’t need to define items anymore, we just set the values.

 

Related commit: Basic: To Grid v7 second method

Migrate to Framework 8 Grid

Grid in Framework 8 is way much simpler, we don’t use Containers nor Property anymore. Grid is parameterized with the type of data you want to display. So instead of:

IndexedContainer container
    = new IndexedContainer(Arrays.asList(data));
Gridv7 table = new Gridv7("The Brightest Stars", container);

We set the data directly into Grid:

Grid<object> table = new Grid<>("The Brightest Stars");
table.setItems(data);
 

We don’t need to define properties manually anymore, nor define items one by one, we can use some lambda magic:

table.addColumn(v -> v[0]).setCaption("Name");
table.addColumn(v -> v[1]).setCaption("Mag");
 

The first part table.addColumn(v -> v[i]) defines how the columns are provided from the given data, and the second part setCaption("Name") is to manually give a name for the column, since we are not using a proper POJO that can help us automatically generate the column names. Later there will be some more examples about this, but now we can see how this first example is easily transformed into a very simple code with the power of Framework 8.

 

Related commit: Basic: To Grid v8

 

Does this give you a good kickstarter for your migration process? Let us know how you feel about it so far in a comment below!

Comments
Add Comment
Table is dead! Long live Grid 8! But what about the missing scrollTo(Object itemId) functionality in Grid 8, where itemId is data source id of type Object, not just row index of int? (https://vaadin.com/forum#!/thread/15758435) It's quite hard to migrate without filling in the gaps.
Posted on 8/23/17 9:07 PM.
And multiline headers, multiple injected styles per cell, shift- and ctrl-click for range selection... I'm 80% through a port from TreeTable to TreeGrid and I miss TreeTable. Grid is faster, for sure, but not as mature. And why is TreeData a class and not an interface?
Posted on 8/24/17 12:14 AM in reply to Vasiley Borschenko.
@Vasiley I've just posted a reply: https://vaadin.com/forum#!/thread/15758435/16597838
Apparently there is also a related issue: https://github.com/vaadin/framework/issues/8820
Thanks for reporting!
Posted on 8/25/17 3:30 PM in reply to Jeffrey Lyon.
@Jeffrey: In my next post coming next Wednesday, I will discuss the `shift- and ctrl-click for range selection` but to give you an early answer: unfortunately not planned to be supported anytime soon. There is a github issue about it and you can discuss it there: https://github.com/vaadin/framework/issues/6597

Multiple headers: Will discuss it later in three weeks from now. stay tuned!

Multiple injected styles: not sure what you mean by this?

TreeData: Please ask in the forum. Not really sure about the architectural reason behind it. But we can always discuss if you are facing some problems with it? Community Experts in the forums always know more though :-)
Posted on 8/25/17 3:41 PM in reply to Jeffrey Lyon.
Thanks for the reply, I'll keep an eye out for information regarding multiple headers. Table/TreeTable supports range selection so dropping that feature from Grid/TreeGrid is a real problem as I have to pull functionality from my customers.

TreeGrid is wicked fast but is full of feature holes, e.g. scrollTo(int) always throws and exception and I'm still chasing a bug where indented information doesn't display after the first setDataProvider.

Re. multiple injected styles: StyleGenerator should allow us to return a list of style names. I've got text cells that should be displayed in red, yellow, green, and blue and aligned left, right, and center. Because StyleGenerator can only return a single style name I have to spin over all permutations in my css and programmatically build a compounded style name. Providing a setStyleGenerator(Function<T, String>) and a setStylesGenerator(Function<T, List<String>>) would be much nicer.
Posted on 8/29/17 2:32 AM in reply to AMahdy Abdelaziz.
And here is the new post, one day earlier than initally announced :-)
https://vaadin.com/blog/-/blogs/mission-rip-table-migrate-to-grid-selection

There is a nice add-on that provide some of the missing features such as old-style multi selection, you can give it a try: https://vaadin.com/directory/-/directory/addon/#!addon/gridextensionpack-add-on

Please do report all bugs, hopefully with reproducible code in here: https://github.com/vaadin/framework/issues
You can also post your feature suggest there as well, and let the discussion begin! :-)
Posted on 8/29/17 10:43 AM in reply to Jeffrey Lyon.