1

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

我的理解是对 Swing 类的调用main()应该使用invokelater. 对于一次调用,这一切正常(JVM 成功退出)chooseFile(),但是当我向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);
                }
            }
        });
    }
}
4

1 回答 1

1

在您对您的调用中showOpenDialog(null)null作为JFileChooser. 自从我使用 以来已经有一段时间了JFileChooser,但我似乎记得,当null传入时,可能会构造一个“魔术”JFrame。在这个用例中,可能会创建两个“魔术”JFrame,它们会阻止终止。

您可能想尝试创建一个JFrame作为两个JFileChoosers 的父级的,这样它就不会创建自动框架。

编辑:

我的第一个想法是:

public static class ParticipantManager {
    JFrame frame;

    private JFrame getFrame() {
        if (frame==null) {
            frame = new JFrame();
            frame.setSize(600, 400);
            frame.setLocationRelativeTo(null);
            // frame.setVisible(true); // <---- worked for me without this call too
        }
        return frame;
    }

    private void close() {
        frame.dispose();
    }

    private Path chooseFile() throws IOException{
        JFrame f = getFrame();
        ...
        int returnVal = chooser.showOpenDialog(f);
    ...

    ...
                pm.chooseFile();
                pm.chooseFile();
                pm.close(); // <----- close the frame
    ...
于 2015-11-18T21:42:47.457 回答