Simple UI-View error

Hello vaadin community,

I´m trying to implement an simple view which is extending from UI-class.
If I´m adding an vaadin component I get these error:

java.lang.IllegalStateException: Can’t set the parent of the tree root
at com.vaadin.flow.internal.StateTree$RootNode.setParent(StateTree.java:60) ~[flow-server-1.4.2.jar:1.4.2]

at com.vaadin.flow.internal.nodefeature.NodeFeature.attachPotentialChild(NodeFeature.java:78) ~[flow-server-1.4.2.jar:1.4.2]

at com.vaadin.flow.internal.nodefeature.StateNodeNodeList.add(StateNodeNodeList.java:53) ~[flow-server-1.4.2.jar:1.4.2]

at com.vaadin.flow.internal.nodefeature.ElementChildrenList.add(ElementChildrenList.java:42) ~[flow-server-1.4.2.jar:1.4.2]

at com.vaadin.flow.dom.impl.AbstractNodeStateProvider.insertChild(AbstractNodeStateProvider.java:102) ~[flow-server-1.4.2.jar:1.4.2]

at com.vaadin.flow.dom.Node.insertChild(Node.java:250) ~[flow-server-1.4.2.jar:1.4.2]

My view looks so

@Route
@PWA(name = "Project Base for Vaadin Flow with Spring", shortName = "Project Base")
public class MainView extends UI {

    public MainView(@Autowired MessageBean bean) {
        VerticalLayout layout = new VerticalLayout();
        Button button = new Button("Click me",
                e -> Notification.show(bean.getMessage()));
        layout.add(button);
        add(layout);
    }

}

Can anybody say me how i can set the layout as child? (Using vaadin version 13)
Thanksssss!

Hi Peter,

I think this sentence sums up your issue:

I´m trying to implement an simple view which is extending from UI-class.

You probably don’t want to have your MainView extend the UI class, but rather some specific components class like e.g. a Div.

The Vaadin Javadocs states the purpose of the UI class pretty well imo:

 The topmost component in any component hierarchy. There is one UI for every
 Vaadin instance in a browser window. A UI may either represent an entire
 browser window (or tab) or some part of a html page where a Vaadin
 application is embedded.

Hey Dennis,

I wanted to represent with the mainView an entire browser window.

  1. Instead of extending UI, extend VerticalLayout. This VerticalLayout component will be added to the <body> element in the DOM (simplifying a bit).
  2. Give a value parameter to the @Route annotation, like an empty String: @Route(""). This will mean this component will be found from the root URL of the application like http://localhost:8080/ deployed on a local Jetty server’s root context.

You might want to read more about routing in the docs here : https://vaadin.com/docs/v13/flow/routing/tutorial-routing-annotation.html or watch the Router API training: https://vaadin.com/training/course/view/v10-router

-Olli

Hi Peter

Dennis is right; In Vaadin Flow, the view classes do no longer extend UI like it was done in Vaadin 8 and earlier. Instead, Every View needs to extend a Component like for example a Div or a VerticalLayout.

Changing your extend like this should already work:

@Route("")
@PWA(name = "Project Base for Vaadin Flow with Spring", shortName = "Project Base")
public class MainView extends VerticalLayout {

    public MainView(@Autowired MessageBean bean) {
        VerticalLayout layout = new VerticalLayout();
        Button button = new Button("Click me",
                e -> Notification.show(bean.getMessage()));
        layout.add(button);
        add(layout); // will use VerticalLayout::add
    }
}

or you could now leave out your inner VerticalLayout (only if you want) and add your components directly to the MainView since it now extends VerticalLayout:

@Route("")
@PWA(name = "Project Base for Vaadin Flow with Spring", shortName = "Project Base")
public class MainView extends VerticalLayout {

    public MainView(@Autowired MessageBean bean) {
        Button button = new Button("Click me",
                e -> Notification.show(bean.getMessage()));
        add(button); // uses VerticalLayout::add
    }
}

Its good to know that the view class do not extend from UI.class. Thanks a lot for your help.
The reason because I wanted to use the UI was that I needed the transport polling. So its not required to use the UI right?
Thankss!!!

No, you can set the @Push annotation in your main View class.