1 回答
TA贡献1831条经验 获得超4个赞
是的,callSeriallyAndWait相当于SwingUtilities.invokeAndWait. 没有逻辑上的区别。
这可以工作,但这里有一些问题......首先:
如果两个线程同时显示这样的对话框怎么办?第一个对话框将显示第二个对话框,而第二个对话框可能会显示无限循环中的第一个对话框...即使您实际在 EDT 上,这种情况也可能发生,因为代码不是正常应用程序流程的一部分。
与 Swing 不同,我们一次只有一个Form对话框,因此对话框会“返回”,这可能会变得很棘手。
因此,首先,您的 GUI 代码需要检查您当前是否没有请求 pin,最好的方法是让一个类负责在必要时从用户那里获取 pin,并且它应该具有静态状态。如果还应该检查此时是否没有其他对话框显示,如果是这样,它可能希望避免显示,例如:
if(getCurrentForm() instanceof Dialog) {
// ... don't show yet
}
如果我正确理解您的问题,您有可能需要引脚的后台线程。在这种情况下,可能会捕获多个没有 pin 的线程,并且需要从 GUI 获取它。因此,两个线程都需要挂起,但只有其中一个线程应该调用callSeriallyAndWait...这意味着当前的方法无论如何都是低于标准的。
通常我们会避免这样做callSeriallyAndWait,因为它慢得多(在 Swing 上也是如此)。我还会使用一个InteractionDialog或类似的对话框,它比常规对话框的侵入性较小。然而,它不是模态的。但在这种情况下,这应该不重要。
您需要为后台线程开发自己的线程阻塞代码,它可以对标准回调做出反应以释放所有等待的后台线程。然后,您可以使用想要创建 GUI 的任何代码并使用任何侦听器,然后使用新 pin 更新类中的共享状态,并调用以唤醒等待notifyAll()pin 的线程。例如
synchronized(LOCK) {
if(pin == null && !dialogIsShowing) {
dialogIsShowing = true;
callSerially(() -> promptForPin());
}
while(pin == null) {
LOCK.wait();
}
}
然后是UI逻辑:
private void onUserSubmittedPin(String pin) {
synchronized(LOCK) {
this.pin = pin;
dialogIsShowing = false;
LOCK.notifyAll();
}
}
添加回答
举报