2014-04-13 43 views
1

在下面的例子,试图发开的工人开始对话,并关闭它在工人结束。为什么()完成不叫,直到模式对话框关闭?

不幸的是,不执行done()直到对话框手动关闭。

为什么?

package tests.javax.swing; 

import java.awt.FlowLayout; 
import java.awt.event.ActionEvent; 
import java.beans.PropertyChangeEvent; 
import java.beans.PropertyChangeListener; 

import javax.swing.AbstractAction; 
import javax.swing.JButton; 
import javax.swing.JDialog; 
import javax.swing.JFrame; 
import javax.swing.JOptionPane; 
import javax.swing.SwingUtilities; 
import javax.swing.SwingWorker; 

import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 

public class Try_SwingWorker_Modality { 

    private static final Logger log = LoggerFactory.getLogger(Try_SwingWorker_Modality.class); 

    public static void main(String[] args) { 

     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 





       AbstractAction popupAction = new AbstractAction("popup") { 

        @Override 
        public void actionPerformed(ActionEvent e) { 
         JOptionPane.showMessageDialog(null, "popup"); 
        } 

       }; 

       final JDialog dialog = new JDialog((JFrame)null, true); 
       dialog.setLayout(new FlowLayout()); 
       dialog.add(new JButton(popupAction)); 


       dialog.pack(); 
       dialog.setLocationRelativeTo(null); 



       SwingWorker<Object,Object> swingWorker = new SwingWorker<Object,Object>() { 

        @Override 
        protected Object doInBackground() throws Exception { 
         log.debug("doInBackground()"); 
         return null; 
        } 

        @Override 
        protected void done() { 
         log.debug("done"); 
         //dialog.dispose(); 
        } 

       }; 

       swingWorker.addPropertyChangeListener(new PropertyChangeListener() { 

        @Override 
        public void propertyChange(PropertyChangeEvent evt) { 
         log.debug("event = {}", evt); 
         if("state".equals(evt.getPropertyName())) { 
          if(SwingWorker.StateValue.STARTED == evt.getNewValue()) { 
           dialog.setVisible(true); 
           log.debug("after setVisible()"); 
          } 
          else if(SwingWorker.StateValue.DONE == evt.getNewValue()) { 
           dialog.dispose(); 
          } 
         } 
        } 
       }); 


       swingWorker.execute(); 

      } 
     }); 


    } 

} 

回答

4

您正在使用该代码冻结您的SwingWorker的PropertyChangeListener。我永远不会在PCL中设置可见的对话框。

相反,我会在这里做:

swingWorker.execute(); 
dialog.setVisible(true); 
+0

如何克服? –

+0

@SuzanCioc:开始执行SwingWorker后。请参阅编辑以回答。 –

+0

如果摆动工人有时间来完成执行设置可见之前这可能无法正常工作被调用。该对话框将显示,但从不隐藏。但是当工人结束时应该隐藏它。 –