So if I understand your question right, you want to have the Collections of your BeanItemContainer-Entity displayed in one column each?
I see two possibilities for that.
Option 1 - use a wrapper class for your Set
s and use addNestedContainerBean
One possibility would be to not use Set
s inside your LocationBasedRole
but to use a wrapper class that extends HashSet
.
Then you could use the addNestedContainerBean
method.
I created a small example with the BeanItemContainer-Entity Team
public class Team {
private String teamName;
private Members teamMembers;
public String getTeamName() {
return teamName;
}
public void setTeamName(String teamName) {
this.teamName = teamName;
}
public Members getTeamMembers() {
return teamMembers;
}
public void setTeamMembers(Members teamMembers) {
this.teamMembers = teamMembers;
}
}
Which consists of a name and teamMembers. The latter is of type Members
:
public class Members extends HashSet<TeamMember> {
public String getMembers() {
return this.stream()
.map(member -> member.getFirstName() + " " + member.getLastName())
.collect(Collectors.joining(","));
}
}
Which is a simple wrapper for the Set
that contains instances of TeamMember
:
public class TeamMember {
private String firstName;
private String lastName;
private Integer age;
// getters and setters
}
As you can see in the Members
class, there is a method getMembers
which returns a String, containing a comma separated list of the team members names.
If we now use addNestedContainerBean("teamMembers")
Vaadin tries to display all properties contained in the class Members
. Vaadin will think getMembers is a getter for a String property called members and so generate a column for it.
Vaadin will also display a column "empty" because it will find the isEmpty
method of Set
and think empty
is a property to display in a column. So we tell Vaadin to remove that column.
The final code of my example looks like:
protected Component createContent() {
Set<Team> teams=new HashSet<>();
for (int teamCounter = 0; teamCounter < 5; teamCounter++) {
Team team = createTeam();
addMembersToTeam(5, team);
teams.add(team);
}
BeanItemContainer<Team> bean=new BeanItemContainer<>(Team.class);
bean.addNestedContainerBean("teamMembers");
bean.removeContainerProperty("teamMembers.empty");
bean.addAll(teams);
teamTable.setContainerDataSource(bean);
return new VerticalLayout(teamTable);
}
The result looks like:

Option 2 - create fake getters and use addNestedContainerProperty
The only thing you have to do for this is extend your BeanItemContainer-Entity (LocationBasedRole
) and create a fake getter for each Set
you want to be displayed in a column. In your example those two fake getters could be public String getTheRoles()
and public String getTheLocations()
. Then you can use bean.addNestedContainerProperty("theRoles")
and bean.addNestedContainerProperty("theLocations")
.
In my example my TeamMember
class (the counterpart to your Role
/ Location
classes) would still look like in the option above:
public class TeamMember {
private String firstName;
private String lastName;
private Integer age;
// getters and setters
}
And my Team
class (your LocationBasedRole
) would look like:
public class Team {
private String teamName;
private Set<TeamMember> teamMembers;
public String getTeamName() {
return teamName;
}
public void setTeamName(String teamName) {
this.teamName = teamName;
}
public Set<TeamMember> getTeamMembers() {
return teamMembers;
}
public void setTeamMembers(Set<TeamMember> teamMembers) {
this.teamMembers = teamMembers;
}
public String getMembers() {
if (teamMembers != null) {
return teamMembers.stream()
.map(member -> member.getFirstName() + " " + member.getLastName())
.collect(Collectors.joining(","));
} else {
return "No members";
}
}
}
Now you can tell vaadin to add the (not existing) property "members" and Vaadin will find the getter getMembers
and use this for generating the column. We also have to tell vaadin not to display the original "teamMembers" property. So the final code is:
protected Component createContent() {
Set<Team> teams=new HashSet<>();
for (int teamCounter = 0; teamCounter < 5; teamCounter++) {
Team team = createTeam();
addMembersToTeam(5, team);
teams.add(team);
}
BeanItemContainer<Team> bean=new BeanItemContainer<>(Team.class);
bean.addNestedContainerProperty("members");
bean.removeContainerProperty("teamMembers");
bean.addAll(teams);
teamTable.setContainerDataSource(bean);
return new VerticalLayout(teamTable);
}
and the result looks like:
