Vaadin 23.2.8打开多ConfirmDialog异常:应用冻结而非层级显示
问题分析
你的代码连续调用ConfirmDialog.open()后出现应用冻结,核心原因是open()方法是阻塞式的——它会暂停当前线程,必须等用户关闭对话框后才会继续执行后续代码。第一个对话框还未关闭时就调用第二个的open(),线程会被双重阻塞,直接导致应用无响应,自然无法显示第二个对话框。
解决方案
要实现层级显示两个对话框,需避免线程被连续阻塞,以下是两种可行方案:
方案1:通过确认事件触发第二个对话框
在第一个对话框的确认回调中打开第二个,确保第一个对话框关闭后再加载第二个:
ConfirmDialog dialog = new ConfirmDialog(); dialog.setCloseOnEsc(false); dialog.setHeader("ok"); dialog.setConfirmText("ok"); dialog.setText("ok"); // 监听确认事件,打开第二个对话框 dialog.addConfirmListener(e -> { ConfirmDialog dialog1 = new ConfirmDialog(); dialog1.setCloseOnEsc(false); dialog1.setHeader("ok1"); dialog1.setConfirmText("ok1"); dialog1.setText("ok1"); dialog1.open(); }); dialog.open();
方案2:异步触发第二个对话框
如果不需要等待用户确认第一个对话框,而是要异步加载第二个,可通过UI.getCurrent().accessAsync()避免线程阻塞:
ConfirmDialog dialog = new ConfirmDialog(); dialog.setCloseOnEsc(false); dialog.setHeader("ok"); dialog.setConfirmText("ok"); dialog.setText("ok"); dialog.open(); // 异步打开第二个对话框 UI.getCurrent().accessAsync(() -> { ConfirmDialog dialog1 = new ConfirmDialog(); dialog1.setCloseOnEsc(false); dialog1.setHeader("ok1"); dialog1.setConfirmText("ok1"); dialog1.setText("ok1"); dialog1.open(); });
关键提示
ConfirmDialog.open()的阻塞特性是设计使然,用于同步获取用户交互结果,连续调用必然引发线程死锁。- 采用事件回调或异步方式,既能保证对话框按层级显示,又能避免应用冻结。
内容的提问来源于stack exchange,提问作者Fabiano Costa Leite
相关产品推荐
相关产品推荐

