I have MyUI class
@Theme("mytheme")
@CDIUI("")
public class MyUI extends UI {
@Inject
LoginView loginView;
@Override
protected void init(VaadinRequest vaadinRequest) {
setContent(loginView);
}
...
I have a View with a init method annotated with @PostConstruct
@UIScoped
@CDIView(LoginView.VIEWNAME)
public class LoginView extends VerticalLayout implements CustomView {
@PostConstruct
public void initView() {
//initializations elements
Component loginForm = buildLoginForm();
addComponent(loginForm);
setComponentAlignment(loginForm, Alignment.MIDDLE_CENTER);
Notification notification = new Notification("Demo");
notification.setDescription("<span>DEMO</span>");
notification.setHtmlContentAllowed(true);
notification.setStyleName("tray dark small closable login-help");
notification.setPosition(Position.BOTTOM_CENTER);
notification.setDelayMsec(20000);
notification.show(Page.getCurrent()); // NullPointerException
}
}
The stacktrace is:
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.jboss.weld.injection.producer.DefaultLifecycleCallbackInvoker.invokeMethods(DefaultLifecycleCallbackInvoker.java:98)
... 72 more
Caused by: java.lang.NullPointerException
at com.vaadin.ui.Notification.show(Notification.java:378)
at com.test.claspina.view.LoginView.initView(LoginView.java:103)
... 77 more
My question is how to get the UI instance to use during the render the elements of my view.
I found a partial solution putting all definitions of elements into a configure method, this way:
public void configure() {
//initializations elements
Component loginForm = buildLoginForm();
addComponent(loginForm);
setComponentAlignment(loginForm, Alignment.MIDDLE_CENTER);
Notification notification = new Notification("Demo");
notification.setDescription("<span>DEMO</span>");
notification.setHtmlContentAllowed(true);
notification.setStyleName("tray dark small closable login-help");
notification.setPosition(Position.BOTTOM_CENTER);
notification.setDelayMsec(20000);
notification.show(Page.getCurrent());
}
And calling before setContent in my UI
loginView.configure();
setContent(loginView);
Finally, with the help of my co-worker, I found a solution:
It's necessary to use CDIViewProvider
this way
@Theme("mytheme")
@CDIUI("")
public class MyUI extends UI {
@Inject
LoginView loginView;
@Inject
private CDIViewProvider viewProvider;
@Override
protected void init(VaadinRequest vaadinRequest) {
Navigator navigator = new Navigator(this, this);
navigator.addProvider(viewProvider);
navigator.navigateTo("login");
}
And into the class, define the name of the view, and put all definitions of the elements of the view in entering method
@UIScoped
@CDIView(LoginView.VIEWNAME)
public class LoginView extends VerticalLayout implements CustomView {
public static final String VIEWNAME = "login";
//...
//other methods
//...
@Override
public void enter(ViewChangeListener.ViewChangeEvent event) {
//initializations elements
Component loginForm = buildLoginForm();
addComponent(loginForm);
setComponentAlignment(loginForm, Alignment.MIDDLE_CENTER);
Notification notification = new Notification("Demo");
notification.setDescription("<span>DEMO</span>");
notification.setHtmlContentAllowed(true);
notification.setStyleName("tray dark small closable login-help");
notification.setPosition(Position.BOTTOM_CENTER);
notification.setDelayMsec(20000);
notification.show(Page.getCurrent());
}
}