I have JFileChooser.addPropertyChangeListener(new PropertyChangeListener()); where PropertyChangeListener listens to the changes of the count size of files selection, so that it limits the count of selection to a specified count of files. It works well, but a little flaw in the behavior of selection/deselection of files.

Say I limit selection count size to be 3, then I select any 3 files, after that when I select one more file below that 3 selected files (below in position), the new selection will be rejected (deselected) but maintain the already 3 selected files; which is the expected behavior. However, oppositely; when I select one more file above any of the already 3 selected files (above in position), that new selected file will be selected causing deselection to the one file at the bottom of the already 3 selected files.

I need to maintain the deselection behavior after selecting above file to be the same as after selecting below file.

Here is MCVE code


import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

public class FileChooserWithLimitedFilesSelection {

    private JPanel panel;
    private JFileChooser fileChooser;
    private JButton btnFileChooser;

    public FileChooserWithLimitedFilesSelection() {
        panel = new JPanel();
        btnFileChooser = new JButton("Browse...");
        btnFileChooser.addActionListener(new ButtonHandler());
        panel.add(btnFileChooser);
    }

    private class ButtonHandler implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            if (fileChooser == null) {
                fileChooser = new JFileChooser();
                fileChooser.setMultiSelectionEnabled(true);
                fileChooser.setAcceptAllFileFilterUsed(false);
                fileChooser.addPropertyChangeListener(new LimitSelectionHandler());
            }
            int returnedValue = fileChooser.showDialog(null, "Select files");
            // 
        }
    }

    private class LimitSelectionHandler implements PropertyChangeListener {

        @Override
        public void propertyChange(PropertyChangeEvent evt) {
            File[] selectedFiles = fileChooser.getSelectedFiles();
            int currentSelectionLength = selectedFiles.length;
            if (currentSelectionLength > 3) {
                File[] limitedFilesSelection = new File[3];
                for (int i = 0; i < limitedFilesSelection.length; i++) {
                    limitedFilesSelection[i] = selectedFiles[i];
                }
                fileChooser.setSelectedFiles(limitedFilesSelection);
                JOptionPane.showMessageDialog(fileChooser, "Only 3 selected files allowed.", "File chooser",
                        JOptionPane.ERROR_MESSAGE);
            }
        }
    }

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            FileChooserWithLimitedFilesSelection fcwrfs = new FileChooserWithLimitedFilesSelection();
            frame.add(fcwrfs.panel);
            frame.pack();
            frame.setVisible(true);
        });
    }
}

I took the implementation code of PropertyChangeListener from this answer.

1

There are 1 best solutions below

0
Saleh Rezq On

It is just as simple as @Holger has commented to the question above.

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

public class FileChooserWithLimitedFilesSelection {

    private JPanel panel;
    private JFileChooser fileChooser;
    private JButton btnFileChooser;
    private File[] limitedFilesSelection;

    public FileChooserWithLimitedFilesSelection() {
        limitedFilesSelection = new File[3];
        panel = new JPanel();
        btnFileChooser = new JButton("Browse...");
        btnFileChooser.addActionListener(new ButtonHandler());
        panel.add(btnFileChooser);
    }

    private class ButtonHandler implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            if (fileChooser == null) {
                fileChooser = new JFileChooser();
                fileChooser.setMultiSelectionEnabled(true);
                fileChooser.setAcceptAllFileFilterUsed(false);
                fileChooser.addPropertyChangeListener(new LimitSelectionHandler());
            }
            int returnedValue = fileChooser.showDialog(null, "Select files");
            // 
        }
    }

    private class LimitSelectionHandler implements PropertyChangeListener {

        @Override
        public void propertyChange(PropertyChangeEvent evt) {
            File[] selectedFiles = fileChooser.getSelectedFiles();
            int currentSelectionLength = selectedFiles.length;
            if (currentSelectionLength == 3) {
                for (int i = 0; i < limitedFilesSelection.length; i++) {
                    limitedFilesSelection[i] = selectedFiles[i];
                }
            } else if (currentSelectionLength > 3) {
                fileChooser.setSelectedFiles(limitedFilesSelection);
                JOptionPane.showMessageDialog(fileChooser, "Only 3 selected files allowed.", "File chooser",
                        JOptionPane.ERROR_MESSAGE);
            }
        }
    }

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            FileChooserWithLimitedFilesSelection fcwrfs = new FileChooserWithLimitedFilesSelection();
            frame.add(fcwrfs.panel);
            frame.pack();
            frame.setVisible(true);
        });
    }
}