Calling JFileChooser twice in invokelater causes program not to exit

情到浓时终转凉″ 提交于 2020-01-06 19:34:30

问题


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

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.

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?

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);
                }
            }
        });
    }
}

回答1:


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.

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

EDIT:

My first take would be this:

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


来源:https://stackoverflow.com/questions/33788138/calling-jfilechooser-twice-in-invokelater-causes-program-not-to-exit

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!