How can i create a reusable base Grid

Hey guys.
I am new to Vaadin and still trying to learn it.
Currently i am butting heads with the components.

My issue here is this:
I have class A, B and C and so on…
And i have a view where i display the list of objects from those classes on a grid, each class has a grid assigned to them. (currently i have 5 of them but there will be more throughout the web app)
The thing is those classes have similar fields. Like all of the classes have the fields Id, name, shortName, etc. (they all extend one Main class Z)
So i was wondering how can i create a single reusable grid to use as a base and depending on the class i want to list, add the specific fields to it. Basically in my head i want a reusable grid component created separately and then call it to the view and then from there adapt it to my needs.

Because right now what i am doing is i am creating 5 different grids in the same view (i don’t feel like this is a good practice btw) and that kinda makes my code very repetitive cause i have to do the same thing multiple times and i would like to know if its possible to prevent this repetitive coding.

Sorry for the bothering and thanks in advance for your time.

Hi,

It’s hard to give a solution without knowing the architecture and your need.
But one simple solution to avoid copy/paste for the generic columns is to make a static class GridUtil
GridUtil.addGenericColumns(grid)
This method will add the generic columns of your Main class Z.

About the 5 different grids in one view. That’s probably a lot to show, but it’s more a UX problem than a technical issue.

Hey thanks for the help,
I basically want to have something like the form layout component created apart like the one the [tutorial here]
(https://vaadin.com/learn/tutorials/modern-web-apps-with-spring-boot-and-vaadin/creating-custom-reusable-components-in-vaadin) shows
But with a grid and i want to be able to add to that component more columns depending on the type of object i want to list.
The GridUtil.addGenericColumns(grid) i could not find it or understand where or how to use it. I am using vaadin flow not sure if it helps or not.

As far as the 5 grids in one view yea it was too much so i decided to only show 2 and from the second grid go to another page with the other 2 grids and then have the option to go to another page
Since i have 5 classes i want to list and each of them is related to the other like this:
Client has Organization that has Plant that has Section that has Cell
And all of them extend class FObject that has a name, shortname, description etc. but they all have attributes of their own wich is why i was hoping to find a way to have a “master” grid and then from that one adapt.

Vaadins Grid class pretty much is a master grid already. You can have it automatically add columns for all basic attributes of the item-class. All you need to do is pass the item class in the grids constructor.
If you don’t want to rely on automatic column creation, you could also have a helper method somewhere that adds column for the FObject properties and invoke that method on each of your grids, and add individual columns for single grids separately for the attributes that they don’t share.

Grid<Client> clientGrid = new Grid<>(Client.class);
Grid<Organization> orgGrid = new Grid<>(Organization .class);
Grid<Plant> plantGrid = new Grid<>(Plant .class);
Grid<Section> sectionGrid = new Grid<>(Section .class);
Grid<Cell> cellGrid = new Grid<>(Cell .class);

Now you add selectionChange Listeners to change the items of other grids once you select a different client for example.

clientGrid.addSelectionListener(selectionEvent -> {
	Optional<Client> selectedClient = selectionEvent.getFirstSelectedItem();
	if(selectedClient.isPresent()) {
		orgGrid.setItems(selectedClient.get().getOrganisations();
		// todo: probably clear all other grids
	}
}
// todo: same for orgGrid, plantGrid, sectionGrid

Hi there, sorry for the late answer.

Thank you very much for the help it pointed me to the right direction.

I decided to create a helper class ConfigurationGrid and create my grids there like this:

private static Grid<? extends FmObject> createObjectGrid() {
	    Grid<? extends FmObject> objectGrid = new Grid<>(FmObject.class);
		objectGrid.setHeight("400px");
		objectGrid.setColumns();
		Grid.Column<?> id = objectGrid.addColumn(Long -> FmObject.getId(Long)).setHeader("Id").setKey("id").setSortable(true);
		//rest of the columns below
		...
		
		return objectGrid;
	}
	//then use the created objectGrid to create the other ones that have an object that extends FmObject
	public static Grid<FmClient> createClientGrid() {
		
		Grid<FmClient> clientGrid = new Grid<>(FmClient.class);
		
		clientGrid = (Grid<FmClient>) createObjectGrid();
		clientGrid.addClassName("clientGrid");
		clientGrid.getColumns().forEach(col -> col.setAutoWidth(true));

		return clientGrid;
	}
		public static Grid<FmOrganization> createOrganizationGrid() {
		Grid<FmOrganization> organizationGrid = new Grid<>(FmOrganization.class);
		organizationGrid = (Grid<FmOrganization>) createObjectGrid();
		
		organizationGrid.setVisible(false);
		organizationGrid.addClassName("orgGrid");
		organizationGrid.addColumn(organization -> {
			FmClient client = organization.getFmClient();
			return client == null ? "-" : client.getName();
		}).setHeader("Cliente").setKey("client").setSortable(true);
		organizationGrid.getColumns().forEach(col -> col.setAutoWidth(true));

		return organizationGrid;
	}
	//etc...

and then in the view i did it like this

private Grid setCliGrid() {
		cliGrid = ConfigurationGrids.createClientGrid();

		cliGrid.addSelectionListener(event -> event.getFirstSelectedItem().ifPresent(this::setOrganizationGridList));
		Grid.Column<FmClient> actions = cliGrid.addComponentColumn(this::editClientButton).setHeader("Acções");
		
		//i also created a function that helps me add headers to the grids i want
		HeaderRow clientHeader = ConfigurationGrids.setGridHeader(cliGrid, "Tabela dos Clientes");
		clientHeader.getCell(actions).setComponent(addClientButton());

		setClientGrid(cliGrid);

		return cliGrid;
	}

	private Grid setOrgGrid() {
		orgGrid = ConfigurationGrids.createOrganizationGrid();

		orgGrid.addItemDoubleClickListener(event -> viewPlantsSectionsView(event.getItem()));
		Grid.Column<FmOrganization> actions = orgGrid.addComponentColumn(this::editOrganizationButton).setHeader("Acções");
		
		HeaderRow organizationHeader = ConfigurationGrids.setGridHeader(orgGrid, "Tabela Organizaçoes");
		organizationHeader.getCell(orgGrid.getColumnByKey("client")).setComponent(closeOrganizationButton());
		organizationHeader.getCell(actions).setComponent(addOrganizationButton());

		setOrganizationGrid(orgGrid);
		return orgGrid;
	}

I am not sure if this is the best approach but it worked for me and allowed me to organize my code a little better but i am sure there are many ways to improve it