如何修复 PropertyChangeListener 中有限选择 JFileChooser.setSelectedFiles(fs) 的取消选择行为以维护已选择的文件?

问题描述 投票:0回答:1

我有

JFileChooser.addPropertyChangeListener(new PropertyChangeListener());
,其中
PropertyChangeListener
监听文件选择的计数大小的变化,以便将选择的计数限制为指定的文件数。它工作得很好,但在选择/取消选择文件的行为上有一点缺陷。

假设我将选择计数大小限制为3,然后我选择任意3个文件,之后当我在下面选择的3个文件(位置下方)中再选择一个文件时,新选择将被拒绝(取消选择)但保留已经选择的3个文件; 这是预期的行为。然而,恰恰相反;当我在 上面 任何已选择的文件(上方位置)中再选择一个文件时,将选择该新选择的文件,从而取消选择已选择的 3 个文件底部的一个文件。

我需要在选择 above 文件后保持取消选择行为与选择 below 文件后相同。

这是MCVE代码


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

我从这个

answer
中获取了PropertyChangeListener的实现代码。

java swing jfilechooser propertychangelistener deselect
1个回答
0
投票

就像@Holger对上述问题进行评论一样简单。

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);
        });
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.