我是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();下载完成后,我尝试删除所有内容。但它没有效果。
问题:
更新
我发现如果我通过另一个按钮调用方法表单,请点击:
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);
}
所有学分归于那些通过他/她的宝贵信息给我提示的人。
答案 0 :(得分:0)
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()
.