Vaadin对话框在方法执行之后而不是之前打开
当我点击一个按钮时,我想做两件事:第一,打开一个对话框,第二,执行一个方法(在jar文件中)。问题是,当我单击按钮时,首先执行方法,然后打开对话框。代码如下所示:Vaadin对话框在方法执行之后而不是之前打开,vaadin,vaadin10,Vaadin,Vaadin10,当我点击一个按钮时,我想做两件事:第一,打开一个对话框,第二,执行一个方法(在jar文件中)。问题是,当我单击按钮时,首先执行方法,然后打开对话框。代码如下所示: button.addClickListener(event -> start()); public void start() { dialog.open(); //Second, it opens the Dialog methodInJar(); //First it executes t
button.addClickListener(event -> start());
public void start() {
dialog.open(); //Second, it opens the Dialog
methodInJar(); //First it executes this method
}
注意:无论是对话框、通知还是界面中的任何更改,都会发生相同的情况
有人知道问题出在哪里吗
多谢各位
警察局。这是全班同学:
package com.example.test;
import com.vaadin.flow.component.UI;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.dialog.Dialog;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.page.Push;
import com.vaadin.flow.router.Route;
@Route("myView")
@Push
public class MyView extends VerticalLayout {
private UI ui;
private Dialog dialog = new Dialog();
public MyView(){
addAttachListener(event -> {
this.ui = event.getUI();
});
add(new Button("some button", click -> start()));
}
private void start(){
this.ui.access(() -> {
dialog.open();
});
methodInJarTest();
}
private void methodInJarTest() {
try {
System.out.println("JAR test - 10 seconds pause");
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
任何UI更改都是在到服务器的整个往返过程完成之后执行的,在您的案例中,也就是在clickListener按钮完全完成之后。因为在整个clicklistener过程中,UI被锁定,所以在clicklistener过程中甚至不能执行
UI.access,因为这也需要UI锁定
这里您可以做的是让clicklistener启动一个新线程,在其中执行繁重的提升。这意味着clicklistener很快就完成了,因此释放了对UI的锁定。我们现在可以从仍在运行的后台线程中执行ui.access(…)
调用
下面是您的代码的外观
@Route("myView")
@Push
public class MyView extends VerticalLayout {
private UI ui;
private Dialog dialog = new Dialog();
public MyView(){
// save the ui instance when the view is attached for later reference
addAttachListener(event -> {
this.ui = event.getUI();
});
add(new Button("some button", click -> start()));
}
private void start(){
new Thread(() -> {
// UI.getCurrent() would return null in a new Thread, that's why we saved the ui instance during attach of the view.
ui.access(() -> dialog.open());
methodInJarTest();
}).start();
}
private void methodInJarTest() {
try {
System.out.println("JAR test - 10 seconds pause");
Thread.sleep(10000);
ui.access(() -> dialog.add(new Span("methodInJar completed")));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
文档:
一般来说,可以说您应该在后台线程中执行任何可能需要一段时间的任务,以避免锁定UI。Hi-kscherrer。谢谢你的快速回复。我在我的项目中遵循了您的指示,但不幸的是,问题仍然存在。我甚至用一个类和代码创建了一个Vaadin“我的初学者项目”,但结果还是一样的:一旦方法结束执行,它就会打开对话框。我正在使用Eclipse和Vaadin10+项目。当我创建项目时,技术堆栈是Spring boot。有什么想法吗?再次感谢。您能显示视图的代码吗?也许我那时就明白了问题所在。我在回答中写的代码应该可以用。当然,我已经编辑了我的原始问题。我正在一个只包含一个类的项目上测试您的代码。谢谢。我自己刚试过这个代码,它确实不起作用。我很困惑!显然,clicklistener会将ui完全锁定,直到完成,因此,ui.access
会被延迟,直到它能够锁定自己。解决方案是将繁重的操作放在一个异步/后台线程中,这样clicklistener会很快完成,然后您可以使用ui执行ui更新。从后台线程访问。这很有效!谢谢你的研究和帮助。我非常感激。