Natalie
Natalie

Reputation: 471

Vaadin 8: How to show ProgressBar window before navigating to other view with long loading

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!

Upvotes: 0

Views: 1091

Answers (3)

Natalie
Natalie

Reputation: 471

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);

Upvotes: 0

Laurent de Laprade
Laurent de Laprade

Reputation: 15

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

Upvotes: 0

Tatu Lund
Tatu Lund

Reputation: 10643

I would recommend to watch the excellent tutorial by Alejandro about the topic.

Upvotes: 1

Related Questions