问题
I want to navigate to a view that displays large data in a grid after a button click. I know there is lazy loading but I want to load all data to be able to sort by clicking the header. With lazy loading I could only sort one column.
Button viewDataBtn = new Button("View scan data");
viewDataBtn .addClickListener(e -> {
UI.getCurrent().getNavigator().navigateTo("scandataview/" + name);
});
This does work but there is a long break until the new view is visible. Therefore, I want to show a window with a progress bar until the new view is loaded and load the new view in another thread. I tried the following without success:
viewDataBtn .addClickListener(e -> {
UI.getCurrent().addWindow(showProgress);
new Thread(new Loader()).start();
});
In the same class:
class Loader implements Runnable {
@Override
public void run() {
try {
//Nullpointer exception here:
UI.getCurrent().getNavigator().navigateTo("scandataview/" + name);
} catch (Exception e) {
e.printStackTrace();
}
finally {
UI.getCurrent().removeWindow(showProgress);
}
}
}
And the progress bar window:
public class LoadingIndicatorWindow extends Window {
public LoadingIndicatorWindow() {
center();
setVisible(true);
setResizable(false);
setDraggable(false);
setModal(true);
setClosable(false);
setCaption("Loading");
VerticalLayout layout = new VerticalLayout();
layout.setMargin(true);
layout.setWidth("100%");
Label progressLabel = new Label("Please wait! Data loading in progress...");
progressLabel.setSizeFull();
ProgressBar progressBar = new ProgressBar();
progressBar.setSizeFull();
progressBar.setIndeterminate(true);
progressBar.setVisible(true);
layout.addComponent(progressLabel);
layout.addComponent(progressBar);
layout.setComponentAlignment(progressLabel, Alignment.MIDDLE_CENTER);
layout.setComponentAlignment(progressBar, Alignment.MIDDLE_CENTER);
setContent(layout);
}
}
It seems I cannot navigate in a different thread.
Is there any way of showing a progress bar window before navigating to another view when that view is ready showing the large grid with data???
Thank you very much for your help!
回答1:
I would recommend to watch the excellent tutorial by Alejandro about the topic.
回答2:
try this: https://github.com/ldelaprade/ProgressWindowForVaadin
This progress window closes itself automatically when long task is complete. Works with No multi-threading required. The trick here is that you ask the progress window to show up, then when it gets focus, it asks back the server to start long operation.
Laurent
回答3:
As pointed out by Tatu Lund the tutorial by Alejandro is great. However, not exactly what I needed. Therefore, I want to post my answer.
I found the following link helpful:
Push documentation
The Loader class looks now as follows:
class Loader implements Runnable {
@Override
public void run() {
try {
getUI().access(() -> {
getUI().getNavigator().navigateTo("scandataview/" + name);
});
} catch (Exception e) {
e.printStackTrace();
}
}
}
To close the progress window I created an instance of the LoadingIndicatorWindow in the UI class and gave it to both views. The window is closed in the view that shows the data after the "grid display code" with
UI.getCurrent().removeWindow(showProgress);
来源:https://stackoverflow.com/questions/53814542/vaadin-8-how-to-show-progressbar-window-before-navigating-to-other-view-with-lo