But if i navigate outside the button event handler (in other thread as a Timer after button event handler completed execution) then the “Result Page” will not show. Need to click again in page, then “Result Page” will only show.
void buttonLoginHandler(ClickEvent<Button> event){
}
void myTimerThread(){
// this will not work, ResultView does not show, there is no exception.
ui.access(()->{ (ui.getUI().ifPresent(uii -> {
uii.navigate(ResultView.class, data);
}); };)
}
If the code is run asynchronously (for example new Thread, etc), then you need ui.access(..) to push any changes to the ui. Inside a ClickListener (or any Listener based on user action) however, you don’t need that. That’s why it worked there.
In your code sample, you don’t show how ui is defined. You need to save the ui instance of the view when the view is attached, to be able to reuse it later for a call of ui.access in a background thread.
PS: you don’t need ui.getUI.ifPresent part, it gets an optional of itself.
public class MyLoginView extends VerticalLayout {
private UI ui;
private String data = "";
public MyLoginView(){
// save ui instance when view is attached
addAttachListener(event -> this.ui = UI.getCurrent());
add(new Button("Navigate in 5 seconds", click -> {
new Thread(() -> {
Thread.sleep(5000);
this.ui.access(() -> ui.navigate(ResultView.class, data));
}).start();
}));
}
}