Integrate V-Leaflet vaadin add-on with platform 6.10

V-Leaflet is the Vaadin add-on based on the open source Leaflet JavaScript library for mobile-friendly interactive maps.
This step-by-step tutorial allows you to integrate addon into your Cuba Platform application. Note that your application should be based on platform version 6.10.X:

Create a new project called leaflet-demo with the root package name

Create the Salesperson entity that describes an abstract salesperson.


Because the photo attribute is an association to com.haulmont.cuba.core.entity.FileDescriptor, create a view to be able to retrieve all its attributes from the application database.

Create the entity’s editor and browser. In the view field for the editor screen, select the newly created view.

To integrate the add-on into your project you should follow these instructions. In order to find the latest compatible add-on version, go to the add-on web page and select a Vaadin 7.0+ framework support link. In our case the latest compatible version is 1.0.6:


Create a blank screen with XML descriptor called map-screen.xml and a controller called in the package.

Add a visual component that will be used as a container for a map to the map-screen.xml, e.g. vbox:

<layout expand="mapContainer">
    <vbox id="mapContainer" width="100%"/>

Your controller should contain these imports and the methods below:

import com.haulmont.cuba.core.entity.FileDescriptor;
import com.haulmont.cuba.gui.components.VBoxLayout;
import com.haulmont.cuba.web.gui.components.WebComponentsHelper;
import com.haulmont.cuba.web.gui.components.WebFileDescriptorResource;
import com.haulmont.demo.entity.Salesperson;
import com.vaadin.server.Resource;
import com.vaadin.ui.Layout;
import org.vaadin.addon.leaflet.LLayerGroup;
import org.vaadin.addon.leaflet.LMap;
import org.vaadin.addon.leaflet.LMarker;
import org.vaadin.addon.leaflet.LOpenStreetMapLayer;
import org.vaadin.addon.leaflet.shared.Point;
import javax.inject.Inject;
import java.util.Objects;
import java.util.UUID;

initMap() creates your map, sets its default center coordinates and zoom level and adds an OSM tiles layer:

private static final double DEFAULT_LATITUDE = 53.241505;
private static final double DEFAULT_LONGITUDE = 50.221245;
private static final double ZOOM_LEVEL = 12;
private LMap map;
private void initMap() {
    map = new LMap();
    map.addLayer(new LOpenStreetMapLayer());
    map.setCenter(new Point(DEFAULT_LATITUDE, DEFAULT_LONGITUDE));

drawPersonMarkers() creates personMarkers LLayerGroup that contains combined map layers (markers in our case) to handle them as one in our code, refreshes salespersonsDs, then for each Salesperson creates marker that will be added to the personMarkers. Finally adds personMarkers to the map:

private CollectionDatasource<Salesperson, UUID> salespersonsDs;
private LLayerGroup personMarkers;
private void drawPersonMarkers() {
    personMarkers = new LLayerGroup();

    for (Salesperson person: salespersonsDs.getItems()) {
        LMarker marker = createPersonMarker(person);


createPersonMarker(Salesperson person) creates LMarker object for the passed to the method Salesperson object and sets icon if a passed person has its own photo:

private LMarker createPersonMarker(Salesperson person) {
    Point personLocation = new Point(person.getLatitude(), person.getLongitude());
    LMarker marker = new LMarker(personLocation);

    Resource photoResource = getPersonPhotoResource(person);
    if (Objects.nonNull(photoResource)) {
        Point iconSize = new Point(65, 65);  // Icon size 65x65 px
        Point iconAnchor = new Point(32, 32);  // Icon anchor at the center of the image
    return marker;

getPersonPhotoResource(Salesperson person) transforms the person’s photo that is FileDescriptor object to a Vaadin Resource object needed to set marker’s icon:

private Resource getPersonPhotoResource(Salesperson person) {
    Resource photoResource = null;

    FileDescriptor photoDescriptor = person.getPhoto();
    if (Objects.nonNull(photoDescriptor)) {
        WebFileDescriptorResource fileDescriptorResource = new WebFileDescriptorResource();
        photoResource = fileDescriptorResource.getResource();

    return photoResource;

addMapToContainer() adds map to VBoxLayout container via vaadin Layout object:

private VBoxLayout mapContainer;
private void addMapToContainer() {
    Layout layout = (Layout) WebComponentsHelper.unwrap(mapContainer);

Finally, you just should call the methods above from ready() hook method:

public void ready() {

As the result you will see the following:


The complete project can be found on GitHub.