gpt4 book ai didi

java - 如何在 JFileChooser Swing 组件中列出最近使用的文件

转载 作者:行者123 更新时间:2023-11-29 07:46:47 25 4
gpt4 key购买 nike

我在我的 Java 项目中使用 javax.swing.JFileChooser swing 组件通过对话框打开文件。如何在 JFileChooser 中列出最近使用的文件以供选择。每次我进入目录并选择耗时的文件。

我如何在组件本身中列出最近几个最近使用的文件,这样我们就不需要一次又一次地浏览目录来选择文件?

最佳答案

JFileChooser 允许您提供一个 accessory Component,它被添加到右侧的 JFileChooser 组件中Windows 下的一侧。

你可以做的是......

  • 创建一个JListListModel,将JList设置为JFileChoosers accessory (将其包装在 JScrollPane 中)
  • 每次选择一个文件时,将其添加到Set
  • 每次打开 JFileChooser 时,使用 Set 中的值更新 JList 的模型(或返回模型使用 Set)。
  • 每次用户从列表中选择一个值时,您都需要更改 JFileChoosers selectedFile 属性以反射(reflect)更改...

有关更多详细信息,请查看 Providing an Accessory Component更多详情...

已更新

Example

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javax.swing.AbstractListModel;
import javax.swing.DefaultListCellRenderer;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.filechooser.FileSystemView;

public class TestFileChooser {

public static void main(String[] args) {
new TestFileChooser();
}

public TestFileChooser() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}

JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}

public class TestPane extends JPanel {

private JFileChooser fc;
private RectentFileList rectentFileList;

public TestPane() {
setLayout(new GridBagLayout());
JButton chooser = new JButton("Choose");
chooser.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (fc == null) {
fc = new JFileChooser();
rectentFileList = new RectentFileList(fc);
fc.setAccessory(rectentFileList);
fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
}
switch (fc.showOpenDialog(TestPane.this)) {
case JOptionPane.OK_OPTION:
File file = fc.getSelectedFile();
rectentFileList.add(file);
break;
}
}
});
add(chooser);
}

@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}

public class RectentFileList extends JPanel {

private final JList<File> list;
private final FileListModel listModel;
private final JFileChooser fileChooser;

public RectentFileList(JFileChooser chooser) {
fileChooser = chooser;
listModel = new FileListModel();
list = new JList<>(listModel);
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
list.setCellRenderer(new FileListCellRenderer());

setLayout(new BorderLayout());
add(new JScrollPane(list));

list.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
if (!e.getValueIsAdjusting()) {
File file = list.getSelectedValue();
// You might like to check to see if the file still exists...
fileChooser.setSelectedFile(file);
}
}
});
}

public void clearList() {
listModel.clear();
}

public void add(File file) {
listModel.add(file);
}

public class FileListModel extends AbstractListModel<File> {

private List<File> files;

public FileListModel() {
files = new ArrayList<>();
}

public void add(File file) {
if (!files.contains(file)) {
if (files.isEmpty()) {
files.add(file);
} else {
files.add(0, file);
}
fireIntervalAdded(this, 0, 0);
}
}

public void clear() {
int size = files.size() - 1;
if (size >= 0) {
files.clear();
fireIntervalRemoved(this, 0, size);
}
}

@Override
public int getSize() {
return files.size();
}

@Override
public File getElementAt(int index) {
return files.get(index);
}
}

public class FileListCellRenderer extends DefaultListCellRenderer {

@Override
public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (value instanceof File) {
File file = (File) value;
Icon ico = FileSystemView.getFileSystemView().getSystemIcon(file);
setIcon(ico);
setToolTipText(file.getParent());
setText(file.getName());
}
return this;
}

}

}

}

持久性问题是一个广泛的问题,将归结为您的个人需求,例如,您可以将文件列表转储到一个平面文件中,这可能是最简单的解决方案,因为这意味着您可以简单地阅读从头到尾检查文件,并知道您拥有全部内容。此外,再次写出文件将覆盖任何以前的值,使其易于管理。

其他解决方案可能需要提供一个“计数”属性,然后您可以将其作为已知键的后缀以列出值,这将需要在您更新详细信息时手动删除旧值。您还可以尝试使用定界符将所有值保存为持久性存储中的单个值,但这会带来选择不会在文件名中使用的定界符的问题(路径分隔符可能会做:D)

看看How can I save the state of my program and then load it?更多的想法...

已更新

经过一番思考,您可以使用 Preferences API 通过 File.pathSeparator 使用单个键来存储文件列表,因为这应该是唯一的并且不被文件名/路径使用。

例如,您可以使用类似...的方式保存列表

StringBuilder sb = new StringBuilder(128);
for (int index = 0; index < listModel.getSize(); index++) {
File file = listModel.getElementAt(index);
if (sb.length() > 0) {
sb.append(File.pathSeparator);
}
sb.append(file.getPath());
}
System.out.println(sb.toString());
Preferences p = Preferences.userNodeForPackage(TestFileChooser.class);
p.put("RectentFileList.fileList", sb.toString());

然后使用类似...的方式再次加载它

Preferences p = Preferences.userNodeForPackage(TestFileChooser.class);
String listOfFiles = p.get("RectentFileList.fileList", null);
if (listOfFiles != null) {
String[] files = listOfFiles.split(File.pathSeparator);
for (String fileRef : files) {
File file = new File(fileRef);
if (file.exists()) {
add(file);
}
}
}

关于java - 如何在 JFileChooser Swing 组件中列出最近使用的文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25051305/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com