在 invokelater 中调用 JFileChooser 两次导致程序不退出 [英] Calling JFileChooser twice in invokelater causes program not to exit

查看:28
本文介绍了在 invokelater 中调用 JFileChooser 两次导致程序不退出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am writing a program to collect information from two text files to add to tables in a database. In order to permit the user to select his own files I created a non-static method called chooseFile() that uses JFileChooser class to present a showOpenDialog (I've also tried it as a static method with the same results. If this sounds like I'm guessing, you're correct - I'm only so-so with programming).

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

My understanding is that calls to Swing classes in main() should be done using invokelater. This all worked fine (the JVM exits successfully) for one call to chooseFile(), but when I added a second call to chooseFile() the JVM keeps running indefinitely. However, the program exits normally with both calls to chooseFile() if I do so without using invokelater. Adding System.exit(0) after the second call in invokelater also allows the program to exit normally.

据我所知,在所有(非守护进程)线程都关闭之前,程序不会退出.但是,我认为使用 invokelater 的目的是将所有非线程安全的 Swing 相关活动推送到 EDT.使用 System.exit(0) 是这里的最佳实践还是我应该了解的其他内容?

From what I have been able to gather, the program won't exit until all the (non-daemon) threads are closed. However, I thought that the purpose for using invokelater was to push all non-thread safe Swing related activities onto the EDT. Is using System.exit(0) the best practice here or is there something else I should know about?

这是我的 SSCCE:

Here is my 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);
                }
            }
        });
    }
}

推荐答案

在您对 showOpenDialog(null) 的调用中,您将 null 作为 的父组件传递>JFileChooser.自从我使用 JFileChooser 以来已经有一段时间了,但我似乎记得,当 null 传入时,可能会构造一个神奇的"JFrame.这可能是可能的,在这个用例中,创建了两个神奇"的 JFrame 并防止终止.

In your call to showOpenDialog(null) you pass null as the parent component for the JFileChooser. It's been some time since I worked with JFileChooser, but I seem to remember, that a "magic" JFrame may be constructed, when null is passed in. It may be possible, that in this use case two "magic" JFrames are created and they prevent termination.

您可能想尝试创建一个 JFrame 作为两个 JFileChooser 的父级,这样它就不会创建自动帧.

You may want to try to create a JFrame which serves as parent for both JFileChoosers so it does not create the automatic frames.

我的第一个想法是:

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
    ...

这篇关于在 invokelater 中调用 JFileChooser 两次导致程序不退出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆