为什么在模态对话框关闭之前不会调用done()?

时间:2014-04-13 19:25:39

标签: java multithreading swing modal-dialog swingworker

在下面的示例中,尝试在工作人员启动时打开对话框并在工作人员端关闭它。

不幸的是,在手动关闭对话框之前,不会执行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();

            }
        });


    }

}

1 个答案:

答案 0 :(得分:4)

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

相反,我在这里做:

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