我需要一种方法从数据库中获取一些数据,并阻止用户修改当前的现有数据.
我创建了一个SwingWorker来进行数据库更新,并创建了一个模态JDialog来向用户显示正在发生的事情(使用JProgressBar).模态对话框的defaultCloSEOperation设置为DO_NOTHING,因此只能通过正确的调用关闭它 – 我使用setVisible(false).
MySwingWorkerTask myTask = new MySwingWorkerTask(); myTask.execute(); myModalDialog.setVisible(true);
SwingWorker在doInBackground()中执行一些操作,最后调用:
myModalDialog.setVisible(false);
我唯一担心的问题是:
SwingWorker是否可能在worker生成后的行中setVisible(true)之前执行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<Object,Object> { @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; } }