SwingWorker,未调用done()方法

这只是SwingWorker的一个实现:

class GuiWorker extends SwingWorker { private JFrame frame = new JFrame(); private JDialog dialog = new JDialog(frame, "Loadin data", true); private JProgressBar progressBar = new JProgressBar(); private Statistics st = new Statistics(); public GuiWorker(GraphEditor editor, Statistics st) { this.st = st; Window mainWindow = SwingUtilities.windowForComponent(editor .getGraphComponent().getParent()); dialog.setSize(400, 200); int x = mainWindow.getX() + (mainWindow.getWidth() - dialog.getWidth()) / 2; int y = mainWindow.getY() + (mainWindow.getHeight() - dialog.getHeight()) / 2; progressBar.setString("Have fun to wait some time..."); progressBar.setStringPainted(true); progressBar.setIndeterminate(true); dialog.add(progressBar); dialog.setModal(true); dialog.setLocation(x, y); dialog.setVisible(true); } @Override protected Integer doInBackground() throws Exception { st.loadInitialData(); return 0; } @Override protected void done() { dialog.setVisible(false); JLabel label = new JLabel("Task Complete"); dialog.getContentPane().remove(progressBar); dialog.getContentPane().add(label); dialog.getContentPane().validate(); dialog.setVisible(false); } } 

diaglog永远不会隐藏的问题,直到我强行关闭它(任务结束时必须隐藏)。 我注意到loadInitialData()方法是一种从我的DB收集一些统计信息的方法,需要几秒钟。

更新 :我确信在关闭dialog时调用done()方法。

更新 :我在哪里使用GuiWorker在这里:

 mainTabs.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { switch (mainTabs.getSelectedIndex()) { case 0: case 1: case 2: // stats tab GuiWorker gw = new GuiWorker(editor,st); gw.execute(); break; default: break; } } }); 

所有swing事件都在Event Dispatch Thread中运行。 因此,您添加到mainTabsChangeListener将在Event Dispatch Thread中运行。

在事件监听器中,您实例化GuiWorker并在该构造函数中通过调用dialog.setVisible(true);打开对话框dialog.setVisible(true);

您的JDialog实例是modal并且在模式对话框上调用setVislbe(true)将阻止调用线程,在您的情况下是事件调度线程。 所以在对话框关闭之前, gw.execute(); 不叫。 这就是为什么在关闭对话框之前不会调用done方法的原因。

为了使代码正常工作,您可以尝试不在构造函数中调用setVisible(true) ,而是从GuiWorker提供一个方法来设置对话框的可见性。 然后调用gw.execute(); 调用gw.setVisible(true)

澄清一下,试试吧

 class GuiWorker extends SwingWorker { private JFrame frame = new JFrame(); private JDialog dialog = new JDialog(frame, "Loadin data", true); private JProgressBar progressBar = new JProgressBar(); private Statistics st = new Statistics(); public GuiWorker(GraphEditor editor, Statistics st) { this.st = st; Window mainWindow = SwingUtilities.windowForComponent(editor .getGraphComponent().getParent()); dialog.setSize(400, 200); int x = mainWindow.getX() + (mainWindow.getWidth() - dialog.getWidth()) / 2; int y = mainWindow.getY() + (mainWindow.getHeight() - dialog.getHeight()) / 2; progressBar.setString("Have fun to wait some time..."); progressBar.setStringPainted(true); progressBar.setIndeterminate(true); dialog.add(progressBar); dialog.setModal(true); dialog.setLocation(x, y); } @Override protected Integer doInBackground() throws Exception { st.loadInitialData(); return 0; } @Override protected void done() { dialog.setVisible(false); JLabel label = new JLabel("Task Complete"); dialog.getContentPane().remove(progressBar); dialog.getContentPane().add(label); dialog.getContentPane().validate(); dialog.setVisible(false); } public void setVisible(boolean visible) { dialog.setVisible(visible); } } 

 mainTabs.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { switch (mainTabs.getSelectedIndex()) { case 0: case 1: case 2: // stats tab GuiWorker gw = new GuiWorker(editor,st); gw.execute(); gw.setVisible(true); break; default: break; } } });