Vaadin 对话框在方法执行之后而不是之前打开
Vaadin Dialog is opened after a method execution instead of before
当我单击一个按钮时,我想做两件事:首先,打开一个对话框,其次,执行一个方法(在 jar 文件中)。问题是,当我单击按钮时,首先执行该方法,然后打开对话框。代码是这样的:
button.addClickListener(event -> start());
public void start() {
dialog.open(); //Second, it opens the Dialog
methodInJar(); //First it executes this method
}
注意:无论是Dialog、Notification还是界面的任何变化,都会发生同样的事情。
有谁知道问题出在哪里?
谢谢。
PD。这是整个class:
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 完全完成之后。而且因为在整个点击监听器期间,UI 被锁定,你甚至不能在点击监听器期间执行 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();
}
}
}
文档:
@Push
Asynchronous Updates
一般来说,您应该在后台线程中执行任何可能需要一段时间的任务,以避免锁定 UI。
当我单击一个按钮时,我想做两件事:首先,打开一个对话框,其次,执行一个方法(在 jar 文件中)。问题是,当我单击按钮时,首先执行该方法,然后打开对话框。代码是这样的:
button.addClickListener(event -> start());
public void start() {
dialog.open(); //Second, it opens the Dialog
methodInJar(); //First it executes this method
}
注意:无论是Dialog、Notification还是界面的任何变化,都会发生同样的事情。
有谁知道问题出在哪里?
谢谢。
PD。这是整个class:
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 完全完成之后。而且因为在整个点击监听器期间,UI 被锁定,你甚至不能在点击监听器期间执行 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();
}
}
}
文档:
@Push
Asynchronous Updates
一般来说,您应该在后台线程中执行任何可能需要一段时间的任务,以避免锁定 UI。