Creating custom JFileChooser

↘锁芯ラ 提交于 2019-12-19 03:44:18

问题


To create an Arabic JFileChooser (RTL) I use the following:

MyFileChooser:

import javax.swing.JOptionPane;
import javax.swing.UIManager;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.filechooser.FileView;
import java.io.File;
import java.awt.ComponentOrientation;
import java.awt.Dimension;
public class MyFileChooser extends JFileChooser
{
    private String extension;
    private String title;
    public MyFileChooser(String extension, String title)
    {
        super();
        this.extension = extension;
        this.title = title;
        addChoosableFileFilter(new FileNameExtensionFilter(String.format("(*.%1$s) فقط %1$s ملفات", extension), extension));
        applyComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
        //setPreferredSize(new Dimension(450, 350));
    }

    @Override public String getDialogTitle()
    {
        return title;
    }

    @Override public File getSelectedFile()
    {
        File selectedFile = super.getSelectedFile();
        if(selectedFile != null)
        {
            String name = selectedFile.getName();
            if(!name.contains(".")) selectedFile = new File(selectedFile.getParentFile(), name + '.' + extension);
        }
        return selectedFile;
    }
}

Main:

import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
import java.awt.event.*;
public class MainFrame extends JFrame implements ActionListener
{
    public MyFileChooser chooser;
    public MainFrame()
    {
        super("Main Frame");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        try{ UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());}
        catch(Exception e){ System.out.println("Unable to load Windows look and feel");}
        setPreferredSize(new Dimension(300, 100));
        ((JPanel) getContentPane()).setBorder(new EmptyBorder(13, 13, 13, 13) );
        setLayout(new FlowLayout());
        JButton btn = new JButton("Open");
        btn.setActionCommand("myButton");
        btn.addActionListener(this);
        add(btn);
        JPanel panel = new JPanel();

        UIManager.put("FileChooser.saveButtonText", "حفظ");
        UIManager.put("FileChooser.openButtonText", "فتح");
        UIManager.put("FileChooser.cancelButtonText", "إلغاء");
        UIManager.put("FileChooser.updateButtonText", "تحديث");
        UIManager.put("FileChooser.helpButtonText", "مساعدة");
        UIManager.put("FileChooser.saveButtonToolTipText", "حفظ ملف");
        UIManager.put("FileChooser.openButtonToolTipText", "فتح ملف");
        UIManager.put("FileChooser.cancelButtonToolTipText", "إلغاء");
        UIManager.put("FileChooser.updateButtonToolTipText", "تحديث");
        UIManager.put("FileChooser.helpButtonToolTipText", "مساعدة");
        UIManager.put("FileChooser.listViewButtonToolTipText", "قائمة");
        UIManager.put("FileChooser.lookInLabelText", "بحث في:");
        UIManager.put("FileChooser.newFolderToolTipText", "إنشاء مجلد جديد");
        UIManager.put("FileChooser.fileNameLabelText", "اسم الملف:");
        UIManager.put("FileChooser.filesOfTypeLabelText", "  نوع الملف:");
        UIManager.put("FileChooser.detailsViewButtonToolTipText", "تفاصيل");
        UIManager.put("FileChooser.upFolderToolTipText", "للأعلى")

        chooser = new MyFileChooser("aaa", "العنوان");
        chooser.setAcceptAllFileFilterUsed(false);
        chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
        chooser.setFileHidingEnabled(false);

        pack();
        setLocationRelativeTo(null);
        setVisible(true);
        setResizable(false);
    }
    public void actionPerformed(ActionEvent e)
    {
        if(e.getActionCommand().equals("myButton"))
        {
            int status = chooser.showOpenDialog(null);
            // blah blah
        }
    }
    public static void main(String[] args)
    {
        new MainFrame();
    }
}

ScreenShots:

Everything is cool, except some parts I need to modify them so I can get an arabic JFileChooser:

  • The scrollbar is always set to the left when list view is on. How can I fix it?
  • On Details view, the header of the table is written in English. How can I modify it or at least disable the details view?
  • The labeles "Recent Items", "Desktop", "My Documents", "Computer", and "Network" how can I modify them or at least remove them?

回答1:


below is an interesting class that customizes a JFileChooser. it can inspire you on doing more interesting customization. take a look at method customizeFileChooser(). hope this helps.

public class MyJFileChooser extends JFileChooser {

    private static final int COLUMN_FILENAME = 0;
    private static final int COLUMN_FILESIZE = 1;
    private static final int COLUMN_FILETYPE = 2;
    private static final int COLUMN_FILEDATE = 3;
    private static final int COLUMN_FILEATTR = 4;
    private static final int COLUMN_COLCOUNT = 5;
    private static String[] COLUMNS = null;
    Vector detailsBtn = new Vector();
    UI ui;
    static JTable tbl;



    public void customizeFileChooser(Component[] comp) {

        int cnt = 1;

        for (int x = 0; x < comp.length; x++) {
            if (comp[x] instanceof JPanel) {
                customizeFileChooser(((JPanel) comp[x]).getComponents());


                Component[] c = ((JPanel) comp[x]).getComponents();
                for (int i = 0; i < c.length; i++) {

                    if (c[i] instanceof JTextField) {
                        ((JTextField) c[i]).setVisible(false);

                    }
                    if (c[i] instanceof JToggleButton) {

                        detailsBtn.add((JToggleButton) c[i]);
                        ((JToggleButton) c[i]).doClick();

                    }

                    if (c[i] instanceof JLabel) {

                        JLabel lbl = (JLabel) c[i];

                        if (x == 0 && i == 0) {
                            lbl.setVisible(false);
                        } else if (x == 2 && i == 0) {
                            lbl.setVisible(false);
                        } else if (x == 0 && i == 1) {

                            lbl.setVisible(false);
                        }

                    }

                    if (c[i] instanceof JComboBox) {
                        JComboBox b = (JComboBox) c[i];
                        if (x == 0 && i == 1) {
                            b.setVisible(false);
                        }
                        if (x == 2 && i == 1) {
                            b.setVisible(false);
                        }
                        if (x == 2 && i == 3) {
                            b.setVisible(false);
                        }


                    }

                }
            }
        }

    }

    public MyJFileChooser() {
        if (COLUMNS == null) {
            Locale l = getLocale();
            COLUMNS = new String[]{
                        UIManager.getString("FileChooser.fileNameHeaderText", l),
                        UIManager.getString("FileChooser.fileSizeHeaderText", l),
                        UIManager.getString("FileChooser.fileTypeHeaderText", l),
                        UIManager.getString("FileChooser.fileDateHeaderText", l),
                        UIManager.getString("FileChooser.fileAttrHeaderText", l)
                    };
        }

    }

    public void show() {
        MyJFileChooser fc = new MyJFileChooser();
        fc.showOpenDialog(MyJFileChooser.this);

    }


    /**************************************************************************
     * Always create the local UI
     * @param comp
     *************************************************************************/
    public final void setUI(ComponentUI comp) {
        super.setUI(ui = new UI(this));

    }


    /**************************************************************************
     * Internal implementation of Metal LookAndFeel to create the table sorting
     * ability.
     *************************************************************************/
    private final static class UI extends MetalFileChooserUI {

        private DirectoryModel model;

        /**************************************************************************
         * Must be overridden to extend
         * @param e
         *************************************************************************/
        public UI(JFileChooser e) {
            super(e);
        }

        /**************************************************************************
         * Overridden to create our own model
         *************************************************************************/
        protected final void createModel() {
            model = new DirectoryModel(getFileChooser());

        }

        /**************************************************************************
         * Overridden to get our own model
         * @return
         *************************************************************************/
        public final BasicDirectoryModel getModel() {
            return model;
        }

        /**************************************************************************
         * Calls the default method then adds a MouseListener to the JTable
         * @param chooser
         * @return
         *************************************************************************/
        protected final JPanel createDetailsView(JFileChooser chooser) {
            final JPanel panel = super.createDetailsView(chooser);

            //Since we can't access MetalFileChooserUI's private member detailsTable
            //directly, we have to find it in the JPanel
            tbl = findJTable(panel.getComponents());
            if (tbl != null) {

                //Fix the columns so they can't be rearranged, if we don't do this
                //we would need to keep track when each column is moved
                tbl.getTableHeader().setReorderingAllowed(false);

                //Add a mouselistener to listen for clicks on column headers
                tbl.getTableHeader().addMouseListener(new MouseAdapter() {

                    public void mouseClicked(MouseEvent e) {
                        //Only process single clicks
                        if (e.getClickCount() > 1) {
                            return;
                        }
                        e.consume();
                        final int col = tbl.getTableHeader().columnAtPoint(e.getPoint());
                        if (col == COLUMN_FILENAME || col == COLUMN_FILESIZE
                                || col == COLUMN_FILEDATE) {
                            model.sort(col, tbl);
                        }
                    }
                });
            }
            return panel;
        }

        /**************************************************************************
         * Finds the JTable in the panel so we can add MouseListener
         * @param comp
         * @return
         *************************************************************************/
        private final static JTable findJTable(Component[] comp) {
            for (int i = 0; i < comp.length; i++) {
                if (comp[i] instanceof JTable) {
                    return (JTable) comp[i];
                }
                if (comp[i] instanceof Container) {
                    JTable tbl = findJTable(((Container) comp[i]).getComponents());
                    if (tbl != null) {
                        return tbl;
                    }
                }
            }
            return null;
        }
    }

    /***************************************************************************
     * Implementation of BasicDirectoryModel that sorts the Files by column
     **************************************************************************/
    private final static class DirectoryModel extends BasicDirectoryModel {

        int col = 0;
        boolean ascending;

        /**************************************************************************
         * Must be overridden to extend BasicDirectoryModel
         * @param chooser
         *************************************************************************/
        DirectoryModel(JFileChooser chooser) {
            super(chooser);
        }

        /**************************************************************************
         * Supposedly this is not used anymore, hopefully not.  We implemented
         * some basic attempt at sorting just in case
         * @param a
         * @param b
         * @return
         *************************************************************************/
        protected final boolean lt(File a, File b) {
            System.out.println("LT called?");
            boolean less = false;
            switch (col) {
                case COLUMN_FILEDATE:
                    less = a.lastModified() > b.lastModified();
                    break;
                case COLUMN_FILESIZE:
                    less = a.length() > b.length();
                    break;
                default:
                    less = a.getName().compareToIgnoreCase(b.getName()) > 0;
                    break;
            }
            if (ascending) {
                return less = !less;
            }
            return less;
        }

        /**************************************************************************
         * Resorts the JFileChooser table based on new column
         * @param c
         *************************************************************************/
        protected final void sort(int c, JTable tbl) {
            //Set column and order
            col = c;
            ascending = !ascending;
            String indicator = " (^)";
            if (ascending) {
                indicator = " (v)";
            }

            final JTableHeader th = tbl.getTableHeader();
            final TableColumnModel tcm = th.getColumnModel();

            for (int i = 0; i < MyJFileChooser.COLUMN_COLCOUNT - 1; i++) {
                final TableColumn tc = tcm.getColumn(i); // the column to change
                tc.setHeaderValue(COLUMNS[i]);
            }

            final TableColumn tc = tcm.getColumn(col); // the column to change
            tc.setHeaderValue(COLUMNS[col] + indicator);

            th.repaint();

            //Requery the file listing
            validateFileCache();
        }

        /**************************************************************************
         * Sorts the data based on current column setting
         * @param data
         *************************************************************************/
        protected final void sort(Vector data) {
            switch (col) {
                case COLUMN_FILEDATE:
                    Collections.sort(data, new Comparator() {

                        public int compare(Object o1, Object o2) {
                            int ret = 1;
                            final File a = (File) o1;
                            final File b = (File) o2;
                            if (a.lastModified() > b.lastModified()) {
                                ret = -1;
                            } else if (a.lastModified() == b.lastModified()) {
                                ret = 0;
                            }

                            if (ascending) {
                                ret *= -1;
                            }
                            return ret;
                        }
                    });
                    break;
                case COLUMN_FILESIZE:
                    Collections.sort(data, new Comparator() {

                        public int compare(Object o1, Object o2) {
                            int ret = 1;
                            final File a = (File) o1;
                            final File b = (File) o2;
                            if (a.length() > b.length()) {
                                ret = -1;
                            } else if (a.length() == b.length()) {
                                ret = 0;
                            }

                            if (ascending) {
                                ret *= -1;
                            }
                            return ret;
                        }
                    });
                    break;
                case COLUMN_FILENAME:
                    Collections.sort(data, new Comparator() {

                        public int compare(Object o1, Object o2) {
                            final File a = (File) o1;
                            final File b = (File) o2;
                            if (ascending) {
                                return a.getName().compareToIgnoreCase(b.getName());
                            } else {
                                return -1 * a.getName().compareToIgnoreCase(b.getName());
                            }
                        }
                    });
                    break;
            }
        }
    }
    }


来源:https://stackoverflow.com/questions/6720957/creating-custom-jfilechooser

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!