ominug
ominug

Reputation: 1572

Detect when JFileChooser has been closed

JFileChooser has a method addActionListener which accepts an ActionListener which is invoked when the user presses one of the two buttons at the bottom of the JFileChooser window. But, as I discovered, it is not invoked when the user closes the JFileChooser by clicking on the close button in the window title bar of the chooser (or using an other method of the OS to close it). So my question is: How can a creator of a JFileChooser recognize when it has been closed in this case?

Upvotes: 0

Views: 1439

Answers (3)

ominug
ominug

Reputation: 1572

JFileChooser extends JComponent. So if you want to use it asynchronously instead of invoking showDialog and letting the rest of the UI freeze, you can embed the JFileChooser in a regular JFrame or any other Component as it is done here.

Then you can listen for the close event of your JFrame. Little demonstration:

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;

import javax.swing.JFileChooser;
import javax.swing.JFrame;

public class Demo {
    public static void main(String[] args) {
            JFrame frame = new JFrame("Select file");
            frame.setSize(400, 300);
            // disable default close behaviour of JFrame
            frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

            JFileChooser chooser = new JFileChooser();
            frame.add(chooser, BorderLayout.CENTER);

            // little helper to close the JFrame properly
            Runnable closeFrame = () -> {
                frame.setVisible(false);
                frame.dispose();
            };

            chooser.addActionListener((ActionEvent e) -> {
                if (e.getActionCommand() ==
                        JFileChooser.APPROVE_SELECTION) {
                    closeFrame.run();
                    System.out.println("User pressed approve button.");
                    File selectedFile = chooser.getSelectedFile();
                } else if (e.getActionCommand() ==
                        JFileChooser.CANCEL_SELECTION) {
                    closeFrame.run();
                    System.out.println("User pressed cancel button.");
                }
            });

            frame.addWindowListener(new WindowAdapter() {

                @Override
                public void windowClosing(WindowEvent e) {
                    // You could tell the user here
                    // that he has to select a file…
                    closeFrame.run();
                    System.out.println("User closed JFrame.");
                }
            });

            frame.setVisible(true);
    }
}

Upvotes: 0

trashgod
trashgod

Reputation: 205785

In conjunction with the result returned by showOpenDialog(), you can add an AncestorListener and implement ancestorRemoved().

Code:

JFileChooser chooser = new JFileChooser();
chooser.addAncestorListener(new AncestorListener() {

    @Override
    public void ancestorAdded(AncestorEvent e) {}

    @Override
    public void ancestorRemoved(AncestorEvent e) {
        System.out.println(e);
    }

    @Override
    public void ancestorMoved(AncestorEvent e) {}
});

Console:

javax.swing.event.AncestorEvent[] on javax.swing.JFileChooser[…]

Upvotes: 3

KostasC
KostasC

Reputation: 1106

Do you mean like that:

JFileChooser fileChooser = new JFileChooser();
fileChooser.setCurrentDirectory(new File(System.getProperty("user.home")));
int result = fileChooser.showOpenDialog(null);
if (result == JFileChooser.APPROVE_OPTION) {
    File selectedFile = fileChooser.getSelectedFile();
    // select file      
} else if (result == JFileChooser.CANCEL_OPTION) {
    // file chooser closed
}

Upvotes: 5

Related Questions