Да, callSeriallyAndWait
является эквивалентом SwingUtilities.invokeAndWait
. В этом нет логической разницы.
Это может сработать, но здесь есть несколько проблем ... Первое:
Что, если два потока одновременно показывают диалог, подобный этому. Первый будет отображать второй диалог, который может отображать первый диалог в бесконечном цикле ... Это может произойти, даже если вы физически находитесь на EDT, потому что код не является частью нормального потока приложения.
В отличие от Swing, у нас есть только один Form
за раз, поэтому диалог «возвращается», и это может быть сложно.
Итак, прежде всего ваш код GUI должен проверить, что вы нев настоящее время запрашивается пин-код, и лучший способ сделать это - иметь один класс, отвечающий за получение пин-кода от пользователя, если это необходимо, и он должен иметь статическое состояние. Если также следует проверить, что в это время нет другого диалогового окна, и если да, то может не показываться, например:
if(getCurrentForm() instanceof Dialog) {
// ... don't show yet
}
Если я правильно понимаю вашу проблему, у вас есть фоновые потоки, которые могут нуждаться в булавке. В этом случае более одного потока могут быть перехвачены без булавки, и это потребуется из графического интерфейса. Таким образом, оба потока должны быть приостановлены, но только один из них должен вызывать callSeriallyAndWait
... Это означает, что текущий подход в любом случае не соответствует требованиям.
Обычно мы избегаем callSeriallyAndWait
, поскольку он намного медленнее (на Swing тоже). Я бы также использовал InteractionDialog
или аналогичный, который менее навязчив, чем обычный диалог. Тем не менее, это не модально. Но в этом случае это не должно иметь значения.
Вам необходимо разработать собственный код блокировки потоков для фоновых потоков, и он может реагировать на стандартный обратный вызов, чтобы освободить все ожидающие фоновые потоки. Затем вы можете просто использовать любой код, который вы хотите создать в GUI, и использовать любой слушатель, затем обновить общее состояние в классе с помощью нового вывода и вызвать notifyAll()
, чтобы разбудить потоки, ожидающие вывода. Например,
synchronized(LOCK) {
if(pin == null && !dialogIsShowing) {
dialogIsShowing = true;
callSerially(() -> promptForPin());
}
while(pin == null) {
LOCK.wait();
}
}
Тогда логика интерфейса:
private void onUserSubmittedPin(String pin) {
synchronized(LOCK) {
this.pin = pin;
dialogIsShowing = false;
LOCK.notifyAll();
}
}