From one SpringUI to Navigator

Hi,

im stuck and this for a week now. Im using Spring+Vaadin only with java and impement and app with one class that extends UI and has the annotation @SpringUI. Now the amout of things you could do grows that much that i need different views to manage all this stuff.

So i tryed to implenment a navigator and split the SpringUI thing in 10 views. First thing that does not work is Autowireing in the views. It only works in the MainUI. Hope someone could explain or give me a solution for this, another way whatever.

Here are a reduced example what i try to do. First the navigator that works. Then the view where i try to autowire the service class this does not work.

Navigator

@SpringViewDisplay
@SpringUI
public class Navigation extends UI { 
        
    @Override
    protected void init(VaadinRequest request) {
        
        HorizontalLayout mainLayout = new HorizontalLayout();
        VerticalLayout navigationPanelLeft = new VerticalLayout();
        VerticalLayout contentRight = new VerticalLayout();
        
        mainLayout.addComponents(navigationPanelLeft, contentRight);
        mainLayout.setExpandRatio(navigationPanelLeft, 20);
        mainLayout.setExpandRatio(contentRight, 80);
        
        setContent(mainLayout);
        
        Navigator navigator = new Navigator(this, contentRight);
        //navigator.addView("Abschluss-Editor", AbschlussEditorView.class);
        //navigator.addView("Mitarbeiter-Editor", MitarbeiterEditorView.class);
        navigator.addView("Sprachen-Editor", SprachenEditorView.class);
        navigator.addView("", SprachenEditorView.class);
        
        navigationPanelLeft.addComponent(this.createNewNavBtn("Sprachen-Editor", navigator));
        //navigationPanelLeft.addComponent(this.createNewNavBtn("Abschluss-Editor", navigator));
        //navigationPanelLeft.addComponent(this.createNewNavBtn("Mitarbeiter-Editor", navigator));
        
    }

    private Button createNewNavBtn(String goToSite, Navigator navigator) {
        return new Button(goToSite, new Button.ClickListener() {
            
            @Override
            public void buttonClick(ClickEvent event) {
                navigator.navigateTo(goToSite);
            }
        });
        
    }  
    
}


@SpringView
public class SprachenEditorView extends FormLayout implements View{
    
    @Autowired
    private SprachenService sprachenService;
    
    private Grid<Sprache> sprachenGrid = new Grid(Sprache.class);
    private Button speichernBtn = new Button("Speichern");
    private Button loeschenBtn = new Button("Löschen");
    private TextField sprache = new TextField("Sprache");
    
    private VerticalLayout mainLayout = new VerticalLayout();
    private HorizontalLayout buttonLayout = new HorizontalLayout();
    
    public SprachenEditorView() {
        
        buttonLayout.addComponents(loeschenBtn, speichernBtn);
        mainLayout.addComponents(sprachenGrid, sprache, buttonLayout);
        this.addComponents(mainLayout, buttonLayout);
        
        Mitarbeiter m = new Mitarbeiter(null, "", "", "", "", "", "", "", null, null, null, null, "", "", "");
        m.setId((long) 1);
        updateSprachenGrid(m);
    }
    
    @Override
    public void enter(ViewChangeEvent e) {
        
    }
    
    private void updateSprachenGrid(Mitarbeiter m) {
        List<Sprache> listSprachen = sprachenService.sprachenMitarbeiter(m.getId());
        sprachenGrid.setItems(listSprachen);
    }
    
}

I assume you are using Vaadin Spring add-on. And it that case you are having slightly wrong approach. You should not add individual views to navigator with addView(…), instead you should autowire the view provider (given by the add-on) and annotate your views, so that they are picked to view provider automatically.

See also another thread here:

https://vaadin.com/forum/#!/thread/16860432/16862607

Mh i take a look at the bakery before but i dont get it. In the bakery they also use the vaadin designer so there are a lot auf autogenerated classes. I am looking for a more simple example or some correction in my code i posted. Something with a navigator 2 views or so.

Still need assist

I guess this is a good example of why field-level injection is not good :wink:

In your
View
implementation, move the
@Autowired
annotation to the constructor and add a parameter to allow Spring inject the service bean:

@SpringView
public class SprachenEditorView extends FormLayout implements View{
    
    private final SprachenService sprachenService;
    ...
    
    @Autowired
    public SprachenEditorView(SprachenService sprachenService) {
        ...
    }
    ...
}

Moreover, you can remove the
@Autowired
annotation altogether.

You can find a working example here:
https://github.com/alejandro-du/community-answers/tree/side-menu-spring/side-menu

This really helps me a lot. Thank you so much i appriciate that.