簡體   English   中英

如何在JFileChooser Swing組件中列出最近使用的文件

[英]How to list recently used files in JFileChooser Swing component

我在Java項目中使用javax.swing.JFileChooser swing組件通過對話框打開文件。 如何在JFileChooser中列出最近使用的文件以供選擇。 每當我進入目錄並選擇耗時的文件時。

如何在組件本身中列出最近使用過的最后幾個文件,這樣我們就不需要一次又一次地瀏覽目錄來選擇一個文件?

JFileChooser允許您提供accessory Component ,該Component已添加到Windows中右側的JFileChooser組件中。

你能做的是...

  • 創建一個JListListModel ,將JList設置為JFileChoosers accessory (將其包裝在JScrollPane
  • 每次選擇文件時,將其添加到Set
  • 每次您打開JFileChooser ,請使用Set的值更新JList的模型(或使用Set返回模型)。
  • 每次用戶從列表中選擇一個值時,您都需要更改JFileChoosers selectedFile屬性以反映更改。

有關更多詳細信息,請參閱提供附件組件以了解更多詳細信息...

更新

例

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)

看一看如何保存程序狀態然后加載它? 還有更多想法...

更新

經過一番思考,您可以使用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);
        }
    }
}
Use setSelectedFile(File file) method of JFileChooser.

醫生說:

public void setSelectedFile(File file)

設置所選文件。 如果文件的父目錄不是當前目錄,則將當前目錄更改為文件的父目錄。

此鏈接可能會有所幫助

peeskillet的例子

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM