Using Threads to Update UI in Vaadin 14

Viewed 701

I created a thread (via a lambda expression) to fetch some data based on user input fields but when I try to click on dropdown menus while it is retrieving data I get the mini progress bar indicator. So is a new thread even being created? What am I doing wrong here?

Button doComputation = new Button("Get Results);
doComputation.addClickListener(event -> {
        UI ui = UI.getCurrent();
        new Thread(() -> {
             
             // Do some work
             ui.access(() -> layout.add(results);

        }).start();
});

UPDATE: RESOLVED! Unneccesary ui.access calls were made, which locked up resources. Thank you to all that commented and helped.

2 Answers

The code looks correct to me (apart from the missing end parenthesis after ui.access). Is that the only ui.access call, and is that all you do inside it?

I made this example for reference, and the combo box stays responsive while the background task is running.

@Route
public class ThreadView extends VerticalLayout {

    public ThreadView() {
        Button runThreadButton = new Button("Start thread", e -> {
            UI ui = UI.getCurrent();
            new Thread(() -> {
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
                ui.access(() -> Notification.show("Completed"));
            }).start();
        });
        ComboBox<String> comboBox = new ComboBox<>("Items", "One", "Two", "Three");
        add(runThreadButton, comboBox);
    }
}

So is a new thread even being created?

You can verify that by adding a System.out.println("Thread started") and checking whether that message is printed, or by running your application in debug mode and setting a breakpoint on the part that you're interested in.

What am I doing wrong here?

The code that you showed looks fine. I would guess there's a problem outside the shown code, namely that you have forgotten that you also need to add the @Push annotation. Without that annotation, the server will have no way of directly sending messages to the client.

Related