【发布时间】:2010-12-27 09:10:33
【问题描述】:
我的完整 GUI 在 AWT 线程中运行,因为我使用 SwingUtilities.invokeAndWait(...) 启动主窗口。
现在我有一个 JDialog,它只显示一个 JLabel,这表明某个工作正在进行中,并在工作完成后关闭该对话框。
问题是:标签不显示。这项工作似乎在JDialog 完全布局之前就开始了。
当我让对话框打开而不等待作业并关闭时,标签 会显示出来。
对话框在其 ctor 中做的最后一件事是 setVisible(true)。
诸如revalidate()、repaint()、...之类的东西也无济于事。
即使我为受监控的作业启动一个线程,并使用someThread.join() 等待它也无济于事,因为我猜,当前线程(即 AWT 线程)被join 阻塞了。
将JDialog 替换为JFrame 也无济于事。
那么,这个概念总体上是错误的吗?或者我可以在确保JDialog(或JFrame)完全布局之后完成某些工作吗?
我想要实现的简化算法:
- 创建
JDialog的子类 - 确保它及其内容完全布局
- 启动一个进程并等待它完成(线程与否,无关紧要)
- 关闭对话框
我设法编写了一个可重现的测试用例:
EDIT 现在解决了来自答案的问题: 此用例确实显示标签,但无法关闭 在“模拟过程”之后,因为对话的形式。
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();
}
});
}
}
【问题讨论】:
-
请添加您启动挥杆组件的代码段。
-
我真的不明白问题出在哪里。如果您的应用程序在线程内运行,那么您只需从中显示 JDialog,然后使用 JDialog 作为作业的参数启动您的作业(也从线程)。像这样的东西: JDialog myDialog = ....;启动我的工作(我的对话);该过程完成后,从作业中关闭 JDialog。对于您的标签问题,正如 Amjad 所说,您应该展示如何实例化您的 JDialog 及其组件。
标签: java multithreading events swing awt