如果长时间运行的任务在Event Dispatch Thread
(EDT) 上执行,则对话框可能没有机会自行绘制/重绘,直到任务完成。有关 EDT 的更多详细信息,请查看Swing 中的并发教程。
这是一个使用您的代码的示例,它演示了行为不端的对话框:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class TestDialog {
private static void createAndShowGUI() {
final JFrame frame = new JFrame("Demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton button = new JButton("Execute");
button.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
final JDialog dialog = new JDialog((JFrame)frame, "blabla");
dialog.setLayout(new BorderLayout());
JLabel label = new JLabel("more blabla");
dialog.getContentPane().add(label, BorderLayout.CENTER);
dialog.setSize(new Dimension(280, 80));
dialog.setLocationRelativeTo(frame);
dialog.setVisible(true);
try {
Thread.sleep(3000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
dialog.setVisible(false);
dialog.dispose();
}
});
frame.add(button);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
考虑通过在工作线程上执行长时间运行的任务来重构您的实现。例如,您可以使用SwingWorker来实现。
这是一个演示,用一个简单的工作人员说明了相同的对话框:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingWorker;
public class TestDialogWithWorker {
private static void createAndShowGUI() {
final JFrame frame = new JFrame("Demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton button = new JButton("Execute");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
new Worker(frame).execute();
}
});
frame.add(button);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
static class Worker extends SwingWorker<Void, Void> {
JDialog dialog;
public Worker(JFrame parent) {
dialog = new JDialog((JFrame) parent, "blabla");
dialog.setLayout(new BorderLayout());
JLabel label = new JLabel("more blabla");
dialog.getContentPane().add(label, BorderLayout.CENTER);
dialog.setSize(new Dimension(280, 80));
dialog.setLocationRelativeTo(parent);
dialog.setVisible(true);
}
@Override
protected Void doInBackground() throws Exception {
Thread.sleep(3000);
return null;
}
@Override
protected void done() {
dialog.setVisible(false);
dialog.dispose();
try {
get();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}