Мой полный графический интерфейс работает внутри потока AWT, потому что я запускаю главное окно, используя SwingUtilities.invokeAndWait(...)
.
Теперь у меня есть JDialog, который должен просто отобразить JLabel
, который указывает, что определенное задание выполняется, и закрыть это диалоговое окно после того, как задание было завершено.
Проблема в том, что метка не отображается. Эта работа, кажется, была начата до того, как JDialog
был полностью выложен.
Когда я просто позволяю диалоговому окну открываться, не дожидаясь задания и не закрывая, отображается метка .
Последнее, что диалог делает в своем ctor, это setVisible(true)
.
Такие вещи, как revalidate()
, repaint()
, ... тоже не помогают.
Даже когда я запускаю поток для отслеживаемого задания и жду его, используя someThread.join()
, это не помогает, потому что текущий поток (который является потоком AWT) заблокирован join
, я полагаю.
Замена JDialog
на JFrame
тоже не помогает.
Итак, концепция вообще неверна? Или я могу сделать это для выполнения определенной работы после , когда JDialog
(или JFrame
) полностью выложен?
Упрощенный алгоритм того, чего я пытаюсь достичь:
- Создать подкласс
JDialog
- Убедитесь, что он и его содержимое полностью выложены
- Запустите процесс и дождитесь его завершения (с резьбой или нет, не имеет значения)
- Закрыть диалоговое окно
Мне удалось написать воспроизводимый контрольный пример:
РЕДАКТИРОВАТЬ Задача из ответа теперь решается:
В этом сценарии использования отображается метка, но она не закрывается
после "смоделированного процесса" из-за модальности диалога.
import java.awt.*;
import javax.swing.*;
public class _DialogTest2 {
public static void main(String[] args) throws Exception {
SwingUtilities.invokeAndWait(new Runnable() {
final JLabel jLabel = new JLabel("Please wait...");
@Override
public void run() {
JFrame myFrame = new JFrame("Main frame");
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myFrame.setSize(750, 500);
myFrame.setLocationRelativeTo(null);
myFrame.setVisible(true);
JDialog d = new JDialog(myFrame, "I'm waiting");
d.setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
d.add(jLabel);
d.setSize(300, 200);
d.setLocationRelativeTo(null);
d.setVisible(true);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(3000); // simulate process
jLabel.setText("Done");
} catch (InterruptedException ex) {
}
}
});
d.setVisible(false);
d.dispose();
myFrame.setVisible(false);
myFrame.dispose();
}
});
}
}