/*
 * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.swing;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.ComponentOrientation;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.DefaultKeyboardFocusManager;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Insets;
import java.awt.KeyboardFocusManager;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.text.DateFormat;
import java.text.MessageFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.Callable;

import javax.accessibility.AccessibleContext;
import javax.swing.AbstractAction;
import javax.swing.AbstractListModel;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.ButtonGroup;
import javax.swing.DefaultCellEditor;
import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListSelectionModel;
import javax.swing.Icon;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.ListModel;
import javax.swing.ListSelectionModel;
import javax.swing.LookAndFeel;
import javax.swing.RowSorter;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.TransferHandler;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.RowSorterEvent;
import javax.swing.event.RowSorterListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.filechooser.FileSystemView;
import javax.swing.plaf.basic.BasicDirectoryModel;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableColumnModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
import javax.swing.text.Position;

import sun.awt.AWTAccessor;
import sun.awt.AWTAccessor.MouseEventAccessor;
import sun.awt.shell.ShellFolder;
import sun.awt.shell.ShellFolderColumnInfo;

/**
 * <b>WARNING:</b> This class is an implementation detail and is only
 * public so that it can be used by two packages. You should NOT consider
 * this public API.
 * <p>
 * This component is intended to be used in a subclass of
 * javax.swing.plaf.basic.BasicFileChooserUI. It relies heavily on the
 * implementation of BasicFileChooserUI and is intended to be API compatible
 * with earlier implementations of MetalFileChooserUI and WindowsFileChooserUI.
 *
 * @author Leif Samuelsson
 */
@SuppressWarnings("serial") // JDK-implementation class
public class FilePane extends JPanel implements PropertyChangeListener {
    // Constants for actions. These are used for the actions' ACTION_COMMAND_KEY
    // and as keys in the action maps for FilePane and the corresponding UI classes

    public static final String ACTION_APPROVE_SELECTION = "approveSelection";
    public static final String ACTION_CANCEL            = "cancelSelection";
    public static final String ACTION_EDIT_FILE_NAME    = "editFileName";
    public static final String ACTION_REFRESH           = "refresh";
    public static final String ACTION_CHANGE_TO_PARENT_DIRECTORY = "Go Up";
    public static final String ACTION_NEW_FOLDER        = "New Folder";
    public static final String ACTION_VIEW_LIST         = "viewTypeList";
    public static final String ACTION_VIEW_DETAILS      = "viewTypeDetails";

    private Action[] actions;

    // "enums" for setViewType()
    public  static final int VIEWTYPE_LIST     = 0;
    public  static final int VIEWTYPE_DETAILS  = 1;
    private static final int VIEWTYPE_COUNT    = 2;

    private int viewType = -1;
    private JPanel[] viewPanels = new JPanel[VIEWTYPE_COUNT];
    private JPanel currentViewPanel;
    private String[] viewTypeActionNames;

    private String filesListAccessibleName = null;
    private String filesDetailsAccessibleName = null;

    private JPopupMenu contextMenu;
    private JMenu viewMenu;

    private String viewMenuLabelText;
    private String refreshActionLabelText;
    private String newFolderActionLabelText;

    private String kiloByteString;
    private String megaByteString;
    private String gigaByteString;

    private String renameErrorTitleText;
    private String renameErrorText;
    private String renameErrorFileExistsText;

    private static final Cursor waitCursor =
        Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR);

    private final KeyListener detailsKeyListener = new KeyAdapter() {
        private final long timeFactor;

        private final StringBuilder typedString = new StringBuilder();

        private long lastTime = 1000L;

        {
            Long l = (Long) UIManager.get("Table.timeFactor");
            timeFactor = (l != null) ? l : 1000L;
        }

        /**
         * Moves the keyboard focus to the first element whose prefix matches
         * the sequence of alphanumeric keys pressed by the user with delay
         * less than value of <code>timeFactor</code>. Subsequent same key
         * presses move the keyboard focus to the next object that starts with
         * the same letter until another key is pressed, then it is treated
         * as the prefix with appropriate number of the same letters followed
         * by first typed another letter.
         */
        public void keyTyped(KeyEvent e) {
            BasicDirectoryModel model = getModel();
            int rowCount = model.getSize();

            if (detailsTable == null || rowCount == 0 ||
                    e.isAltDown() || e.isControlDown() || e.isMetaDown()) {
                return;
            }

            InputMap inputMap = detailsTable.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
            KeyStroke key = KeyStroke.getKeyStrokeForEvent(e);

            if (inputMap != null && inputMap.get(key) != null) {
                return;
            }

            int startIndex = detailsTable.getSelectionModel().getLeadSelectionIndex();

            if (startIndex < 0) {
                startIndex = 0;
            }

            if (startIndex >= rowCount) {
                startIndex = rowCount - 1;
            }

            char c = e.getKeyChar();

            long time = e.getWhen();

            if (time - lastTime < timeFactor) {
                if (typedString.length() == 1 && typedString.charAt(0) == c) {
                    // Subsequent same key presses move the keyboard focus to the next
                    // object that starts with the same letter.
                    startIndex++;
                } else {
                    typedString.append(c);
                }
            } else {
                startIndex++;

                typedString.setLength(0);
                typedString.append(c);
            }

            lastTime = time;

            if (startIndex >= rowCount) {
                startIndex = 0;
            }

            // Find next file
            int index = getNextMatch(startIndex, rowCount - 1);

            if (index < 0 && startIndex > 0) { // wrap
                index = getNextMatch(0, startIndex - 1);
            }

            if (index >= 0) {
                detailsTable.getSelectionModel().setSelectionInterval(index, index);

                Rectangle cellRect = detailsTable.getCellRect(index,
                        detailsTable.convertColumnIndexToView(COLUMN_FILENAME), false);
                detailsTable.scrollRectToVisible(cellRect);
            }
        }

        private int getNextMatch(int startIndex, int finishIndex) {
            BasicDirectoryModel model = getModel();
            JFileChooser fileChooser = getFileChooser();
            DetailsTableRowSorter rowSorter = getRowSorter();

            String prefix = typedString.toString().toLowerCase();

            // Search element
            for (int index = startIndex; index <= finishIndex; index++) {
                File file = (File) model.getElementAt(rowSorter.convertRowIndexToModel(index));

                String fileName = fileChooser.getName(file).toLowerCase();

                if (fileName.startsWith(prefix)) {
                    return index;
                }
            }

            return -1;
        }
    };

    private FocusListener editorFocusListener = new FocusAdapter() {
        public void focusLost(FocusEvent e) {
            if (! e.isTemporary()) {
                applyEdit();
            }
        }
    };

    private static FocusListener repaintListener = new FocusListener() {
        public void focusGained(FocusEvent fe) {
            repaintSelection(fe.getSource());
        }

        public void focusLost(FocusEvent fe) {
            repaintSelection(fe.getSource());
        }

        private void repaintSelection(Object source) {
            if (source instanceof JList) {
                repaintListSelection((JList)source);
            } else if (source instanceof JTable) {
                repaintTableSelection((JTable)source);
            }
        }

        private void repaintListSelection(JList<?> list) {
            int[] indices = list.getSelectedIndices();
            for (int i : indices) {
                Rectangle bounds = list.getCellBounds(i, i);
                list.repaint(bounds);
            }
        }

        private void repaintTableSelection(JTable table) {
            int minRow = table.getSelectionModel().getMinSelectionIndex();
            int maxRow = table.getSelectionModel().getMaxSelectionIndex();
            if (minRow == -1 || maxRow == -1) {
                return;
            }

            int col0 = table.convertColumnIndexToView(COLUMN_FILENAME);

            Rectangle first = table.getCellRect(minRow, col0, false);
            Rectangle last = table.getCellRect(maxRow, col0, false);
            Rectangle dirty = first.union(last);
            table.repaint(dirty);
        }
    };

    private boolean smallIconsView = false;
    private Border  listViewBorder;
    private Color   listViewBackground;
    private boolean listViewWindowsStyle;
    private boolean readOnly;
    private boolean fullRowSelection = false;

    private ListSelectionModel listSelectionModel;
    private JList<?> list;
    private JTable detailsTable;

    private static final int COLUMN_FILENAME = 0;

    // Provides a way to recognize a newly created folder, so it can
    // be selected when it appears in the model.
    private File newFolderFile;

    // Used for accessing methods in the corresponding UI class
    private FileChooserUIAccessor fileChooserUIAccessor;
    private DetailsTableModel detailsTableModel;
    private DetailsTableRowSorter rowSorter;

    public FilePane(FileChooserUIAccessor fileChooserUIAccessor) {
        super(new BorderLayout());

        this.fileChooserUIAccessor = fileChooserUIAccessor;

        installDefaults();
        createActionMap();
    }

    public void uninstallUI() {
        if (getModel() != null) {
            getModel().removePropertyChangeListener(this);
        }
    }

    protected JFileChooser getFileChooser() {
        return fileChooserUIAccessor.getFileChooser();
    }

    protected BasicDirectoryModel getModel() {
        return fileChooserUIAccessor.getModel();
    }

    public int getViewType() {
        return viewType;
    }

    public void setViewType(int viewType) {
        if (viewType == this.viewType) {
            return;
        }

        int oldValue = this.viewType;
        this.viewType = viewType;

        JPanel createdViewPanel = null;
        Component newFocusOwner = null;

        switch (viewType) {
          case VIEWTYPE_LIST:
            if (viewPanels[viewType] == null) {
                createdViewPanel = fileChooserUIAccessor.createList();
                if (createdViewPanel == null) {
                    createdViewPanel = createList();
                }

                list = findChildComponent(createdViewPanel, JList.class);
                if (listSelectionModel == null) {
                    listSelectionModel = list.getSelectionModel();
                    if (detailsTable != null) {
                        detailsTable.setSelectionModel(listSelectionModel);
                    }
                } else {
                    list.setSelectionModel(listSelectionModel);
                }
            }
            list.setLayoutOrientation(JList.VERTICAL_WRAP);
            newFocusOwner = list;
            break;

          case VIEWTYPE_DETAILS:
            if (viewPanels[viewType] == null) {
                createdViewPanel = fileChooserUIAccessor.createDetailsView();
                if (createdViewPanel == null) {
                    createdViewPanel = createDetailsView();
                }

                detailsTable = findChildComponent(createdViewPanel, JTable.class);
                detailsTable.setRowHeight(Math.max(detailsTable.getFont().getSize() + 4, 16 + 1));
                if (listSelectionModel != null) {
                    detailsTable.setSelectionModel(listSelectionModel);
                }
            }
            newFocusOwner = detailsTable;
            break;
        }

        if (createdViewPanel != null) {
            viewPanels[viewType] = createdViewPanel;
            recursivelySetInheritsPopupMenu(createdViewPanel, true);
        }

        boolean isFocusOwner = false;

        if (currentViewPanel != null) {
            Component owner = DefaultKeyboardFocusManager.
                    getCurrentKeyboardFocusManager().getPermanentFocusOwner();

            isFocusOwner = owner == detailsTable || owner == list;

            remove(currentViewPanel);
        }

        currentViewPanel = viewPanels[viewType];
        add(currentViewPanel, BorderLayout.CENTER);

        if (isFocusOwner && newFocusOwner != null) {
            newFocusOwner.requestFocusInWindow();
        }

        revalidate();
        repaint();
        updateViewMenu();
        firePropertyChange("viewType", oldValue, viewType);
    }

    @SuppressWarnings("serial") // JDK-implementation class
    class ViewTypeAction extends AbstractAction {
        private int viewType;

        ViewTypeAction(int viewType) {
            super(viewTypeActionNames[viewType]);
            this.viewType = viewType;

            String cmd;
            switch (viewType) {
                case VIEWTYPE_LIST:    cmd = ACTION_VIEW_LIST;    break;
                case VIEWTYPE_DETAILS: cmd = ACTION_VIEW_DETAILS; break;
                default:               cmd = (String)getValue(Action.NAME);
            }
            putValue(Action.ACTION_COMMAND_KEY, cmd);
        }

        public void actionPerformed(ActionEvent e) {
            setViewType(viewType);
        }
    }

    public Action getViewTypeAction(int viewType) {
        return new ViewTypeAction(viewType);
    }

    private static void recursivelySetInheritsPopupMenu(Container container, boolean b) {
        if (container instanceof JComponent) {
            ((JComponent)container).setInheritsPopupMenu(b);
        }
        int n = container.getComponentCount();
        for (int i = 0; i < n; i++) {
            recursivelySetInheritsPopupMenu((Container)container.getComponent(i), b);
        }
    }

    protected void installDefaults() {
        Locale l = getFileChooser().getLocale();

        listViewBorder       = UIManager.getBorder("FileChooser.listViewBorder");
        listViewBackground   = UIManager.getColor("FileChooser.listViewBackground");
        listViewWindowsStyle = UIManager.getBoolean("FileChooser.listViewWindowsStyle");
        readOnly             = UIManager.getBoolean("FileChooser.readOnly");

        // TODO: On windows, get the following localized strings from the OS

        viewMenuLabelText =
                        UIManager.getString("FileChooser.viewMenuLabelText", l);
        refreshActionLabelText =
                        UIManager.getString("FileChooser.refreshActionLabelText", l);
        newFolderActionLabelText =
                        UIManager.getString("FileChooser.newFolderActionLabelText", l);

        viewTypeActionNames = new String[VIEWTYPE_COUNT];
        viewTypeActionNames[VIEWTYPE_LIST] =
                        UIManager.getString("FileChooser.listViewActionLabelText", l);
        viewTypeActionNames[VIEWTYPE_DETAILS] =
                        UIManager.getString("FileChooser.detailsViewActionLabelText", l);

        kiloByteString = UIManager.getString("FileChooser.fileSizeKiloBytes", l);
        megaByteString = UIManager.getString("FileChooser.fileSizeMegaBytes", l);
        gigaByteString = UIManager.getString("FileChooser.fileSizeGigaBytes", l);
        fullRowSelection = UIManager.getBoolean("FileView.fullRowSelection");

        filesListAccessibleName = UIManager.getString("FileChooser.filesListAccessibleName", l);
        filesDetailsAccessibleName = UIManager.getString("FileChooser.filesDetailsAccessibleName", l);

        renameErrorTitleText = UIManager.getString("FileChooser.renameErrorTitleText", l);
        renameErrorText = UIManager.getString("FileChooser.renameErrorText", l);
        renameErrorFileExistsText = UIManager.getString("FileChooser.renameErrorFileExistsText", l);
    }

    /**
     * Fetches the command list for the FilePane. These commands
     * are useful for binding to events, such as in a keymap.
     *
     * @return the command list
     */
    public Action[] getActions() {
        if (actions == null) {
            @SuppressWarnings("serial") // JDK-implementation class
            class FilePaneAction extends AbstractAction {
                FilePaneAction(String name) {
                    this(name, name);
                }

                FilePaneAction(String name, String cmd) {
                    super(name);
                    putValue(Action.ACTION_COMMAND_KEY, cmd);
                }

                public void actionPerformed(ActionEvent e) {
                    String cmd = (String)getValue(Action.ACTION_COMMAND_KEY);

                    if (cmd == ACTION_CANCEL) {
                        if (editFile != null) {
                           cancelEdit();
                        } else {
                           getFileChooser().cancelSelection();
                        }
                    } else if (cmd == ACTION_EDIT_FILE_NAME) {
                        JFileChooser fc = getFileChooser();
                        int index = listSelectionModel.getMinSelectionIndex();
                        if (index >= 0 && editFile == null &&
                            (!fc.isMultiSelectionEnabled() ||
                             fc.getSelectedFiles().length <= 1)) {

                            editFileName(index);
                        }
                    } else if (cmd == ACTION_REFRESH) {
                        getFileChooser().rescanCurrentDirectory();
                    }
                }

                public boolean isEnabled() {
                    String cmd = (String)getValue(Action.ACTION_COMMAND_KEY);
                    if (cmd == ACTION_CANCEL) {
                        return getFileChooser().isEnabled();
                    } else if (cmd == ACTION_EDIT_FILE_NAME) {
                        return !readOnly && getFileChooser().isEnabled();
                    } else {
                        return true;
                    }
                }
            }

            ArrayList<Action> actionList = new ArrayList<Action>(8);
            Action action;

            actionList.add(new FilePaneAction(ACTION_CANCEL));
            actionList.add(new FilePaneAction(ACTION_EDIT_FILE_NAME));
            actionList.add(new FilePaneAction(refreshActionLabelText, ACTION_REFRESH));

            action = fileChooserUIAccessor.getApproveSelectionAction();
            if (action != null) {
                actionList.add(action);
            }
            action = fileChooserUIAccessor.getChangeToParentDirectoryAction();
            if (action != null) {
                actionList.add(action);
            }
            action = getNewFolderAction();
            if (action != null) {
                actionList.add(action);
            }
            action = getViewTypeAction(VIEWTYPE_LIST);
            if (action != null) {
                actionList.add(action);
            }
            action = getViewTypeAction(VIEWTYPE_DETAILS);
            if (action != null) {
                actionList.add(action);
            }
            actions = actionList.toArray(new Action[actionList.size()]);
        }

        return Arrays.copyOf(actions, actions.length);
    }

    protected void createActionMap() {
        addActionsToMap(super.getActionMap(), getActions());
    }


    public static void addActionsToMap(ActionMap map, Action[] actions) {
        if (map != null && actions != null) {
            for (Action a : actions) {
                String cmd = (String)a.getValue(Action.ACTION_COMMAND_KEY);
                if (cmd == null) {
                    cmd = (String)a.getValue(Action.NAME);
                }
                map.put(cmd, a);
            }
        }
    }


    private void updateListRowCount(JList<?> list) {
        if (smallIconsView) {
            list.setVisibleRowCount(getModel().getSize() / 3);
        } else {
            list.setVisibleRowCount(-1);
        }
    }

    public JPanel createList() {
        JPanel p = new JPanel(new BorderLayout());
        final JFileChooser fileChooser = getFileChooser();

        final JList<Object> list = new JList<Object>() {
            public int getNextMatch(String prefix, int startIndex, Position.Bias bias) {
                ListModel<?> model = getModel();
                int max = model.getSize();
                if (prefix == null || startIndex < 0 || startIndex >= max) {
                    throw new IllegalArgumentException();
                }
                // start search from the next element before/after the selected element
                boolean backwards = (bias == Position.Bias.Backward);
                for (int i = startIndex; backwards ? i >= 0 : i < max; i += (backwards ?  -1 : 1)) {
                    String filename = fileChooser.getName((File)model.getElementAt(i));
                    if (filename.regionMatches(true, 0, prefix, 0, prefix.length())) {
                        return i;
                    }
                }
                return -1;
            }
        };
        list.setCellRenderer(new FileRenderer());
        list.setLayoutOrientation(JList.VERTICAL_WRAP);

        // 4835633 : tell BasicListUI that this is a file list
        list.putClientProperty("List.isFileList", Boolean.TRUE);

        if (listViewWindowsStyle) {
            list.addFocusListener(repaintListener);
        }

        updateListRowCount(list);

        getModel().addListDataListener(new ListDataListener() {
            public void intervalAdded(ListDataEvent e) {
                updateListRowCount(list);
            }
            public void intervalRemoved(ListDataEvent e) {
                updateListRowCount(list);
            }
            public void contentsChanged(ListDataEvent e) {
                if (isShowing()) {
                    clearSelection();
                }
                updateListRowCount(list);
            }
        });

        getModel().addPropertyChangeListener(this);

        if (fileChooser.isMultiSelectionEnabled()) {
            list.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
        } else {
            list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        }
        list.setModel(new SortableListModel());

        list.addListSelectionListener(createListSelectionListener());
        list.addMouseListener(getMouseHandler());

        JScrollPane scrollpane = new JScrollPane(list);
        if (listViewBackground != null) {
            list.setBackground(listViewBackground);
        }
        if (listViewBorder != null) {
            scrollpane.setBorder(listViewBorder);
        }

        list.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY, filesListAccessibleName);

        p.add(scrollpane, BorderLayout.CENTER);
        return p;
    }

    /**
     * This model allows for sorting JList
     */
    @SuppressWarnings("serial") // JDK-implementation class
    private class SortableListModel extends AbstractListModel<Object>
            implements TableModelListener, RowSorterListener {

        public SortableListModel() {
            getDetailsTableModel().addTableModelListener(this);
            getRowSorter().addRowSorterListener(this);
        }

        public int getSize() {
            return getModel().getSize();
        }

        public Object getElementAt(int index) {
            // JList doesn't support RowSorter so far, so we put it into the list model
            return getModel().getElementAt(getRowSorter().convertRowIndexToModel(index));
        }

        public void tableChanged(TableModelEvent e) {
            fireContentsChanged(this, 0, getSize());
        }

        public void sorterChanged(RowSorterEvent e) {
            fireContentsChanged(this, 0, getSize());
        }
    }

    private DetailsTableModel getDetailsTableModel() {
        if(detailsTableModel == null) {
            detailsTableModel = new DetailsTableModel(getFileChooser());
        }
        return detailsTableModel;
    }

    @SuppressWarnings("serial") // JDK-implementation class
    class DetailsTableModel extends AbstractTableModel implements ListDataListener {
        private final JFileChooser chooser;
        private final BasicDirectoryModel directoryModel;

        ShellFolderColumnInfo[] columns;
        int[] columnMap;

        DetailsTableModel(JFileChooser fc) {
            this.chooser = fc;
            directoryModel = getModel();
            directoryModel.addListDataListener(this);

            updateColumnInfo();
        }

        void updateColumnInfo() {
            File dir = chooser.getCurrentDirectory();
            if (dir != null && usesShellFolder(chooser)) {
                try {
                    dir = ShellFolder.getShellFolder(dir);
                } catch (FileNotFoundException e) {
                    // Leave dir without changing
                }
            }

            ShellFolderColumnInfo[] allColumns = ShellFolder.getFolderColumns(dir);

            ArrayList<ShellFolderColumnInfo> visibleColumns =
                    new ArrayList<ShellFolderColumnInfo>();
            columnMap = new int[allColumns.length];
            for (int i = 0; i < allColumns.length; i++) {
                ShellFolderColumnInfo column = allColumns[i];
                if (column.isVisible()) {
                    columnMap[visibleColumns.size()] = i;
                    visibleColumns.add(column);
                }
            }

            columns = new ShellFolderColumnInfo[visibleColumns.size()];
            visibleColumns.toArray(columns);
            columnMap = Arrays.copyOf(columnMap, columns.length);

            List<? extends RowSorter.SortKey> sortKeys =
                    (rowSorter == null) ? null : rowSorter.getSortKeys();
            fireTableStructureChanged();
            restoreSortKeys(sortKeys);
        }

        private void restoreSortKeys(List<? extends RowSorter.SortKey> sortKeys) {
            if (sortKeys != null) {
                // check if preserved sortKeys are valid for this folder
                for (int i = 0; i < sortKeys.size(); i++) {
                    RowSorter.SortKey sortKey = sortKeys.get(i);
                    if (sortKey.getColumn() >= columns.length) {
                        sortKeys = null;
                        break;
                    }
                }
                if (sortKeys != null) {
                    rowSorter.setSortKeys(sortKeys);
                }
            }
        }

        public int getRowCount() {
            return directoryModel.getSize();
        }

        public int getColumnCount() {
            return columns.length;
        }

        public Object getValueAt(int row, int col) {
            // Note: It is very important to avoid getting info on drives, as
            // this will trigger "No disk in A:" and similar dialogs.
            //
            // Use (f.exists() && !chooser.getFileSystemView().isFileSystemRoot(f)) to
            // determine if it is safe to call methods directly on f.
            return getFileColumnValue((File)directoryModel.getElementAt(row), col);
        }

        private Object getFileColumnValue(File f, int col) {
            return (col == COLUMN_FILENAME)
                    ? f // always return the file itself for the 1st column
                    : ShellFolder.getFolderColumnValue(f, columnMap[col]);
        }

        public void setValueAt(Object value, int row, int col) {
            if (col == COLUMN_FILENAME) {
                final JFileChooser chooser = getFileChooser();
                File f = (File)getValueAt(row, col);
                if (f != null) {
                    String oldDisplayName = chooser.getName(f);
                    String oldFileName = f.getName();
                    String newDisplayName = ((String)value).trim();
                    String newFileName;

                    if (!newDisplayName.equals(oldDisplayName)) {
                        newFileName = newDisplayName;
                        //Check if extension is hidden from user
                        int i1 = oldFileName.length();
                        int i2 = oldDisplayName.length();
                        if (i1 > i2 && oldFileName.charAt(i2) == '.') {
                            newFileName = newDisplayName + oldFileName.substring(i2);
                        }

                        // rename
                        FileSystemView fsv = chooser.getFileSystemView();
                        final File f2 = fsv.createFileObject(f.getParentFile(), newFileName);
                        if (f2.exists()) {
                            JOptionPane.showMessageDialog(chooser, MessageFormat.format(renameErrorFileExistsText,
                                    oldFileName), renameErrorTitleText, JOptionPane.ERROR_MESSAGE);
                        } else {
                            if (directoryModel.renameFile(f, f2)) {
                                if (fsv.isParent(chooser.getCurrentDirectory(), f2)) {
                                    // The setSelectedFile method produces a new setValueAt invocation while the JTable
                                    // is editing. Postpone file selection to be sure that edit mode of the JTable
                                    // is completed
                                    SwingUtilities.invokeLater(new Runnable() {
                                        public void run() {
                                            if (chooser.isMultiSelectionEnabled()) {
                                                chooser.setSelectedFiles(new File[]{f2});
                                            } else {
                                                chooser.setSelectedFile(f2);
                                            }
                                        }
                                    });
                                } else {
                                    // Could be because of delay in updating Desktop folder
                                    // chooser.setSelectedFile(null);
                                }
                            } else {
                                JOptionPane.showMessageDialog(chooser, MessageFormat.format(renameErrorText, oldFileName),
                                        renameErrorTitleText, JOptionPane.ERROR_MESSAGE);
                            }
                        }
                    }
                }
            }
        }

        public boolean isCellEditable(int row, int column) {
            File currentDirectory = getFileChooser().getCurrentDirectory();
            return (!readOnly && column == COLUMN_FILENAME && canWrite(currentDirectory));
        }

        public void contentsChanged(ListDataEvent e) {
            // Update the selection after the model has been updated
            new DelayedSelectionUpdater();
            fireTableDataChanged();
        }

        public void intervalAdded(ListDataEvent e) {
            int i0 = e.getIndex0();
            int i1 = e.getIndex1();
            if (i0 == i1) {
                File file = (File)directoryModel.getElementAt(i0);
                if (file.equals(newFolderFile)) {
                    new DelayedSelectionUpdater(file);
                    newFolderFile = null;
                }
            }

            fireTableRowsInserted(e.getIndex0(), e.getIndex1());
        }
        public void intervalRemoved(ListDataEvent e) {
            fireTableRowsDeleted(e.getIndex0(), e.getIndex1());
        }

        public ShellFolderColumnInfo[] getColumns() {
            return columns;
        }
    }


    private void updateDetailsColumnModel(JTable table) {
        if (table != null) {
            ShellFolderColumnInfo[] columns = detailsTableModel.getColumns();

            TableColumnModel columnModel = new DefaultTableColumnModel();
            for (int i = 0; i < columns.length; i++) {
                ShellFolderColumnInfo dataItem = columns[i];
                TableColumn column = new TableColumn(i);

                String title = dataItem.getTitle();
                if (title != null && title.startsWith("FileChooser.") && title.endsWith("HeaderText")) {
                    // the column must have a string resource that we try to get
                    String uiTitle = UIManager.getString(title, table.getLocale());
                    if (uiTitle != null) {
                        title = uiTitle;
                    }
                }
                column.setHeaderValue(title);

                Integer width = dataItem.getWidth();
                if (width != null) {
                    column.setPreferredWidth(width);
                    // otherwise we let JTable to decide the actual width
                }

                columnModel.addColumn(column);
            }

            // Install cell editor for editing file name
            if (!readOnly && columnModel.getColumnCount() > COLUMN_FILENAME) {
                columnModel.getColumn(COLUMN_FILENAME).
                        setCellEditor(getDetailsTableCellEditor());
            }

            table.setColumnModel(columnModel);
        }
    }

    private DetailsTableRowSorter getRowSorter() {
        if (rowSorter == null) {
            rowSorter = new DetailsTableRowSorter();
        }
        return rowSorter;
    }

    private class DetailsTableRowSorter extends TableRowSorter<TableModel> {
        public DetailsTableRowSorter() {
            SorterModelWrapper modelWrapper = new SorterModelWrapper();
            setModelWrapper(modelWrapper);
            modelWrapper.getModel().addTableModelListener(
                new TableModelListener() {
                    @Override
                    public void tableChanged(TableModelEvent e) {
                        modelStructureChanged();
                    }
                });
        }

        public void updateComparators(ShellFolderColumnInfo [] columns) {
            for (int i = 0; i < columns.length; i++) {
                Comparator<?> c = columns[i].getComparator();
                if (c != null) {
                    c = new DirectoriesFirstComparatorWrapper(i, c);
                }
                setComparator(i, c);
            }
        }

        @Override
        public void sort() {
            ShellFolder.invoke(new Callable<Void>() {
                public Void call() {
                    DetailsTableRowSorter.super.sort();
                    return null;
                }
            });
        }

        public void modelStructureChanged() {
            super.modelStructureChanged();
            updateComparators(detailsTableModel.getColumns());
        }

        private class SorterModelWrapper extends ModelWrapper<TableModel, Integer> {
            public TableModel getModel() {
                return getDetailsTableModel();
            }

            public int getColumnCount() {
                return getDetailsTableModel().getColumnCount();
            }

            public int getRowCount() {
                return getDetailsTableModel().getRowCount();
            }

            public Object getValueAt(int row, int column) {
                return FilePane.this.getModel().getElementAt(row);
            }

            public Integer getIdentifier(int row) {
                return row;
            }
        }
    }

    /**
     * This class sorts directories before files, comparing directory to
     * directory and file to file using the wrapped comparator.
     */
    private class DirectoriesFirstComparatorWrapper implements Comparator<File> {
        private Comparator<Object> comparator;
        private int column;

        @SuppressWarnings("unchecked")
        public DirectoriesFirstComparatorWrapper(int column, Comparator<?> comparator) {
            this.column = column;
            this.comparator = (Comparator<Object>)comparator;
        }

        public int compare(File f1, File f2) {
            if (f1 != null && f2 != null) {
                boolean traversable1 = getFileChooser().isTraversable(f1);
                boolean traversable2 = getFileChooser().isTraversable(f2);
                // directories go first
                if (traversable1 && !traversable2) {
                    return -1;
                }
                if (!traversable1 && traversable2) {
                    return 1;
                }
            }
            if (detailsTableModel.getColumns()[column].isCompareByColumn()) {
                return comparator.compare(
                        getDetailsTableModel().getFileColumnValue(f1, column),
                        getDetailsTableModel().getFileColumnValue(f2, column)
                );
            }
            // For this column we need to pass the file itself (not a
            // column value) to the comparator
            return comparator.compare(f1, f2);
        }
    }

    private DetailsTableCellEditor tableCellEditor;

    private DetailsTableCellEditor getDetailsTableCellEditor() {
        if (tableCellEditor == null) {
            tableCellEditor = new DetailsTableCellEditor(new JTextField());
        }
        return tableCellEditor;
    }

    @SuppressWarnings("serial") // JDK-implementation class
    private class DetailsTableCellEditor extends DefaultCellEditor {
        private final JTextField tf;

        public DetailsTableCellEditor(JTextField tf) {
            super(tf);
            this.tf = tf;
            tf.setName("Table.editor");
            tf.addFocusListener(editorFocusListener);
        }

        public Component getTableCellEditorComponent(JTable table, Object value,
                                                     boolean isSelected, int row, int column) {
            Component comp = super.getTableCellEditorComponent(table, value,
                    isSelected, row, column);
            if (value instanceof File) {
                tf.setText(getFileChooser().getName((File) value));
                tf.selectAll();
            }
            return comp;
        }
    }

    @SuppressWarnings("serial") // JDK-implementation class
    class DetailsTableCellRenderer extends DefaultTableCellRenderer {
        private final JFileChooser chooser;
        private final DateFormat df;
        private final MessageFormat mf = new MessageFormat("");
        private final NumberFormat nf = NumberFormat.getNumberInstance();
        private static final double baseFileSize = 1000.0;

        DetailsTableCellRenderer(JFileChooser chooser) {
            this.chooser = chooser;
            df = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT,
                                                chooser.getLocale());
            nf.setMinimumFractionDigits(1);
        }

        public void setBounds(int x, int y, int width, int height) {
        if (getHorizontalAlignment() == SwingConstants.LEADING &&
                    !fullRowSelection) {
                // Restrict width to actual text
                width = Math.min(width, this.getPreferredSize().width+4);
            } else {
                x -= 4;
            }
            super.setBounds(x, y, width, height);
        }


        public Insets getInsets(Insets i) {
            // Provide some space between columns
            i = super.getInsets(i);
            i.left  += 4;
            i.right += 4;
            return i;
        }

        public Component getTableCellRendererComponent(JTable table, Object value,
                              boolean isSelected, boolean hasFocus, int row, int column) {

            if ((table.convertColumnIndexToModel(column) != COLUMN_FILENAME ||
                    (listViewWindowsStyle && !table.isFocusOwner())) &&
                    !fullRowSelection) {
                isSelected = false;
            }

            super.getTableCellRendererComponent(table, value, isSelected,
                                                       hasFocus, row, column);

            setIcon(null);

            int modelColumn = table.convertColumnIndexToModel(column);
            ShellFolderColumnInfo columnInfo = detailsTableModel.getColumns()[modelColumn];

            Integer alignment = columnInfo.getAlignment();
            if (alignment == null) {
                alignment = (value instanceof Number)
                        ? SwingConstants.RIGHT
                        : SwingConstants.LEADING;
            }

            setHorizontalAlignment(alignment);

            // formatting cell text
            // TODO: it's rather a temporary trick, to be revised
            String text;

            if (value == null) {
                text = "";

            } else if (value instanceof File) {
                File file = (File)value;
                text = chooser.getName(file);
                Icon icon = chooser.getIcon(file);
                setIcon(icon);

            } else if (value instanceof final Long len) {
                /*
                 * This code block is relevant to Linux.
                 * File size is displayed up to 1 decimal precision.
                 * Base-10 number system is used for formatting file size
                 * similar to how it's formatted in file managers on Linux.
                 * Empty file size is shown as 0.0 KB,
                 * 1-100-byte files are shown as 0.1 KB,
                 * 101-200-byte files are shown as 0.2 KB and so on.
                 */
                Object[] displayedFileSize = new Object[1];

                if (listViewWindowsStyle) {
                    updateMessageFormatPattern(kiloByteString);
                    displayedFileSize[0] = roundToOneDecimalPlace(len);
                } else {
                    double kbVal = roundToOneDecimalPlace(len);
                    if (kbVal < baseFileSize) {
                        updateMessageFormatPattern(kiloByteString);
                        displayedFileSize[0] = kbVal;
                    } else {
                        double mbVal = roundToOneDecimalPlace(Math.ceil(kbVal));
                        if (mbVal < baseFileSize) {
                            updateMessageFormatPattern(megaByteString);
                            displayedFileSize[0] = mbVal;
                        } else {
                            updateMessageFormatPattern(gigaByteString);
                            displayedFileSize[0] = roundToOneDecimalPlace(Math.ceil(mbVal));
                        }
                    }
                }
                text = mf.format(displayedFileSize);

            } else if (value instanceof Date) {
                text = df.format((Date)value);

            } else {
                text = value.toString();
            }

            setText(text);

            putClientProperty("html.disable", getFileChooser().getClientProperty("html.disable"));

            return this;
        }

        private void updateMessageFormatPattern(String pattern) {
            mf.applyPattern(pattern);
            mf.setFormat(0, nf);
        }

        /**
         * Rounds a value to one decimal place. It's used to format
         * file size similar to how it's formatted in file managers on Linux.
         * For example, the file size of 1200 bytes is rounded to 1.2 KB.
         *
         * @param fileSize the file size to round to one decimal place
         * @return file size rounded to one decimal place
         */
        private static double roundToOneDecimalPlace(double fileSize) {
            return Math.ceil(fileSize / 100.0d) / 10.0d;
        }
    }

    public JPanel createDetailsView() {
        final JFileChooser chooser = getFileChooser();

        JPanel p = new JPanel(new BorderLayout());

        final JTable detailsTable = new JTable(getDetailsTableModel()) {
            // Handle Escape key events here
            protected boolean processKeyBinding(KeyStroke ks, KeyEvent e, int condition, boolean pressed) {
                if (e.getKeyCode() == KeyEvent.VK_ESCAPE && getCellEditor() == null) {
                    // We are not editing, forward to filechooser.
                    chooser.dispatchEvent(e);
                    return true;
                }
                return super.processKeyBinding(ks, e, condition, pressed);
            }

            public void tableChanged(TableModelEvent e) {
                super.tableChanged(e);

                if (e.getFirstRow() == TableModelEvent.HEADER_ROW) {
                    // update header with possibly changed column set
                    updateDetailsColumnModel(this);
                }
            }
        };

        detailsTable.setRowSorter(getRowSorter());
        detailsTable.setAutoCreateColumnsFromModel(false);
        detailsTable.setComponentOrientation(chooser.getComponentOrientation());
        detailsTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        detailsTable.setShowGrid(false);
        detailsTable.putClientProperty("JTable.autoStartsEdit", Boolean.FALSE);
        detailsTable.addKeyListener(detailsKeyListener);

        Font font = list.getFont();
        detailsTable.setFont(font);
        detailsTable.setIntercellSpacing(new Dimension(0, 0));

        TableCellRenderer headerRenderer =
                new AlignableTableHeaderRenderer(detailsTable.getTableHeader().getDefaultRenderer());
        detailsTable.getTableHeader().setDefaultRenderer(headerRenderer);
        TableCellRenderer cellRenderer = new DetailsTableCellRenderer(chooser);
        detailsTable.setDefaultRenderer(Object.class, cellRenderer);

        // So that drag can be started on a mouse press
        detailsTable.getColumnModel().getSelectionModel().
            setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

        detailsTable.addMouseListener(getMouseHandler());
        // No need to addListSelectionListener because selections are forwarded
        // to our JList.

        // 4835633 : tell BasicTableUI that this is a file list
        detailsTable.putClientProperty("Table.isFileList", Boolean.TRUE);

        if (listViewWindowsStyle) {
            detailsTable.addFocusListener(repaintListener);
        }

        detailsTable.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
                     null);
        detailsTable.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
                     null);

        JScrollPane scrollpane = new JScrollPane(detailsTable);
        scrollpane.setComponentOrientation(chooser.getComponentOrientation());
        LookAndFeel.installColors(scrollpane.getViewport(), "Table.background", "Table.foreground");

        // Adjust width of first column so the table fills the viewport when
        // first displayed (temporary listener).
        scrollpane.addComponentListener(new ComponentAdapter() {
            public void componentResized(ComponentEvent e) {
                JScrollPane sp = (JScrollPane)e.getComponent();
                fixNameColumnWidth(sp.getViewport().getSize().width);
                sp.removeComponentListener(this);
            }
        });

        // 4835633.
        // If the mouse is pressed in the area below the Details view table, the
        // event is not dispatched to the Table MouseListener but to the
        // scrollpane.  Listen for that here so we can clear the selection.
        scrollpane.addMouseListener(new MouseAdapter() {
            public void mousePressed(MouseEvent e) {
                JScrollPane jsp = ((JScrollPane)e.getComponent());
                JTable table = (JTable)jsp.getViewport().getView();

                if (!e.isShiftDown() || table.getSelectionModel().getSelectionMode() == ListSelectionModel.SINGLE_SELECTION) {
                    clearSelection();
                    TableCellEditor tce = table.getCellEditor();
                    if (tce != null) {
                        tce.stopCellEditing();
                    }
                }
            }
        });

        detailsTable.setForeground(list.getForeground());
        detailsTable.setBackground(list.getBackground());

        if (listViewBorder != null) {
            scrollpane.setBorder(listViewBorder);
        }
        p.add(scrollpane, BorderLayout.CENTER);

        detailsTableModel.fireTableStructureChanged();

        detailsTable.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY, filesDetailsAccessibleName);

        return p;
    } // createDetailsView

    private class AlignableTableHeaderRenderer implements TableCellRenderer {
        TableCellRenderer wrappedRenderer;

        public AlignableTableHeaderRenderer(TableCellRenderer wrappedRenderer) {
            this.wrappedRenderer = wrappedRenderer;
        }

        public Component getTableCellRendererComponent(
                                JTable table, Object value, boolean isSelected,
                                boolean hasFocus, int row, int column) {

            Component c = wrappedRenderer.getTableCellRendererComponent(
                                table, value, isSelected, hasFocus, row, column);

            int modelColumn = table.convertColumnIndexToModel(column);
            ShellFolderColumnInfo columnInfo = detailsTableModel.getColumns()[modelColumn];

            Integer alignment = columnInfo.getAlignment();
            if (alignment == null) {
                alignment = SwingConstants.CENTER;
            }
            if (c instanceof JLabel) {
                ((JLabel) c).setHorizontalAlignment(alignment);
            }

            return c;
        }
    }

    private void fixNameColumnWidth(int viewWidth) {
        TableColumn nameCol = detailsTable.getColumnModel().getColumn(COLUMN_FILENAME);
        int tableWidth = detailsTable.getPreferredSize().width;

        if (tableWidth < viewWidth) {
            nameCol.setPreferredWidth(nameCol.getPreferredWidth() + viewWidth - tableWidth);
        }
    }

    private class DelayedSelectionUpdater implements Runnable {
        File editFile;

        DelayedSelectionUpdater() {
            this(null);
        }

        DelayedSelectionUpdater(File editFile) {
            this.editFile = editFile;
            if (isShowing()) {
                SwingUtilities.invokeLater(this);
            }
        }

        public void run() {
            setFileSelected();
            if (editFile != null) {
                editFileName(getRowSorter().convertRowIndexToView(
                        getModel().indexOf(editFile)));
                editFile = null;
            }
        }
    }


    /**
     * Creates a selection listener for the list of files and directories.
     *
     * @return a <code>ListSelectionListener</code>
     */
    public ListSelectionListener createListSelectionListener() {
        return fileChooserUIAccessor.createListSelectionListener();
    }

    int lastIndex = -1;
    File editFile = null;

    private int getEditIndex() {
        return lastIndex;
    }

    private void setEditIndex(int i) {
        lastIndex = i;
    }

    private void resetEditIndex() {
        lastIndex = -1;
    }

    private void cancelEdit() {
        if (editFile != null) {
            editFile = null;
            list.remove(editCell);
            repaint();
        } else if (detailsTable != null && detailsTable.isEditing()) {
            detailsTable.getCellEditor().cancelCellEditing();
        }
    }

    JTextField editCell = null;

    /**
     * @param index visual index of the file to be edited
     */
    @SuppressWarnings("deprecation")
    private void editFileName(int index) {
        JFileChooser chooser = getFileChooser();
        File currentDirectory = chooser.getCurrentDirectory();

        if (readOnly || !canWrite(currentDirectory)) {
            return;
        }

        ensureIndexIsVisible(index);
        switch (viewType) {
          case VIEWTYPE_LIST:
            editFile = (File)getModel().getElementAt(getRowSorter().convertRowIndexToModel(index));
            Rectangle r = list.getCellBounds(index, index);
            if (editCell == null) {
                editCell = new JTextField();
                editCell.setName("Tree.cellEditor");
                editCell.addActionListener(new EditActionListener());
                editCell.addFocusListener(editorFocusListener);
                editCell.setNextFocusableComponent(list);
            }
            list.add(editCell);
            editCell.setText(chooser.getName(editFile));
            ComponentOrientation orientation = list.getComponentOrientation();
            editCell.setComponentOrientation(orientation);

            Icon icon = chooser.getIcon(editFile);

            // PENDING - grab padding (4) below from defaults table.
            int editX = icon == null ? 20 : icon.getIconWidth() + 4;

            if (orientation.isLeftToRight()) {
                editCell.setBounds(editX + r.x, r.y, r.width - editX, r.height);
            } else {
                editCell.setBounds(r.x, r.y, r.width - editX, r.height);
            }
            editCell.requestFocus();
            editCell.selectAll();
            break;

          case VIEWTYPE_DETAILS:
            detailsTable.editCellAt(index, COLUMN_FILENAME);
            break;
        }
    }


    class EditActionListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            applyEdit();
        }
    }

    private void applyEdit() {
        if (editFile != null && editFile.exists()) {
            JFileChooser chooser = getFileChooser();
            String oldDisplayName = chooser.getName(editFile);
            String oldFileName = editFile.getName();
            String newDisplayName = editCell.getText().trim();
            String newFileName;

            if (!newDisplayName.equals(oldDisplayName)) {
                newFileName = newDisplayName;
                //Check if extension is hidden from user
                int i1 = oldFileName.length();
                int i2 = oldDisplayName.length();
                if (i1 > i2 && oldFileName.charAt(i2) == '.') {
                    newFileName = newDisplayName + oldFileName.substring(i2);
                }

                // rename
                FileSystemView fsv = chooser.getFileSystemView();
                File f2 = fsv.createFileObject(editFile.getParentFile(), newFileName);
                if (f2.exists()) {
                    JOptionPane.showMessageDialog(chooser, MessageFormat.format(renameErrorFileExistsText, oldFileName),
                            renameErrorTitleText, JOptionPane.ERROR_MESSAGE);
                } else {
                    if (getModel().renameFile(editFile, f2)) {
                        if (fsv.isParent(chooser.getCurrentDirectory(), f2)) {
                            if (chooser.isMultiSelectionEnabled()) {
                                chooser.setSelectedFiles(new File[]{f2});
                            } else {
                                chooser.setSelectedFile(f2);
                            }
                        } else {
                            //Could be because of delay in updating Desktop folder
                            //chooser.setSelectedFile(null);
                        }
                    } else {
                        JOptionPane.showMessageDialog(chooser, MessageFormat.format(renameErrorText, oldFileName),
                                renameErrorTitleText, JOptionPane.ERROR_MESSAGE);
                    }
                }
            }
        }
        if (detailsTable != null && detailsTable.isEditing()) {
            detailsTable.getCellEditor().stopCellEditing();
        }
        cancelEdit();
    }

    protected Action newFolderAction;

    public Action getNewFolderAction() {
        if (!readOnly && newFolderAction == null) {
            newFolderAction = new AbstractAction(newFolderActionLabelText) {
                private Action basicNewFolderAction;

                // Initializer
                {
                    putValue(Action.ACTION_COMMAND_KEY, FilePane.ACTION_NEW_FOLDER);

                    File currentDirectory = getFileChooser().getCurrentDirectory();
                    if (currentDirectory != null) {
                        setEnabled(canWrite(currentDirectory));
                    }
                }

                public void actionPerformed(ActionEvent ev) {
                    if (basicNewFolderAction == null) {
                        basicNewFolderAction = fileChooserUIAccessor.getNewFolderAction();
                    }
                    JFileChooser fc = getFileChooser();
                    File oldFile = fc.getSelectedFile();
                    basicNewFolderAction.actionPerformed(ev);
                    File newFile = fc.getSelectedFile();
                    if (newFile != null && !newFile.equals(oldFile) && newFile.isDirectory()) {
                        newFolderFile = newFile;
                    }
                }
            };
        }
        return newFolderAction;
    }

    @SuppressWarnings("serial") // JDK-implementation class
    protected class FileRenderer extends DefaultListCellRenderer  {

        public Component getListCellRendererComponent(JList<?> list, Object value,
                                                      int index, boolean isSelected,
                                                      boolean cellHasFocus) {

            if (listViewWindowsStyle && !list.isFocusOwner()) {
                isSelected = false;
            }

            super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
            File file = (File) value;
            String fileName = getFileChooser().getName(file);
            setText(fileName);
            setFont(list.getFont());

            Icon icon = getFileChooser().getIcon(file);
            if (icon != null) {
                setIcon(icon);
            } else {
                if (getFileChooser().getFileSystemView().isTraversable(file)) {
                    setText(fileName+File.separator);
                }
            }

            putClientProperty("html.disable", getFileChooser().getClientProperty("html.disable"));

            return this;
        }
    }


    @SuppressWarnings("deprecation")
    void setFileSelected() {
        if (getFileChooser().isMultiSelectionEnabled() && !isDirectorySelected()) {
            File[] files = getFileChooser().getSelectedFiles(); // Should be selected
            Object[] selectedObjects = list.getSelectedValues(); // Are actually selected

            listSelectionModel.setValueIsAdjusting(true);
            try {
                int lead = listSelectionModel.getLeadSelectionIndex();
                int anchor = listSelectionModel.getAnchorSelectionIndex();

                Arrays.sort(files);
                Arrays.sort(selectedObjects);

                int shouldIndex = 0;
                int actuallyIndex = 0;

                // Remove files that shouldn't be selected and add files which should be selected
                // Note: Assume files are already sorted in compareTo order.
                while (shouldIndex < files.length &&
                       actuallyIndex < selectedObjects.length) {
                    int comparison = files[shouldIndex].compareTo((File)selectedObjects[actuallyIndex]);
                    if (comparison < 0) {
                        doSelectFile(files[shouldIndex++]);
                    } else if (comparison > 0) {
                        doDeselectFile(selectedObjects[actuallyIndex++]);
                    } else {
                        // Do nothing
                        shouldIndex++;
                        actuallyIndex++;
                    }

                }

                while (shouldIndex < files.length) {
                    doSelectFile(files[shouldIndex++]);
                }

                while (actuallyIndex < selectedObjects.length) {
                    doDeselectFile(selectedObjects[actuallyIndex++]);
                }

                // restore the anchor and lead
                if (listSelectionModel instanceof DefaultListSelectionModel) {
                    ((DefaultListSelectionModel)listSelectionModel).
                        moveLeadSelectionIndex(lead);
                    listSelectionModel.setAnchorSelectionIndex(anchor);
                }
            } finally {
                listSelectionModel.setValueIsAdjusting(false);
            }
        } else {
            JFileChooser chooser = getFileChooser();
            File f;
            if (isDirectorySelected()) {
                f = getDirectory();
            } else {
                f = chooser.getSelectedFile();
            }
            int i;
            if (f != null && (i = getModel().indexOf(f)) >= 0) {
                int viewIndex = getRowSorter().convertRowIndexToView(i);
                listSelectionModel.setSelectionInterval(viewIndex, viewIndex);
                ensureIndexIsVisible(viewIndex);
            } else {
                clearSelection();
            }
        }
    }

    private void doSelectFile(File fileToSelect) {
        int index = getModel().indexOf(fileToSelect);
        // could be missed in the current directory if it changed
        if (index >= 0) {
            index = getRowSorter().convertRowIndexToView(index);
            listSelectionModel.addSelectionInterval(index, index);
        }
    }

    private void doDeselectFile(Object fileToDeselect) {
        int index = getRowSorter().convertRowIndexToView(
                                getModel().indexOf(fileToDeselect));
        listSelectionModel.removeSelectionInterval(index, index);
    }

    /* The following methods are used by the PropertyChange Listener */

    private void doSelectedFileChanged(PropertyChangeEvent e) {
        applyEdit();
        File f = (File) e.getNewValue();
        JFileChooser fc = getFileChooser();
        if (f != null
            && ((fc.isFileSelectionEnabled() && !f.isDirectory())
                || (f.isDirectory() && fc.isDirectorySelectionEnabled()))) {

            setFileSelected();
        }
    }

    private void doSelectedFilesChanged(PropertyChangeEvent e) {
        applyEdit();
        File[] files = (File[]) e.getNewValue();
        JFileChooser fc = getFileChooser();
        if (files != null
            && files.length > 0
            && (files.length > 1 || fc.isDirectorySelectionEnabled() || !files[0].isDirectory())) {
            setFileSelected();
        }
    }

    private void doDirectoryChanged(PropertyChangeEvent e) {
        getDetailsTableModel().updateColumnInfo();

        JFileChooser fc = getFileChooser();
        FileSystemView fsv = fc.getFileSystemView();

        applyEdit();
        resetEditIndex();
        ensureIndexIsVisible(0);
        File currentDirectory = fc.getCurrentDirectory();
        if (currentDirectory != null) {
            if (!readOnly) {
                getNewFolderAction().setEnabled(canWrite(currentDirectory));
            }
            fileChooserUIAccessor.getChangeToParentDirectoryAction().setEnabled(!fsv.isRoot(currentDirectory));
        }
        if (list != null) {
            list.clearSelection();
        }
    }

    private void doFilterChanged(PropertyChangeEvent e) {
        applyEdit();
        resetEditIndex();
        clearSelection();
    }

    private void doFileSelectionModeChanged(PropertyChangeEvent e) {
        applyEdit();
        resetEditIndex();
        clearSelection();
    }

    private void doMultiSelectionChanged(PropertyChangeEvent e) {
        clearSelection();
        if (getFileChooser().isMultiSelectionEnabled()) {
            listSelectionModel.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
            getFileChooser().setSelectedFile(null);
        } else {
            listSelectionModel.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
            getFileChooser().setSelectedFiles(null);
        }
    }

    /*
     * Listen for filechooser property changes, such as
     * the selected file changing, or the type of the dialog changing.
     */
    public void propertyChange(PropertyChangeEvent e) {
            if (viewType == -1) {
                setViewType(VIEWTYPE_LIST);
            }

        String s = e.getPropertyName();
        if (s.equals(JFileChooser.SELECTED_FILE_CHANGED_PROPERTY)) {
            doSelectedFileChanged(e);
        } else if (s.equals(JFileChooser.SELECTED_FILES_CHANGED_PROPERTY)) {
            doSelectedFilesChanged(e);
        } else if (s.equals(JFileChooser.DIRECTORY_CHANGED_PROPERTY)) {
            doDirectoryChanged(e);
        } else if (s.equals(JFileChooser.FILE_FILTER_CHANGED_PROPERTY)) {
            doFilterChanged(e);
        } else if (s.equals(JFileChooser.FILE_SELECTION_MODE_CHANGED_PROPERTY)) {
            doFileSelectionModeChanged(e);
        } else if (s.equals(JFileChooser.MULTI_SELECTION_ENABLED_CHANGED_PROPERTY)) {
            doMultiSelectionChanged(e);
        } else if (s.equals(JFileChooser.CANCEL_SELECTION)) {
            applyEdit();
        } else if (s.equals("busy")) {
            setCursor((Boolean)e.getNewValue() ? waitCursor : null);
        } else if (s.equals("componentOrientation")) {
            ComponentOrientation o = (ComponentOrientation)e.getNewValue();
            JFileChooser cc = (JFileChooser)e.getSource();
            if (o != e.getOldValue()) {
                cc.applyComponentOrientation(o);
            }
            if (detailsTable != null) {
                detailsTable.setComponentOrientation(o);
                detailsTable.getParent().getParent().setComponentOrientation(o);
            }
        }
    }

    private void ensureIndexIsVisible(int i) {
        if (i >= 0) {
            if (list != null) {
                list.ensureIndexIsVisible(i);
            }
            if (detailsTable != null) {
                detailsTable.scrollRectToVisible(detailsTable.getCellRect(i, COLUMN_FILENAME, true));
            }
        }
    }

    public void ensureFileIsVisible(JFileChooser fc, File f) {
        int modelIndex = getModel().indexOf(f);
        if (modelIndex >= 0) {
            ensureIndexIsVisible(getRowSorter().convertRowIndexToView(modelIndex));
        }
    }

    public void rescanCurrentDirectory() {
        getModel().validateFileCache();
    }

    public void clearSelection() {
        if (listSelectionModel != null) {
            listSelectionModel.clearSelection();
            if (listSelectionModel instanceof DefaultListSelectionModel) {
                ((DefaultListSelectionModel)listSelectionModel).moveLeadSelectionIndex(-1);
                listSelectionModel.setAnchorSelectionIndex(-1);
            }
        }
    }

    public JMenu getViewMenu() {
        if (viewMenu == null) {
            viewMenu = new JMenu(viewMenuLabelText);
            ButtonGroup viewButtonGroup = new ButtonGroup();

            for (int i = 0; i < VIEWTYPE_COUNT; i++) {
                JRadioButtonMenuItem mi =
                    new JRadioButtonMenuItem(new ViewTypeAction(i));
                viewButtonGroup.add(mi);
                viewMenu.add(mi);
            }
            updateViewMenu();
        }
        return viewMenu;
    }

    private void updateViewMenu() {
        if (viewMenu != null) {
            Component[] comps = viewMenu.getMenuComponents();
            for (Component comp : comps) {
                if (comp instanceof JRadioButtonMenuItem) {
                    JRadioButtonMenuItem mi = (JRadioButtonMenuItem) comp;
                    if (((ViewTypeAction)mi.getAction()).viewType == viewType) {
                        mi.setSelected(true);
                    }
                }
            }
        }
    }

    public JPopupMenu getComponentPopupMenu() {
        JPopupMenu popupMenu = getFileChooser().getComponentPopupMenu();
        if (popupMenu != null) {
            return popupMenu;
        }

        JMenu viewMenu = getViewMenu();
        if (contextMenu == null) {
            contextMenu = new JPopupMenu();
            if (viewMenu != null) {
                contextMenu.add(viewMenu);
                if (listViewWindowsStyle) {
                    contextMenu.addSeparator();
                }
            }
            ActionMap actionMap = getActionMap();
            Action refreshAction   = actionMap.get(ACTION_REFRESH);
            Action newFolderAction = actionMap.get(ACTION_NEW_FOLDER);
            if (refreshAction != null) {
                contextMenu.add(refreshAction);
                if (listViewWindowsStyle && newFolderAction != null) {
                    contextMenu.addSeparator();
                }
            }
            if (newFolderAction != null) {
                contextMenu.add(newFolderAction);
            }
        }
        if (viewMenu != null) {
            viewMenu.getPopupMenu().setInvoker(viewMenu);
        }

        contextMenu.applyComponentOrientation(getFileChooser().getComponentOrientation());
        return contextMenu;
    }


    private Handler handler;

    protected Handler getMouseHandler() {
        if (handler == null) {
            handler = new Handler();
        }
        return handler;
    }

    private class Handler implements MouseListener {
        private MouseListener doubleClickListener;

        @SuppressWarnings("deprecation")
        public void mouseClicked(MouseEvent evt) {
            JComponent source = (JComponent)evt.getSource();

            if (!source.isEnabled()) {
                return;
            }

            int index;
            if (source instanceof JList) {
                index = SwingUtilities2.loc2IndexFileList(list, evt.getPoint());
            } else if (source instanceof JTable) {
                JTable table = (JTable)source;
                Point p = evt.getPoint();
                index = table.rowAtPoint(p);

                boolean pointOutsidePrefSize =
                        SwingUtilities2.pointOutsidePrefSize(
                            table, index, table.columnAtPoint(p), p);

                if (pointOutsidePrefSize && !fullRowSelection) {
                    return;
                }

                // Translate point from table to list
                if (index >= 0 && list != null &&
                    listSelectionModel.isSelectedIndex(index)) {

                    // Make a new event with the list as source, placing the
                    // click in the corresponding list cell.
                    Rectangle r = list.getCellBounds(index, index);
                    MouseEvent newEvent = new MouseEvent(list, evt.getID(),
                                         evt.getWhen(), evt.getModifiers(),
                                         r.x + 1, r.y + r.height/2,
                                         evt.getXOnScreen(),
                                         evt.getYOnScreen(),
                                         evt.getClickCount(), evt.isPopupTrigger(),
                                         evt.getButton());
                    MouseEventAccessor meAccessor = AWTAccessor.getMouseEventAccessor();
                    meAccessor.setCausedByTouchEvent(newEvent,
                        meAccessor.isCausedByTouchEvent(evt));
                    evt = newEvent;
                }
            } else {
                return;
            }

            if (index >= 0 && SwingUtilities.isLeftMouseButton(evt)) {
                JFileChooser fc = getFileChooser();

                // For single click, we handle editing file name
                if (evt.getClickCount() == 1 && source instanceof JList) {
                    if ((!fc.isMultiSelectionEnabled() || fc.getSelectedFiles().length <= 1)
                        && index >= 0 && listSelectionModel.isSelectedIndex(index)
                        && getEditIndex() == index && editFile == null) {

                        editFileName(index);
                    } else {
                        if (index >= 0) {
                            setEditIndex(index);
                        } else {
                            resetEditIndex();
                        }
                    }
                } else if (evt.getClickCount() == 2) {
                    // on double click (open or drill down one directory) be
                    // sure to clear the edit index
                    resetEditIndex();
                }
            }

            // Forward event to Basic
            if (getDoubleClickListener() != null) {
                getDoubleClickListener().mouseClicked(evt);
            }
        }

        public void mouseEntered(MouseEvent evt) {
            JComponent source = (JComponent)evt.getSource();
            if (source instanceof JTable) {
                JTable table = (JTable)evt.getSource();

                TransferHandler th1 = getFileChooser().getTransferHandler();
                TransferHandler th2 = table.getTransferHandler();
                if (th1 != th2) {
                    table.setTransferHandler(th1);
                }

                boolean dragEnabled = getFileChooser().getDragEnabled();
                if (dragEnabled != table.getDragEnabled()) {
                    table.setDragEnabled(dragEnabled);
                }
            } else if (source instanceof JList) {
                // Forward event to Basic
                if (getDoubleClickListener() != null) {
                    getDoubleClickListener().mouseEntered(evt);
                }
            }
        }

        public void mouseExited(MouseEvent evt) {
            if (evt.getSource() instanceof JList) {
                // Forward event to Basic
                if (getDoubleClickListener() != null) {
                    getDoubleClickListener().mouseExited(evt);
                }
            }
        }

        public void mousePressed(MouseEvent evt) {
            if (evt.getSource() instanceof JList) {
                // Forward event to Basic
                if (getDoubleClickListener() != null) {
                    getDoubleClickListener().mousePressed(evt);
                }
            }
        }

        public void mouseReleased(MouseEvent evt) {
            if (evt.getSource() instanceof JList) {
                // Forward event to Basic
                if (getDoubleClickListener() != null) {
                    getDoubleClickListener().mouseReleased(evt);
                }
            }
        }

        private MouseListener getDoubleClickListener() {
            // Lazy creation of Basic's listener
            if (doubleClickListener == null && list != null) {
                doubleClickListener =
                    fileChooserUIAccessor.createDoubleClickListener(list);
            }
            return doubleClickListener;
        }
    }

    /**
     * Property to remember whether a directory is currently selected in the UI.
     *
     * @return <code>true</code> iff a directory is currently selected.
     */
    protected boolean isDirectorySelected() {
        return fileChooserUIAccessor.isDirectorySelected();
    }


    /**
     * Property to remember the directory that is currently selected in the UI.
     *
     * @return the value of the <code>directory</code> property
     * @see javax.swing.plaf.basic.BasicFileChooserUI#setDirectory
     */
    protected File getDirectory() {
        return fileChooserUIAccessor.getDirectory();
    }

    private <T> T findChildComponent(Container container, Class<T> cls) {
        int n = container.getComponentCount();
        for (int i = 0; i < n; i++) {
            Component comp = container.getComponent(i);
            if (cls.isInstance(comp)) {
                return cls.cast(comp);
            } else if (comp instanceof Container) {
                T c = findChildComponent((Container)comp, cls);
                if (c != null) {
                    return c;
                }
            }
        }
        return null;
    }

    public boolean canWrite(File f) {
        // Return false for non FileSystem files or if file doesn't exist.
        if (!f.exists()) {
            return false;
        }

        if (f instanceof ShellFolder) {
            return f.canWrite();
        } else {
            if (usesShellFolder(getFileChooser())) {
                try {
                    return ShellFolder.getShellFolder(f).canWrite();
                } catch (FileNotFoundException ex) {
                    // File doesn't exist
                    return false;
                }
            } else {
                // Ordinary file
                return f.canWrite();
            }
        }
    }

    /**
     * Returns true if specified FileChooser should use ShellFolder
     */
    public static boolean usesShellFolder(JFileChooser chooser) {
        Boolean prop = (Boolean) chooser.getClientProperty("FileChooser.useShellFolder");

        return prop == null ? chooser.getFileSystemView().equals(FileSystemView.getFileSystemView())
                : prop.booleanValue();
    }

    // This interface is used to access methods in the FileChooserUI
    // that are not public.
    public interface FileChooserUIAccessor {
        public JFileChooser getFileChooser();
        public BasicDirectoryModel getModel();
        public JPanel createList();
        public JPanel createDetailsView();
        public boolean isDirectorySelected();
        public File getDirectory();
        public Action getApproveSelectionAction();
        public Action getChangeToParentDirectoryAction();
        public Action getNewFolderAction();
        public MouseListener createDoubleClickListener(JList<?> list);
        public ListSelectionListener createListSelectionListener();
    }
}
