0

I am using Vaadin 14.0.3. I have a class MainLayout with a method someCode. I am using this class as layout for another class named MainView. Is it possible to use the method someCode in MainView? Here's the example:

public class MainLayout {
    public void someCode() {
    }
}

@Route(value = "main", layout = MainLayout.class)
public class MainView { 
}

Thanks!

2 Answers2

0

It is possible, it's not necessarily a great practice though, as it couples the classes very tightly.

That said, if you're using Spring, you can make the MainLayout a UIScoped Spring component and autowire it in the MainView.

Otherwise you'll have to use the getParent() method and cast the result to MainLayout.

@Override
public void onAttach(AttachEvent event) {
    Optional<Component> parent = getParent();
    while (parent.isPresent()) { 
        Component p = parent.get();
        if (p instanceof MainLayout) {
            MainLayout main = (MainLayout) p;
            main.hello();
        }           
        parent = p.getParent();
    }
}
Tatu Lund
  • 9,949
  • 1
  • 12
  • 26
Erik Lumme
  • 5,202
  • 13
  • 27
0

In my application I use the approach described in Erik's answer (get the parent component during onAttach of the routed view). However I expanded it a bit and make use of interfaces to prevent duplicate code. Here's my setup:

public class MainView extends HorizontalLayout implements RouterLayout {
    public MainView(){
        ...
    }

    public interface Retriever extends HasElement {
        default MainView getMainView() {
            Component parent = getElement().getComponent().orElse(null);
            while (parent != null && !parent.getClass().equals(MainView.class)) {
                parent = parent.getParent().orElse(null);
            }
            return (MainView)parent;
        }
    }
}
@Route("main")
public class MainRoute extends VerticalLayout implements MainView.Retriever {

    public MainRoute(){
        ...
    }

    @Override
    public void onAttach(){
        MainView mainView = getMainView();
        if (mainView != null){
            mainView.someCode(); // do with the mainView what you want here
        } else {
            LOGGER.error(...);
        }
    }
}

please notice that my routerLayout is called MainView and not MainLayout. I did not want to change that name as the name "MainView" is used for the routerlayout in most official documentations and examples

kscherrer
  • 5,486
  • 2
  • 19
  • 59