Как вывести список недавно использованных файлов в компоненте JFileChooser Swing

1

Я использую javax.swing.JFileChooser swing компонент в моем проекте Java для открытия файла по диалогу. Как просмотреть недавно использованные файлы для выбора в JFileChooser. Каждый раз, когда я захожу в каталог и выбираю файл, который занимает много времени.

Как перечислить последние несколько недавно использованных файлов в самом компоненте, так что нам не нужно снова и снова перемещаться по каталогам, чтобы выбрать файл?

Теги:
list
swing
jfilechooser

2 ответа

4
Лучший ответ

JFileChooser позволяет вам поставлять accessory Component который добавляется к компоненту JFileChooser, с правой стороны под Windows.

Что вы можете сделать...

  • Создайте JList и ListModel, установите JList как accessory JFileChoosers (JScrollPane его в JScrollPane)
  • Каждый раз, когда вы выбираете файл, добавьте его в Set
  • Каждый раз, когда вы открываете JFileChooser, обновите модель JList со значениями из Set (или обратно с помощью Set).
  • Каждый раз, когда пользователь выбирает значение из списка, вам нужно будет изменить свойство JFileChoosers selectedFile чтобы отразить изменение...

Для получения дополнительной информации см. " Предоставление компонента аксессуаров" для получения более подробной информации...

обновленный

Изображение 174551

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

        }

    }

}

Вопрос о настойчивости - это широкий вопрос и будет сведен к вашим личным потребностям, например, вы можете просто выгрузить список файлов в плоский файл, это, вероятно, самое простое решение, так как это означает, что вы можете просто прочитать файл из начните заканчивать и знайте, что у вас есть все содержимое. Кроме того, запись файла снова переопределит любые предыдущие значения, что упростит управление.

Другим решениям может потребоваться предоставить свойство "count", которое затем будет суффикс к известному ключу для перечисления значений, для чего потребуется вручную удалить старые значения при обновлении данных. Вы также можете попробовать использовать разделитель, чтобы сохранить все значения как одно значение в хранилище персистентности, но это связано с проблемами выбора разделителя, который не будет использоваться в именах файлов (разделитель путей может выполнять: D)

Посмотрите, как я могу сохранить состояние своей программы и загрузить ее? для некоторых идей...

обновленный

Немного подумав, вы можете использовать API Preferences для хранения списка файлов с помощью одного ключа с помощью File.pathSeparator, так как это должно быть уникальным и не использоваться именем файла /path.

Например, вы можете сохранить список, используя что-то вроде...

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);
        }
    }
}
1
Use setSelectedFile(File file) method of JFileChooser.

Док говорит:

public void setSelectedFile(File file)

Устанавливает выбранный файл. Если родительский каталог файла не является текущим каталогом, изменяет текущий каталог в качестве родительского каталога файла.

Эти ссылки могут быть полезны

Например, peeskillet

  • 0
    setSelectedFile требует, чтобы путь к файлу был жестко задан. Скажем, я выбираю файл при первом запуске программы и завершаю работу. Когда я снова запускаю программу, я хочу, чтобы JFileChooser перечислял файл, который я выбрал при последнем запуске.
  • 0
    тогда вы должны ссылаться на ссылку, так как нет прямого метода для достижения этого, вы должны увидеть 2-3 примера, как добиться того, чего вы хотите. @ TheGame

Ещё вопросы

Сообщество Overcoder
Наверх
Меню