2012 lines · 73.4 KB · Java
RawDownload
/* * Copyright (c) 2003, 2009, 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.*;import java.awt.event.*;import java.beans.PropertyChangeEvent;import java.beans.PropertyChangeListener;import java.io.*;import java.text.DateFormat;import java.text.MessageFormat;import java.util.*;import java.util.List;import java.util.concurrent.Callable; import javax.swing.*;import javax.swing.border.*;import javax.swing.event.*;import javax.swing.filechooser.*;import javax.swing.plaf.basic.*;import javax.swing.table.*;import javax.swing.text.*; import sun.awt.shell.*; /** * <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 realies heavily on the * implementation of BasicFileChooserUI, and is intended to be API compatible * with earlier implementations of MetalFileChooserUI and WindowsFileChooserUI. * * @author Leif Samuelsson */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 final static String ACTION_APPROVE_SELECTION = "approveSelection";    public final static String ACTION_CANCEL            = "cancelSelection";    public final static String ACTION_EDIT_FILE_NAME    = "editFileName";    public final static String ACTION_REFRESH           = "refresh";    public final static String ACTION_CHANGE_TO_PARENT_DIRECTORY = "Go Up";    public final static String ACTION_NEW_FOLDER        = "New Folder";    public final static String ACTION_VIEW_LIST         = "viewTypeList";    public final static 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 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 = (JList) 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 = (JTable) 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);    }     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");         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) {            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);

Lines 1–500 of 2012.