Vaadin对话框在方法执行之后而不是之前打开

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

当我点击一个按钮时,我想做两件事:第一,打开一个对话框,第二,执行一个方法(在jar文件中)。问题是,当我单击按钮时,首先执行方法,然后打开对话框。代码如下所示:

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更新。从后台线程访问
。这很有效!谢谢你的研究和帮助。我非常感激。