更改 JFileChooser 中选定的文件以响应事件

发布于 2024-10-17 06:04:24 字数 1347 浏览 0 评论 0原文

我希望我的 JFileChooser 允许选择多个文件,但可以同时选择的文件数量受到限制。

理想情况下,我想实时限制选择,优先考虑最近选择的文件,即当选择第三个文件时,应自动取消选择第一个文件(即最早选择的文件)。

我认为像这样的 PropertyChangeListener 可以工作:

public static void main(String[] args) throws IOException {
    final JFileChooser fc = new JFileChooser(didir);
    fc.setMultiSelectionEnabled(true);
    fc.addPropertyChangeListener(new PropertyChangeListener() {
        private final Set<File> selected = Sets.newLinkedHashSet();
        public void propertyChange(PropertyChangeEvent evt) {
            if (JFileChooser.SELECTED_FILES_CHANGED_PROPERTY.equals(evt.getPropertyName())) {
                File[] selectedFiles = fc.getSelectedFiles();
                if (selectedFiles.length > 2) {
                    selected.addAll(Arrays.asList(selectedFiles));
                    int numToRemove = Math.max(0, selected.size() - 2);
                    Iterables.removeIf(Iterables.limit(selected, numToRemove),
                                       Predicates.alwaysTrue());
                    fc.setSelectedFiles(selected.toArray(new File[0]));
                }
            }
        }
    });
    fc.showOpenDialog(null);
}

但是对 fc.setSelectedFiles() 的调用没有效果(虽然它触发了一个事件,但它不会更新选择在列表中。)

是否有任何方法可以在 JFileChooser 打开时以编程方式强制更改选择?或者还有其他方法来限制选择的大小?

I would like my JFileChooser to allow multiple file selection, but with a limit on the number of files that can be selected simultaneously.

Ideally I would like to constrain the selection in real-time, with priority given to the most-recently selected file, i.e. when a 3rd file is selected, the 1st file (i.e the one that was selected earliest) should be deselected automatically.

I thought that a PropertyChangeListener like this one would work:

public static void main(String[] args) throws IOException {
    final JFileChooser fc = new JFileChooser(didir);
    fc.setMultiSelectionEnabled(true);
    fc.addPropertyChangeListener(new PropertyChangeListener() {
        private final Set<File> selected = Sets.newLinkedHashSet();
        public void propertyChange(PropertyChangeEvent evt) {
            if (JFileChooser.SELECTED_FILES_CHANGED_PROPERTY.equals(evt.getPropertyName())) {
                File[] selectedFiles = fc.getSelectedFiles();
                if (selectedFiles.length > 2) {
                    selected.addAll(Arrays.asList(selectedFiles));
                    int numToRemove = Math.max(0, selected.size() - 2);
                    Iterables.removeIf(Iterables.limit(selected, numToRemove),
                                       Predicates.alwaysTrue());
                    fc.setSelectedFiles(selected.toArray(new File[0]));
                }
            }
        }
    });
    fc.showOpenDialog(null);
}

However the call to fc.setSelectedFiles() has no effect (although it fires an event, it does not update the selection in the list.)

Is there any way to programatically force a change to the selection while the JFileChooser is open? Or is there another way to limit the size of the selection?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

ヤ经典坏疍 2024-10-24 06:04:24
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.IOException;

import javax.swing.JFileChooser;

public class MyClass {
    final static JFileChooser fc = new JFileChooser("/");
    public static void main(String[] args) throws IOException {
        fc.setMultiSelectionEnabled(true);
        fc.addPropertyChangeListener(new ChangeListener());
        fc.showOpenDialog(null);
    }

    private static class ChangeListener implements PropertyChangeListener{
        @Override
        public void propertyChange(PropertyChangeEvent evt) {
            if (JFileChooser.SELECTED_FILES_CHANGED_PROPERTY.equals(evt.getPropertyName())) {
                File[] selectedFiles = fc.getSelectedFiles();
                File[] allowedFiles = new File[2];
                if (selectedFiles.length > 2) {
                    allowedFiles[0] = selectedFiles[1];
                    allowedFiles[1] = selectedFiles[0];

                        fc.setSelectedFiles(allowedFiles);
                }
            }
        }
    }
}
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.IOException;

import javax.swing.JFileChooser;

public class MyClass {
    final static JFileChooser fc = new JFileChooser("/");
    public static void main(String[] args) throws IOException {
        fc.setMultiSelectionEnabled(true);
        fc.addPropertyChangeListener(new ChangeListener());
        fc.showOpenDialog(null);
    }

    private static class ChangeListener implements PropertyChangeListener{
        @Override
        public void propertyChange(PropertyChangeEvent evt) {
            if (JFileChooser.SELECTED_FILES_CHANGED_PROPERTY.equals(evt.getPropertyName())) {
                File[] selectedFiles = fc.getSelectedFiles();
                File[] allowedFiles = new File[2];
                if (selectedFiles.length > 2) {
                    allowedFiles[0] = selectedFiles[1];
                    allowedFiles[1] = selectedFiles[0];

                        fc.setSelectedFiles(allowedFiles);
                }
            }
        }
    }
}
只有影子陪我不离不弃 2024-10-24 06:04:24

我发现这个错误是 Macintosh 外观所特有的。 setSelectedFilesetSelectedFiles 在 Mac 上根本不起作用(甚至在打开对话框之前也是如此)。我的示例代码在 Metal 外观和感觉上运行良好。

可能的解决方法包括:

  • 使用不同的外观
  • 使用 FileDialog 而不是 JFileChooser(不支持多个文件选择)

I have discovered that this bug is specific to the Macintosh look-and feel. setSelectedFile and setSelectedFiles do not work at all on the Mac (even before the dialog is opened.) My sample code works fine with the Metal look-and-feel.

Possible workarounds include:

  • Use a different look-and-feel
  • Use a FileDialog instead of a JFileChooser (does not support multiple file selection)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文