猿问

如何在任何线程上从对话框中获取值?

我想知道这是否是从对话框中获取 PIN 的正确方法?


public static <T> T getFromGui(Supplier<T> supplier) {

    if (CN.isEdt()) return supplier.get();

    final Object[] holder = new Object[1];

    CN.callSeriallyAndWait(() -> holder[0] = supplier.get());

    @SuppressWarnings("unchecked") final T result = (T) holder[0];

    return result;

}


public static String askPin() {

    if (!CN.isEdt()) return getFromGui(() -> askPin(bankzugang));


    ...

    final boolean cont = Dialog.show(

        "Your PIN", BoxLayout.encloseY(pin, label), ok, cancel) == ok;

    return cont? pin.getText() : "";

}

它似乎有效(尝试过一次),但我有点困惑callSeriallyAndWait:它是 的模拟吗SwingUtilities.invokeAndWait?有什么区别?


实际上,我需要一些对话框才能在每个线程中工作,包括 EDT。有没有比上面添加“getFromGui”行更好的方法?


慕标琳琳
浏览 81回答 1
1回答

慕容708150

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

相关分类

Java
我要回答