Vaadin几个基本的问题来操纵一些小部件

时间:2018-03-25 09:12:30

标签: java vaadin vaadin8

我是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. 如何显示消息框?
  4. 更新

    我发现如果我通过另一个按钮调用方法表单,请点击:

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

    所有学分归于那些通过他/她的宝贵信息给我提示的人。

1 个答案:

答案 0 :(得分:0)

  1. The first question is the easy one - downLoadButton.setDisableOnClick(true)

2+3. We're talking about Vaadin Push here. As you've noticed, by default an update to a Vaadin component will only make it back to the browser if that change was triggered by the browser (e.g. clicking workaroundButton above). To send an unsolicited update back to the browser you will need push enabled, which uses a Websocket behind the scenes to allow the browser to continue receiving updates.

The link above explains how to enable push for your UI.

Once push is enabled, it's very slick - you can manipulate widgets as normal and the changes still find their way back to the browser. You just need to remember to wrap those updates in UI.access() to ensure you have the session lock. E.g. :

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

The ui is just your UI class, or you can get to it from any widget with widget.getUI().