在invokelater中两次调用JFileChooser会导致程序不退出

时间:2015-11-18 18:57:10

标签: java swing event-dispatch-thread invokelater

我正在编写一个程序来从两个文本文件中收集信息以添加到数据库中的表中。为了允许用户选择他自己的文件,我创建了一个名为chooseFile()的非静态方法,该方法使用JFileChooser类来呈现showOpenDialog(我也尝试过它作为静态结果相同的方法。如果这听起来像我在猜测,那你就是对的 - 我对编程只是如此。

我的理解是main()中对Swing类的调用应该使用invokelater来完成。对于chooseFile()的一次调用,这一切都运行正常(JVM成功退出),但是当我向chooseFile()添加第二次调用时,JVM会无限期地继续运行。但是,如果我在不使用chooseFile()的情况下调用invokelater,则程序会正常退出。在System.exit(0)中第二次调用后添加invokelater也允许程序正常退出。

从我能够收集的内容来看,在关闭所有(非守护进程)线程之前,程序不会退出。但是,我认为使用invokelater的目的是将所有非线程安全的Swing相关活动推送到EDT上。在这里使用System.exit(0)是最好的做法还是我还应该知道其他什么?

这是我的SSCCE:

package ptMngr;

import java.io.IOException;
import java.nio.file.Path;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileNameExtensionFilter;

public class ParticipantManager {

    private Path chooseFile() throws IOException{
        JFileChooser chooser = new JFileChooser();
        FileNameExtensionFilter filter = new FileNameExtensionFilter("Text Files", "txt","csv");
        chooser.setFileFilter(filter);
        int returnVal = chooser.showOpenDialog(null);
        if(returnVal == JFileChooser.APPROVE_OPTION) {
            System.out.println("You chose to open this file: " +
                chooser.getSelectedFile().getName());
        }
        Path path = chooser.getSelectedFile().toPath();
        return path;
    }
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args){
    //        ParticipantManager pm =  new ParticipantManager();
    //        try {
    //            pm.chooseFile();
    //            pm.chooseFile();
    //
    //        } catch (IOException ex) {
    //            Logger.getLogger(ParticipantManager.class.getName()).log(Level.SEVERE, null, ex);
    //        }

        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {

                ParticipantManager pm =  new ParticipantManager();
                try {

                    pm.chooseFile();
                    pm.chooseFile();
                    System.exit(0);
                } catch (IOException ex) {
                    Logger.getLogger(ParticipantManager.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
    }
}

1 个答案:

答案 0 :(得分:0)

在致电var words: string = "none"; var sentence: string = "none"; 时,您将showOpenDialog(null)作为null的父组件传递。自从我使用JFileChooser以来已经有一段时间了,但我似乎记得,当传递JFileChooser时,可能会构造一个“神奇的”JFrame。在这个用例中可能有可能创建了两个“神奇”的JFrame,它们可以防止终止。

您可能想要尝试创建一个null作为JFrame的父级,因此它不会创建自动框架。

编辑:

我的第一个想法是:

JFileChooser