Vaadin 几个基本问​​题来操作几个小部件

Vaadin couple of basic quesions to manipulate few widgets

我是 Vaadin 的新手。我正在尝试操作以下小部件。

private VerticalLayout layout;
ProgressBar bar = new ProgressBar(0.0f);
Button downLoadButton;

private void setupLayout() {
    layout = new VerticalLayout();
    layout.setDefaultComponentAlignment(Alignment.MIDDLE_CENTER);
    setContent(layout);
}

private void setStockDownloadUI() {
    TextField tf = new TextField("Downloading");
    tf.setValue("Downloading stock data. It takes about 15 seconds.");
    tf.setWidth("400");
    tf.setVisible(false);
    layout.addComponent(tf);
    bar.setHeight("100");
    bar.setWidth("500");
    bar.setIndeterminate(true);
    bar.setVisible(false);
    layout.addComponent(bar);
    Page.getCurrent().reload();
    downLoadButton = new Button("Start download", click -> {
        tf.setVisible(true);
        bar.setVisible(true);
        float current = bar.getValue();
        if (current < 1.0f)
            bar.setValue(current + 0.10f);
        stockService.downloadStockContent();
        startTimer();
        Notification.show("Downloading",
                "Stock data downloading. Please wait.",
                Notification.Type.TRAY_NOTIFICATION);
    });
    downLoadButton.addStyleName("huge");
    layout.addComponent(downLoadButton);
}


 void checkDownloadStatus() {
    stockElements = callBack.getDownloadedStock();
    if (stockElements != null && stockElements.size() != 0) {
        MessageBox
                .createInfo()
                .withCaption("Example 1")
                .withMessage("Hello World!")
                .withOkButton()
                    .open();
        bar.setVisible(false);

        layout.removeAllComponents();
        timer.shutdownNow();
        for (StockElement element : stockElements) {
            System.out.println(element.toString());
        }
    }
}

有几个问题。我正在从网上下载一些内容。首先,我通过 setStockDownloadUI() 设置了 UI。我在哪里设置进度条。下载完成后,我调用 checkDownloadStatus()。在那里我想隐藏进度条。此外,当单击一次下载按钮时,我想禁用它。这样它就不会被点击两次。

在 checkDownloadStatus() 中,我创建了一个永远不会在浏览器中显示的消息框。另外,我打电话给 layout.removeAllComponents();下载完成后,我尝试删除所有内容。但它没有效果。

问题:

  1. 点击一次后如何禁用按钮?
  2. 如何在下载完成后删除VerticalLayout 中的进度条甚至所有组件?
  3. 如何显示消息框?

更新

我发现如果我从另一个按钮调用方法,请单击:

workaroundButton = new Button("Work around", click -> {
    this.bar.setVisible(false);
    this.layout.removeComponent(bar);
    this.layout.removeComponent(downLoadButton);
    this.layout.removeComponent(textField);
    layout.removeAllComponents();
});

然后就可以了。但如果我只是从我自己的回调方法中调用这些方法,它就不起作用了。但这是不可接受的。我相信我的代码中遗漏了一些东西。

更新 2

答案后,我尝试了以下代码。即使我通过调试器设置了一个断点,它也永远不会命中 bp。所以代码从未被执行过。我错过了什么吗?我正在尝试通过计时器检查下载状态。

 @Push
 @Theme("mytheme")
 public class StockApplication extends UI {
   // code removed. 
 }


private void startTimer() {
    ScheduledExecutorService timer = Executors.newSingleThreadScheduledExecutor();
    timer.scheduleWithFixedDelay(new Runnable() {
        public void run() {
            UI.getCurrent().access((() -> {
                // breakpoint never hit this book of code
                       MessageBox
                        .createInfo()
                        .withCaption("Wait")
                        .withMessage("Still downloading stock contents. Please check again  after a while")
                        .withOkButton(() -> System.out.println("Ok pressed."))
                        .open();
                checkDownloadStatus();}));

        }
    }, 1, 1, TimeUnit.SECONDS);
}

怎么了?请让我知道我该如何解决?

我可以用下面的代码修复它:-

private void startTimer() {
    UI ui = UI.getCurrent();
    timer.scheduleWithFixedDelay(new Runnable() {
        public void run() {
            ui.access((() -> {
                checkDownloadStatus();}));
        }
    }, 1, 1, TimeUnit.SECONDS);
}

所有学分都归功于通过 his/her 宝贵信息给我提示的人。

  1. 第一个问题很简单 - downLoadButton.setDisableOnClick(true)

2+3。我们在这里谈论 Vaadin Push。正如您所注意到的,默认情况下,如果更改是由浏览器触发的,则 Vaadin 组件的更新只会返回浏览器(例如,单击上面的 workaroundButton)。要将未经请求的更新发送回浏览器,您需要启用推送,它在后台使用 Websocket 以允许浏览器继续接收更新。

上面的 link 解释了如何为您的 UI 启用推送。

启用推送后,它非常灵巧 - 您可以像往常一样操作小部件,并且更改仍然会返回到浏览器。您只需要记住将这些更新包装在 UI.access() 中以确保您拥有会话锁。例如。 :

ui.access(() -> checkDownloadStatus());

ui 只是您的 UI class,或者您可以通过 widget.getUI().

从任何小部件访问它