Vaadin 8.1 : button looses CSS after ui.push

Hi
I implemented a component named WaitingButton to display a progress bar after clicked on button, waiting for a job to finish. At the end, button comes back to its original display. This is done hiding and displaying two distinct components: a button and a progressbar, kept inside a HorizontalLayout.
This work good in Vaadin 8.0, but with Vaadin 8.1, after the job ends, button is displayed without CSS and icon.

The Component class is:[code]
public class WaitingButton extends CustomComponent {
private static final String DEFAULT_STYLE = “friendly small”;
private Button commandBtn;
private ProgressBar waitingBar;
private HorizontalLayout hl;

public WaitingButton() {
hl = new HorizontalLayout();
commandBtn = new Button();
hl.addComponent(commandBtn);
waitingBar = new ProgressBar();
waitingBar.setIndeterminate(true);
waitingBar.setVisible(false);
waitingBar.addStyleName(“inline”);
waitingBar.setCaption(BaseUI.translate(“waiting.reading”));
hl.addComponent(waitingBar);
setCompositionRoot(hl);
}

public void addClickListener(ClickListener listener) {
commandBtn.addClickListener(event → {
commandBtn.setVisible(false);
waitingBar.setVisible(true);
UI ui = UI.getCurrent();
ui.push();
ui.access(() → {
try {
// waiting response
Thread.sleep(500);
} catch (Exception e) {
log.debug(e.getMessage(), e);
}
listener.buttonClick(event);
commandBtn.setVisible(true);
waitingBar.setVisible(false);
ui.push();
});
});
}
[/code]The click listener is wrapped by another listener, to get control back to client.

With Vaadin 8.1 the HTML first display the button well (first attachement) then after finish is like second attachement.

As HTML I get this for button ok

<tr class="v-formlayout-row">

[code]

Aggiorna validità
[/code]And this after push
<tr class="v-formlayout-row">
<td class="v-formlayout-captioncell">
<div class="v-caption"/>
</td>
<td class="v-formlayout-errorcell">
<div class="v-formlayout-error-indicator"/>
</td>
<td class="v-formlayout-contentcell">
<div class="v-customcomponent v-widget v-has-width" style="width: 100%;">
<div class="v-horizontallayout v-layout v-horizontal v-widget">
<div class="v-slot">
<div tabindex="0" role="button" class="v-button v-widget">
<span class="v-button-wrap">
<span class="v-button-caption"/>
</span>
</div>
</div>
</div>
</div>
</td>
</tr>

Any suggestion?
Thanks.
34116.png
34117.png

There is something a bit strange in the use of UI.push() and UI.access() in your test. I tried with the latest master (close to 8.1.1) and slightly modified code, and wasn’t able to reproduce the issue.

UI:

@Push ... WaitingButton waitingButton = new WaitingButton(); addComponent(waitingButton); waitingButton.addClickListener(event -> System.out.println("Click handled")); WaitingButton:

public class WaitingButton extends CustomComponent {
    private static final String DEFAULT_STYLE = "friendly small";
    private Button commandBtn;
    private ProgressBar waitingBar;
    private HorizontalLayout hl;

    public WaitingButton() {
        hl = new HorizontalLayout();
        commandBtn = new Button();
        commandBtn.addStyleName(DEFAULT_STYLE);
        hl.addComponent(commandBtn);
        waitingBar = new ProgressBar();
        waitingBar.setIndeterminate(true);
        waitingBar.setVisible(false);
        waitingBar.addStyleName("inline");
        waitingBar.setCaption("waiting.reading");
        hl.addComponent(waitingBar);
        setCompositionRoot(hl);
    }

    public void addClickListener(ClickListener listener) {
        commandBtn.addClickListener(event -> {
            commandBtn.setVisible(false);
            waitingBar.setVisible(true);
            UI ui = UI.getCurrent();
            Runnable runnable = new Runnable() {
                public void run() {
                    try {
                        // waiting response
                        Thread.sleep(2000);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    ui.access(() -> {
                        listener.buttonClick(event);
                        commandBtn.setVisible(true);
                        waitingBar.setVisible(false);
                        ui.push();
                    });
                }
            };
            new Thread(runnable).start();
        });
    }
}

Thank you Henri! Adding the new Thread solved this problem. In other parts of the application I followed this pattern, but here it was missing.
One question remains unaswered: why my bad code run correctly in Vaadin 8.0 ?

There were some changes in the cleanup of unused component connectors etc. at the end of a request, and the old way was probably skipping a check (and potentially a warning) in that case. Perhaps that caused the difference in behavior.

Note that in modern application servers, explicitly creating threads is not recommended (with EJBs it is even explicitly forbidden by the spec) and one should use a suitable ExecutorService (e.g. with a thread pool) instead to let the container manage threads. My quick test used a new thread for brevity.