安全地打开和关闭模态JDialog(使用SwingWorker)

我需要一种方法从数据库中获取一些数据,并阻止用户修改当前的现有数据。

我创建了一个SwingWorker来进行数据库更新,并创建了一个模态JDialog来向用户显示正在发生的事情(使用JProgressBar)。 modal dialog的defaultCloseOperation设置为DO_NOTHING,因此只能通过正确的调用关闭 – 我使用setVisible(false)

 MySwingWorkerTask myTask = new MySwingWorkerTask(); myTask.execute(); myModalDialog.setVisible(true); 

SwingWorker在doInBackground()中执行一些操作,最后调用:

 myModalDialog.setVisible(false); 

我唯一担心的问题是:在工作人员生成之后,SwingWorker可能会在setVisible(false)之前执行setVisible(false)吗?

如果是这样, setVisible(true)可能永远阻塞(用户无法关闭模态窗口)。

我必须实现以下内容:

 while (!myModalDialog.isVisible()) { Thread.sleep(150); } myModalDialog.setVisible(false); 

确保它实际上会被关闭?

一般来说,是的。

我要做的是在你的doInBackground方法中使用SwingUtilities.invokeLater来显示对话框并在你的done方法中隐藏对话框。

这应该意味着即使对话框没有进入屏幕,您也可以获得对流量的更多控制……

小问题是你现在必须将对话框传递给工人,以便它可以控制它…

 public class TestSwingWorkerDialog { public static void main(String[] args) { new TestSwingWorkerDialog(); } private JDialog dialog; public TestSwingWorkerDialog() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException ex) { } catch (InstantiationException ex) { } catch (IllegalAccessException ex) { } catch (UnsupportedLookAndFeelException ex) { } MyWorker worker = new MyWorker(); worker.execute(); } }); } public class MyWorker extends SwingWorker { @Override protected Object doInBackground() throws Exception { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { getDialog().setVisible(true); } }); Thread.sleep(2000); return null; } @Override protected void done() { System.out.println("now in done..."); JDialog dialog = getDialog(); // Don't care, dismiss the dialog dialog.setVisible(false); } } protected JDialog getDialog() { if (dialog == null) { dialog = new JDialog(); dialog.setModal(true); dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); dialog.setLayout(new BorderLayout()); dialog.add(new JLabel("Please wait...")); dialog.setSize(200, 200); dialog.setLocationRelativeTo(null); } return dialog; } }