Ein Blog

Gesammelte Notizen

Spring Boot and Vaadin with Maven - Views

08 Januar, 2016 | Java

In this post we'll add some views to the application created in the previous post.

Because we will display multiple information we want to separate them into different views. Vaadins view are described here.

To add the views we'll modify the UI class created previously.

package de.jefure.sensorClient;

import com.vaadin.annotations.Theme;
import com.vaadin.navigator.Navigator;
import com.vaadin.server.VaadinRequest;
import com.vaadin.spring.annotation.SpringUI;
import com.vaadin.spring.navigator.SpringViewProvider;
import com.vaadin.ui.Button;
import com.vaadin.ui.CssLayout;
import com.vaadin.ui.Panel;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.themes.ValoTheme;
import de.jefure.sensorClient.view.SensorDataView;
import de.jefure.sensorClient.view.SensorView;
import org.springframework.beans.factory.annotation.Autowired;

@Theme("valo")
@SpringUI
public class SensorFrontendUI extends UI {

@Autowired
private SpringViewProvider viewProvider;

@Override
protected void init(VaadinRequest request) {
VerticalLayout vl = new VerticalLayout();
  vl.setMargin(true);
vl.setSizeFull();
vl.setSpacing(true);

final CssLayout navLayout = new CssLayout();
navLayout.addStyleName(ValoTheme.LAYOUT_COMPONENT_GROUP);
navLayout.addComponent(createNavigationButton("Sensors", SensorView.NAME));
navLayout.addComponent(createNavigationButton("Data", SensorDataView.NAME));
vl.addComponent(navLayout);

final Panel viewContainer = new Panel();
viewContainer.setSizeFull();
vl.addComponent(viewContainer);
vl.setExpandRatio(viewContainer, 1.0f);

setContent(vl);

Navigator navigator = new Navigator(this, viewContainer);
navigator.addProvider(viewProvider);
}

private Button createNavigationButton(String caption, final String viewName) {
Button button = new Button(caption);
button.addStyleName(ValoTheme.BUTTON_SMALL);
button.addClickListener(event -> getUI().getNavigator().navigateTo(viewName));
return button;
}
}

To use the views we'll add we have to update the the layout of the application. First we create and configure a layout component, here it is an VerticalLayout. Then we create another Layout (the CssLayout) where we add the buttons for switching between the different views. Next we create a container (the Panel) where the content of the different views will be displayed in. And at last we create the Navigator component. The navigator handles the navigation between the views, the views itself will be managed by the SpringViewProvider that is injected using the @Autowired annotation. The SpringViewProvider looks for classes annotated with @SpringView.

Now let's create the default view.
The default view is a view with an empty name, which will be called when http://localhost:8080 is called.

package de.jefure.sensorClient.view;

import com.vaadin.navigator.View;
import com.vaadin.navigator.ViewChangeListener;
import com.vaadin.spring.annotation.SpringView;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.Label;

@SpringView(name = DefaultView.NAME)
public class DefaultView extends CustomComponent implements View {
    public final static String NAME = "";

    @Override
    public void enter(ViewChangeListener.ViewChangeEvent event) {
        setCompositionRoot(new Label("Welcome"));
    }    
}

An now we add a view called sensors. It is a good practice to provide explicit names for the views, but it is possible use the automatic view name generation feature. If an explicit name is not provided the class name of the UI will be used to construct a pathname by the following convention: any trailing "View" will be truncated and camelcase will be converted to hyphenated lowercase. Examples here.

@UIScope
@SpringView(name = SensorView.NAME)
public class SensorView extends VerticalLayout implements View {
    public static final String NAME = "sensors";
    
    @Autowired
    private SensorController controller;
    
    @PostConstruct
    void init() {
        VerticalSplitPanel verticalSplit = new VerticalSplitPanel();
        SensorLayout sl = new SensorLayout(controller);
        SensorListLayout sll = new SensorListLayout(controller, sl);
        verticalSplit.setFirstComponent(sll);       
        verticalSplit.setSecondComponent(sl);
        
        setSizeFull();
                
        addComponent(verticalSplit);
    }

    @Override
    public void enter(ViewChangeListener.ViewChangeEvent event) {
        // see init method
    }    
}

In this view the annotation @UIScope is used. This annotation ensures that the view exist during the whole UI session once and that you'll get the same instance of the view every time navigating to it.

There is also the annotation @ViewScope, in this case you'll get a new instance of the view every time navigating to it.

Links:

III - Views and Navigation with Vaadin Spring

Book of Vaadin - 4.2.3. View Navigation