Source Code Cross Referenced for FilePane.java in  » 6.0-JDK-Modules-sun » swing » sun » swing » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules sun » swing » sun.swing 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
0003:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004:         *
0005:         * This code is free software; you can redistribute it and/or modify it
0006:         * under the terms of the GNU General Public License version 2 only, as
0007:         * published by the Free Software Foundation.  Sun designates this
0008:         * particular file as subject to the "Classpath" exception as provided
0009:         * by Sun in the LICENSE file that accompanied this code.
0010:         *
0011:         * This code is distributed in the hope that it will be useful, but WITHOUT
0012:         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013:         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0014:         * version 2 for more details (a copy is included in the LICENSE file that
0015:         * accompanied this code).
0016:         *
0017:         * You should have received a copy of the GNU General Public License version
0018:         * 2 along with this work; if not, write to the Free Software Foundation,
0019:         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020:         *
0021:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022:         * CA 95054 USA or visit www.sun.com if you need additional information or
0023:         * have any questions.
0024:         */
0025:        package sun.swing;
0026:
0027:        import java.awt.*;
0028:        import java.awt.event.*;
0029:        import java.beans.PropertyChangeEvent;
0030:        import java.beans.PropertyChangeListener;
0031:        import java.io.*;
0032:        import java.security.AccessControlException;
0033:        import java.text.DateFormat;
0034:        import java.text.MessageFormat;
0035:        import java.util.*;
0036:        import java.util.List;
0037:
0038:        import javax.swing.*;
0039:        import javax.swing.border.*;
0040:        import javax.swing.event.*;
0041:        import javax.swing.filechooser.*;
0042:        import javax.swing.plaf.basic.*;
0043:        import javax.swing.table.*;
0044:        import javax.swing.text.*;
0045:
0046:        import sun.awt.shell.*;
0047:
0048:        /**
0049:         * <b>WARNING:</b> This class is an implementation detail and is only
0050:         * public so that it can be used by two packages. You should NOT consider
0051:         * this public API.
0052:         * <p>
0053:         * This component is intended to be used in a subclass of
0054:         * javax.swing.plaf.basic.BasicFileChooserUI. It realies heavily on the
0055:         * implementation of BasicFileChooserUI, and is intended to be API compatible
0056:         * with earlier implementations of MetalFileChooserUI and WindowsFileChooserUI.
0057:         * 
0058:         * @version 1.41, 05/09/07
0059:         * @author Leif Samuelsson
0060:         */
0061:        public class FilePane extends JPanel implements  PropertyChangeListener {
0062:            // Constants for actions. These are used for the actions' ACTION_COMMAND_KEY
0063:            // and as keys in the action maps for FilePane and the corresponding UI classes
0064:
0065:            public final static String ACTION_APPROVE_SELECTION = "approveSelection";
0066:            public final static String ACTION_CANCEL = "cancelSelection";
0067:            public final static String ACTION_EDIT_FILE_NAME = "editFileName";
0068:            public final static String ACTION_REFRESH = "refresh";
0069:            public final static String ACTION_CHANGE_TO_PARENT_DIRECTORY = "Go Up";
0070:            public final static String ACTION_NEW_FOLDER = "New Folder";
0071:            public final static String ACTION_VIEW_LIST = "viewTypeList";
0072:            public final static String ACTION_VIEW_DETAILS = "viewTypeDetails";
0073:
0074:            private Action[] actions;
0075:
0076:            // "enums" for setViewType()
0077:            public static final int VIEWTYPE_LIST = 0;
0078:            public static final int VIEWTYPE_DETAILS = 1;
0079:            private static final int VIEWTYPE_COUNT = 2;
0080:
0081:            private int viewType = -1;
0082:            private JPanel[] viewPanels = new JPanel[VIEWTYPE_COUNT];
0083:            private JPanel currentViewPanel;
0084:            private String[] viewTypeActionNames;
0085:
0086:            private JPopupMenu contextMenu;
0087:            private JMenu viewMenu;
0088:
0089:            private String viewMenuLabelText;
0090:            private String refreshActionLabelText;
0091:            private String newFolderActionLabelText;
0092:
0093:            private String kiloByteString;
0094:            private String megaByteString;
0095:            private String gigaByteString;
0096:
0097:            private static final Cursor waitCursor = Cursor
0098:                    .getPredefinedCursor(Cursor.WAIT_CURSOR);
0099:
0100:            private final KeyListener detailsKeyListener = new KeyAdapter() {
0101:                private final long timeFactor;
0102:
0103:                private final StringBuilder typedString = new StringBuilder();
0104:
0105:                private long lastTime = 1000L;
0106:
0107:                {
0108:                    Long l = (Long) UIManager.get("Table.timeFactor");
0109:                    timeFactor = (l != null) ? l : 1000L;
0110:                }
0111:
0112:                /**
0113:                 * Moves the keyboard focus to the first element whose prefix matches
0114:                 * the sequence of alphanumeric keys pressed by the user with delay
0115:                 * less than value of <code>timeFactor</code>. Subsequent same key
0116:                 * presses move the keyboard focus to the next object that starts with
0117:                 * the same letter until another key is pressed, then it is treated
0118:                 * as the prefix with appropriate number of the same letters followed
0119:                 * by first typed another letter.
0120:                 */
0121:                public void keyTyped(KeyEvent e) {
0122:                    BasicDirectoryModel model = getModel();
0123:                    int rowCount = model.getSize();
0124:
0125:                    if (detailsTable == null || rowCount == 0 || e.isAltDown()
0126:                            || e.isControlDown() || e.isMetaDown()) {
0127:                        return;
0128:                    }
0129:
0130:                    InputMap inputMap = detailsTable
0131:                            .getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
0132:                    KeyStroke key = KeyStroke.getKeyStrokeForEvent(e);
0133:
0134:                    if (inputMap != null && inputMap.get(key) != null) {
0135:                        return;
0136:                    }
0137:
0138:                    int startIndex = detailsTable.getSelectionModel()
0139:                            .getLeadSelectionIndex();
0140:
0141:                    if (startIndex < 0) {
0142:                        startIndex = 0;
0143:                    }
0144:
0145:                    if (startIndex >= rowCount) {
0146:                        startIndex = rowCount - 1;
0147:                    }
0148:
0149:                    char c = e.getKeyChar();
0150:
0151:                    long time = e.getWhen();
0152:
0153:                    if (time - lastTime < timeFactor) {
0154:                        if (typedString.length() == 1
0155:                                && typedString.charAt(0) == c) {
0156:                            // Subsequent same key presses move the keyboard focus to the next
0157:                            // object that starts with the same letter.
0158:                            startIndex++;
0159:                        } else {
0160:                            typedString.append(c);
0161:                        }
0162:                    } else {
0163:                        startIndex++;
0164:
0165:                        typedString.setLength(0);
0166:                        typedString.append(c);
0167:                    }
0168:
0169:                    lastTime = time;
0170:
0171:                    if (startIndex >= rowCount) {
0172:                        startIndex = 0;
0173:                    }
0174:
0175:                    // Find next file 
0176:                    int index = getNextMatch(startIndex, rowCount - 1);
0177:
0178:                    if (index < 0 && startIndex > 0) { // wrap
0179:                        index = getNextMatch(0, startIndex - 1);
0180:                    }
0181:
0182:                    if (index >= 0) {
0183:                        detailsTable.getSelectionModel().setSelectionInterval(
0184:                                index, index);
0185:
0186:                        Rectangle cellRect = detailsTable
0187:                                .getCellRect(
0188:                                        index,
0189:                                        detailsTable
0190:                                                .convertColumnIndexToView(COLUMN_FILENAME),
0191:                                        false);
0192:                        detailsTable.scrollRectToVisible(cellRect);
0193:                    }
0194:                }
0195:
0196:                private int getNextMatch(int startIndex, int finishIndex) {
0197:                    BasicDirectoryModel model = getModel();
0198:                    JFileChooser fileChooser = getFileChooser();
0199:                    DetailsTableRowSorter rowSorter = getRowSorter();
0200:
0201:                    String prefix = typedString.toString().toLowerCase();
0202:
0203:                    // Search element
0204:                    for (int index = startIndex; index <= finishIndex; index++) {
0205:                        File file = (File) model.getElementAt(rowSorter
0206:                                .convertRowIndexToModel(index));
0207:
0208:                        String fileName = fileChooser.getName(file)
0209:                                .toLowerCase();
0210:
0211:                        if (fileName.startsWith(prefix)) {
0212:                            return index;
0213:                        }
0214:                    }
0215:
0216:                    return -1;
0217:                }
0218:            };
0219:
0220:            private FocusListener editorFocusListener = new FocusAdapter() {
0221:                public void focusLost(FocusEvent e) {
0222:                    if (!e.isTemporary()) {
0223:                        applyEdit();
0224:                    }
0225:                }
0226:            };
0227:
0228:            private static FocusListener repaintListener = new FocusListener() {
0229:                public void focusGained(FocusEvent fe) {
0230:                    repaintSelection(fe.getSource());
0231:                }
0232:
0233:                public void focusLost(FocusEvent fe) {
0234:                    repaintSelection(fe.getSource());
0235:                }
0236:
0237:                private void repaintSelection(Object source) {
0238:                    if (source instanceof  JList) {
0239:                        repaintListSelection((JList) source);
0240:                    } else if (source instanceof  JTable) {
0241:                        repaintTableSelection((JTable) source);
0242:                    }
0243:                }
0244:
0245:                private void repaintListSelection(JList list) {
0246:                    int[] indices = list.getSelectedIndices();
0247:                    for (int i : indices) {
0248:                        Rectangle bounds = list.getCellBounds(i, i);
0249:                        list.repaint(bounds);
0250:                    }
0251:                }
0252:
0253:                private void repaintTableSelection(JTable table) {
0254:                    int minRow = table.getSelectionModel()
0255:                            .getMinSelectionIndex();
0256:                    int maxRow = table.getSelectionModel()
0257:                            .getMaxSelectionIndex();
0258:                    if (minRow == -1 || maxRow == -1) {
0259:                        return;
0260:                    }
0261:
0262:                    int col0 = table.convertColumnIndexToView(COLUMN_FILENAME);
0263:
0264:                    Rectangle first = table.getCellRect(minRow, col0, false);
0265:                    Rectangle last = table.getCellRect(maxRow, col0, false);
0266:                    Rectangle dirty = first.union(last);
0267:                    table.repaint(dirty);
0268:                }
0269:            };
0270:
0271:            private boolean smallIconsView = false;
0272:            private Border listViewBorder;
0273:            private Color listViewBackground;
0274:            private boolean listViewWindowsStyle;
0275:            private boolean readOnly;
0276:
0277:            private ListSelectionModel listSelectionModel;
0278:            private JList list;
0279:            private JTable detailsTable;
0280:
0281:            private static final int COLUMN_FILENAME = 0;
0282:
0283:            // Provides a way to recognize a newly created folder, so it can
0284:            // be selected when it appears in the model.
0285:            private File newFolderFile;
0286:
0287:            // Used for accessing methods in the corresponding UI class
0288:            private FileChooserUIAccessor fileChooserUIAccessor;
0289:            private DetailsTableModel detailsTableModel;
0290:            private DetailsTableRowSorter rowSorter;
0291:
0292:            public FilePane(FileChooserUIAccessor fileChooserUIAccessor) {
0293:                super (new BorderLayout());
0294:
0295:                this .fileChooserUIAccessor = fileChooserUIAccessor;
0296:
0297:                installDefaults();
0298:                createActionMap();
0299:            }
0300:
0301:            public void uninstallUI() {
0302:                if (getModel() != null) {
0303:                    getModel().removePropertyChangeListener(this );
0304:                }
0305:            }
0306:
0307:            protected JFileChooser getFileChooser() {
0308:                return fileChooserUIAccessor.getFileChooser();
0309:            }
0310:
0311:            protected BasicDirectoryModel getModel() {
0312:                return fileChooserUIAccessor.getModel();
0313:            }
0314:
0315:            public int getViewType() {
0316:                return viewType;
0317:            }
0318:
0319:            public void setViewType(int viewType) {
0320:                int oldValue = this .viewType;
0321:                if (viewType == oldValue) {
0322:                    return;
0323:                }
0324:                this .viewType = viewType;
0325:
0326:                switch (viewType) {
0327:                case VIEWTYPE_LIST:
0328:                    if (viewPanels[viewType] == null) {
0329:                        JPanel p = fileChooserUIAccessor.createList();
0330:                        if (p == null) {
0331:                            p = createList();
0332:                        }
0333:                        setViewPanel(viewType, p);
0334:                    }
0335:                    list.setLayoutOrientation(JList.VERTICAL_WRAP);
0336:                    break;
0337:
0338:                case VIEWTYPE_DETAILS:
0339:                    if (viewPanels[viewType] == null) {
0340:                        JPanel p = fileChooserUIAccessor.createDetailsView();
0341:                        if (p == null) {
0342:                            p = createDetailsView();
0343:                        }
0344:                        setViewPanel(viewType, p);
0345:                    }
0346:                    break;
0347:                }
0348:                JPanel oldViewPanel = currentViewPanel;
0349:                currentViewPanel = viewPanels[viewType];
0350:                if (currentViewPanel != oldViewPanel) {
0351:                    if (oldViewPanel != null) {
0352:                        remove(oldViewPanel);
0353:                    }
0354:                    add(currentViewPanel, BorderLayout.CENTER);
0355:                    revalidate();
0356:                    repaint();
0357:                }
0358:                updateViewMenu();
0359:                firePropertyChange("viewType", oldValue, viewType);
0360:            }
0361:
0362:            class ViewTypeAction extends AbstractAction {
0363:                private int viewType;
0364:
0365:                ViewTypeAction(int viewType) {
0366:                    super (viewTypeActionNames[viewType]);
0367:                    this .viewType = viewType;
0368:
0369:                    String cmd;
0370:                    switch (viewType) {
0371:                    case VIEWTYPE_LIST:
0372:                        cmd = ACTION_VIEW_LIST;
0373:                        break;
0374:                    case VIEWTYPE_DETAILS:
0375:                        cmd = ACTION_VIEW_DETAILS;
0376:                        break;
0377:                    default:
0378:                        cmd = (String) getValue(Action.NAME);
0379:                    }
0380:                    putValue(Action.ACTION_COMMAND_KEY, cmd);
0381:                }
0382:
0383:                public void actionPerformed(ActionEvent e) {
0384:                    setViewType(viewType);
0385:                }
0386:            }
0387:
0388:            public Action getViewTypeAction(int viewType) {
0389:                return new ViewTypeAction(viewType);
0390:            }
0391:
0392:            private static void recursivelySetInheritsPopupMenu(
0393:                    Container container, boolean b) {
0394:                if (container instanceof  JComponent) {
0395:                    ((JComponent) container).setInheritsPopupMenu(b);
0396:                }
0397:                int n = container.getComponentCount();
0398:                for (int i = 0; i < n; i++) {
0399:                    recursivelySetInheritsPopupMenu((Container) container
0400:                            .getComponent(i), b);
0401:                }
0402:            }
0403:
0404:            public void setViewPanel(int viewType, JPanel viewPanel) {
0405:                viewPanels[viewType] = viewPanel;
0406:                recursivelySetInheritsPopupMenu(viewPanel, true);
0407:
0408:                switch (viewType) {
0409:                case VIEWTYPE_LIST:
0410:                    list = (JList) findChildComponent(viewPanels[viewType],
0411:                            JList.class);
0412:                    if (listSelectionModel == null) {
0413:                        listSelectionModel = list.getSelectionModel();
0414:                        if (detailsTable != null) {
0415:                            detailsTable.setSelectionModel(listSelectionModel);
0416:                        }
0417:                    } else {
0418:                        list.setSelectionModel(listSelectionModel);
0419:                    }
0420:                    break;
0421:
0422:                case VIEWTYPE_DETAILS:
0423:                    detailsTable = (JTable) findChildComponent(
0424:                            viewPanels[viewType], JTable.class);
0425:                    detailsTable.setRowHeight(Math.max(detailsTable.getFont()
0426:                            .getSize() + 4, 16 + 1));
0427:                    if (listSelectionModel != null) {
0428:                        detailsTable.setSelectionModel(listSelectionModel);
0429:                    }
0430:                    break;
0431:                }
0432:                if (this .viewType == viewType) {
0433:                    if (currentViewPanel != null) {
0434:                        remove(currentViewPanel);
0435:                    }
0436:                    currentViewPanel = viewPanel;
0437:                    add(currentViewPanel, BorderLayout.CENTER);
0438:                    revalidate();
0439:                    repaint();
0440:                }
0441:            }
0442:
0443:            protected void installDefaults() {
0444:                Locale l = getFileChooser().getLocale();
0445:
0446:                listViewBorder = UIManager
0447:                        .getBorder("FileChooser.listViewBorder");
0448:                listViewBackground = UIManager
0449:                        .getColor("FileChooser.listViewBackground");
0450:                listViewWindowsStyle = UIManager
0451:                        .getBoolean("FileChooser.listViewWindowsStyle");
0452:                readOnly = UIManager.getBoolean("FileChooser.readOnly");
0453:
0454:                // TODO: On windows, get the following localized strings from the OS
0455:
0456:                viewMenuLabelText = UIManager.getString(
0457:                        "FileChooser.viewMenuLabelText", l);
0458:                refreshActionLabelText = UIManager.getString(
0459:                        "FileChooser.refreshActionLabelText", l);
0460:                newFolderActionLabelText = UIManager.getString(
0461:                        "FileChooser.newFolderActionLabelText", l);
0462:
0463:                viewTypeActionNames = new String[VIEWTYPE_COUNT];
0464:                viewTypeActionNames[VIEWTYPE_LIST] = UIManager.getString(
0465:                        "FileChooser.listViewActionLabelText", l);
0466:                viewTypeActionNames[VIEWTYPE_DETAILS] = UIManager.getString(
0467:                        "FileChooser.detailsViewActionLabelText", l);
0468:
0469:                kiloByteString = UIManager.getString(
0470:                        "FileChooser.fileSizeKiloBytes", l);
0471:                megaByteString = UIManager.getString(
0472:                        "FileChooser.fileSizeMegaBytes", l);
0473:                gigaByteString = UIManager.getString(
0474:                        "FileChooser.fileSizeGigaBytes", l);
0475:            }
0476:
0477:            /**
0478:             * Fetches the command list for the FilePane. These commands
0479:             * are useful for binding to events, such as in a keymap.
0480:             *
0481:             * @return the command list
0482:             */
0483:            public Action[] getActions() {
0484:                if (actions == null) {
0485:                    class FilePaneAction extends AbstractAction {
0486:                        FilePaneAction(String name) {
0487:                            this (name, name);
0488:                        }
0489:
0490:                        FilePaneAction(String name, String cmd) {
0491:                            super (name);
0492:                            putValue(Action.ACTION_COMMAND_KEY, cmd);
0493:                        }
0494:
0495:                        public void actionPerformed(ActionEvent e) {
0496:                            String cmd = (String) getValue(Action.ACTION_COMMAND_KEY);
0497:
0498:                            if (cmd == ACTION_CANCEL) {
0499:                                if (editFile != null) {
0500:                                    cancelEdit();
0501:                                } else {
0502:                                    getFileChooser().cancelSelection();
0503:                                }
0504:                            } else if (cmd == ACTION_EDIT_FILE_NAME) {
0505:                                JFileChooser fc = getFileChooser();
0506:                                int index = listSelectionModel
0507:                                        .getMinSelectionIndex();
0508:                                if (index >= 0
0509:                                        && editFile == null
0510:                                        && (!fc.isMultiSelectionEnabled() || fc
0511:                                                .getSelectedFiles().length <= 1)) {
0512:
0513:                                    editFileName(index);
0514:                                }
0515:                            } else if (cmd == ACTION_REFRESH) {
0516:                                getFileChooser().rescanCurrentDirectory();
0517:                            }
0518:                        }
0519:
0520:                        public boolean isEnabled() {
0521:                            String cmd = (String) getValue(Action.ACTION_COMMAND_KEY);
0522:                            if (cmd == ACTION_CANCEL) {
0523:                                return getFileChooser().isEnabled();
0524:                            } else if (cmd == ACTION_EDIT_FILE_NAME) {
0525:                                return !readOnly
0526:                                        && getFileChooser().isEnabled();
0527:                            } else {
0528:                                return true;
0529:                            }
0530:                        }
0531:                    }
0532:
0533:                    ArrayList<Action> actionList = new ArrayList<Action>(8);
0534:                    Action action;
0535:
0536:                    actionList.add(new FilePaneAction(ACTION_CANCEL));
0537:                    actionList.add(new FilePaneAction(ACTION_EDIT_FILE_NAME));
0538:                    actionList.add(new FilePaneAction(refreshActionLabelText,
0539:                            ACTION_REFRESH));
0540:
0541:                    action = fileChooserUIAccessor.getApproveSelectionAction();
0542:                    if (action != null) {
0543:                        actionList.add(action);
0544:                    }
0545:                    action = fileChooserUIAccessor
0546:                            .getChangeToParentDirectoryAction();
0547:                    if (action != null) {
0548:                        actionList.add(action);
0549:                    }
0550:                    action = getNewFolderAction();
0551:                    if (action != null) {
0552:                        actionList.add(action);
0553:                    }
0554:                    action = getViewTypeAction(VIEWTYPE_LIST);
0555:                    if (action != null) {
0556:                        actionList.add(action);
0557:                    }
0558:                    action = getViewTypeAction(VIEWTYPE_DETAILS);
0559:                    if (action != null) {
0560:                        actionList.add(action);
0561:                    }
0562:                    actions = actionList.toArray(new Action[actionList.size()]);
0563:                }
0564:
0565:                return actions;
0566:            }
0567:
0568:            protected void createActionMap() {
0569:                addActionsToMap(super .getActionMap(), getActions());
0570:            }
0571:
0572:            public static void addActionsToMap(ActionMap map, Action[] actions) {
0573:                if (map != null && actions != null) {
0574:                    for (int i = 0; i < actions.length; i++) {
0575:                        Action a = actions[i];
0576:                        String cmd = (String) a
0577:                                .getValue(Action.ACTION_COMMAND_KEY);
0578:                        if (cmd == null) {
0579:                            cmd = (String) a.getValue(Action.NAME);
0580:                        }
0581:                        map.put(cmd, a);
0582:                    }
0583:                }
0584:            }
0585:
0586:            private void updateListRowCount(JList list) {
0587:                if (smallIconsView) {
0588:                    list.setVisibleRowCount(getModel().getSize() / 3);
0589:                } else {
0590:                    list.setVisibleRowCount(-1);
0591:                }
0592:            }
0593:
0594:            public JPanel createList() {
0595:                JPanel p = new JPanel(new BorderLayout());
0596:                final JFileChooser fileChooser = getFileChooser();
0597:                final JList list = new JList() {
0598:                    public int getNextMatch(String prefix, int startIndex,
0599:                            Position.Bias bias) {
0600:                        ListModel model = getModel();
0601:                        int max = model.getSize();
0602:                        if (prefix == null || startIndex < 0
0603:                                || startIndex >= max) {
0604:                            throw new IllegalArgumentException();
0605:                        }
0606:                        // start search from the next element before/after the selected element
0607:                        boolean backwards = (bias == Position.Bias.Backward);
0608:                        for (int i = startIndex; backwards ? i >= 0 : i < max; i += (backwards ? -1
0609:                                : 1)) {
0610:                            String filename = fileChooser.getName((File) model
0611:                                    .getElementAt(i));
0612:                            if (filename.regionMatches(true, 0, prefix, 0,
0613:                                    prefix.length())) {
0614:                                return i;
0615:                            }
0616:                        }
0617:                        return -1;
0618:                    }
0619:                };
0620:                list.setCellRenderer(new FileRenderer());
0621:                list.setLayoutOrientation(JList.VERTICAL_WRAP);
0622:
0623:                // 4835633 : tell BasicListUI that this is a file list
0624:                list.putClientProperty("List.isFileList", Boolean.TRUE);
0625:
0626:                if (listViewWindowsStyle) {
0627:                    list.addFocusListener(repaintListener);
0628:                }
0629:
0630:                updateListRowCount(list);
0631:
0632:                getModel().addListDataListener(new ListDataListener() {
0633:                    public void intervalAdded(ListDataEvent e) {
0634:                        updateListRowCount(list);
0635:                    }
0636:
0637:                    public void intervalRemoved(ListDataEvent e) {
0638:                        updateListRowCount(list);
0639:                    }
0640:
0641:                    public void contentsChanged(ListDataEvent e) {
0642:                        if (isShowing()) {
0643:                            clearSelection();
0644:                        }
0645:                        updateListRowCount(list);
0646:                    }
0647:                });
0648:
0649:                getModel().addPropertyChangeListener(this );
0650:
0651:                if (fileChooser.isMultiSelectionEnabled()) {
0652:                    list
0653:                            .setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
0654:                } else {
0655:                    list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
0656:                }
0657:                list.setModel(new SortableListModel());
0658:
0659:                list.addListSelectionListener(createListSelectionListener());
0660:                list.addMouseListener(getMouseHandler());
0661:
0662:                JScrollPane scrollpane = new JScrollPane(list);
0663:                if (listViewBackground != null) {
0664:                    list.setBackground(listViewBackground);
0665:                }
0666:                if (listViewBorder != null) {
0667:                    scrollpane.setBorder(listViewBorder);
0668:                }
0669:                p.add(scrollpane, BorderLayout.CENTER);
0670:                return p;
0671:            }
0672:
0673:            /**
0674:             * This model allows for sorting JList
0675:             */
0676:            private class SortableListModel extends AbstractListModel implements 
0677:                    TableModelListener, RowSorterListener {
0678:
0679:                public SortableListModel() {
0680:                    getDetailsTableModel().addTableModelListener(this );
0681:                    getRowSorter().addRowSorterListener(this );
0682:                }
0683:
0684:                public int getSize() {
0685:                    return getModel().getSize();
0686:                }
0687:
0688:                public Object getElementAt(int index) {
0689:                    // JList doesn't support RowSorter so far, so we put it into the list model
0690:                    return getModel().getElementAt(
0691:                            getRowSorter().convertRowIndexToModel(index));
0692:                }
0693:
0694:                public void tableChanged(TableModelEvent e) {
0695:                    fireContentsChanged(this , 0, getSize());
0696:                }
0697:
0698:                public void sorterChanged(RowSorterEvent e) {
0699:                    fireContentsChanged(this , 0, getSize());
0700:                }
0701:            }
0702:
0703:            private DetailsTableModel getDetailsTableModel() {
0704:                if (detailsTableModel == null) {
0705:                    detailsTableModel = new DetailsTableModel(getFileChooser());
0706:                }
0707:                return detailsTableModel;
0708:            }
0709:
0710:            class DetailsTableModel extends AbstractTableModel implements 
0711:                    ListDataListener {
0712:                JFileChooser chooser;
0713:                BasicDirectoryModel directoryModel;
0714:
0715:                ShellFolderColumnInfo[] columns;
0716:                int[] columnMap;
0717:
0718:                DetailsTableModel(JFileChooser fc) {
0719:                    this .chooser = fc;
0720:                    directoryModel = getModel();
0721:                    directoryModel.addListDataListener(this );
0722:
0723:                    updateColumnInfo();
0724:                }
0725:
0726:                void updateColumnInfo() {
0727:                    File dir = chooser.getCurrentDirectory();
0728:                    if (dir != null && fileChooserUIAccessor.usesShellFolder()) {
0729:                        try {
0730:                            dir = ShellFolder.getShellFolder(dir);
0731:                        } catch (FileNotFoundException e) {
0732:                            // Leave dir without changing
0733:                        }
0734:                    }
0735:
0736:                    ShellFolderColumnInfo[] allColumns = ShellFolder
0737:                            .getFolderColumns(dir);
0738:
0739:                    ArrayList<ShellFolderColumnInfo> visibleColumns = new ArrayList<ShellFolderColumnInfo>();
0740:                    columnMap = new int[allColumns.length];
0741:                    for (int i = 0; i < allColumns.length; i++) {
0742:                        ShellFolderColumnInfo column = allColumns[i];
0743:                        if (column.isVisible()) {
0744:                            columnMap[visibleColumns.size()] = i;
0745:                            visibleColumns.add(column);
0746:                        }
0747:                    }
0748:
0749:                    columns = new ShellFolderColumnInfo[visibleColumns.size()];
0750:                    visibleColumns.toArray(columns);
0751:                    columnMap = Arrays.copyOf(columnMap, columns.length);
0752:
0753:                    List<RowSorter.SortKey> sortKeys = (rowSorter == null) ? null
0754:                            : rowSorter.getSortKeys();
0755:                    fireTableStructureChanged();
0756:                    restoreSortKeys(sortKeys);
0757:                }
0758:
0759:                private void restoreSortKeys(List<RowSorter.SortKey> sortKeys) {
0760:                    if (sortKeys != null) {
0761:                        // check if preserved sortKeys are valid for this folder
0762:                        for (int i = 0; i < sortKeys.size(); i++) {
0763:                            RowSorter.SortKey sortKey = sortKeys.get(i);
0764:                            if (sortKey.getColumn() >= columns.length) {
0765:                                sortKeys = null;
0766:                                break;
0767:                            }
0768:                        }
0769:                        if (sortKeys != null) {
0770:                            rowSorter.setSortKeys(sortKeys);
0771:                        }
0772:                    }
0773:                }
0774:
0775:                public int getRowCount() {
0776:                    return directoryModel.getSize();
0777:                }
0778:
0779:                public int getColumnCount() {
0780:                    return columns.length;
0781:                }
0782:
0783:                public Object getValueAt(int row, int col) {
0784:                    // Note: It is very important to avoid getting info on drives, as
0785:                    // this will trigger "No disk in A:" and similar dialogs.
0786:                    //
0787:                    // Use (f.exists() && !chooser.getFileSystemView().isFileSystemRoot(f)) to
0788:                    // determine if it is safe to call methods directly on f.
0789:                    return getFileColumnValue((File) directoryModel
0790:                            .getElementAt(row), col);
0791:                }
0792:
0793:                private Object getFileColumnValue(File f, int col) {
0794:                    return (col == COLUMN_FILENAME) ? f // always return the file itself for the 1st column
0795:                            : ShellFolder.getFolderColumnValue(f,
0796:                                    columnMap[col]);
0797:                }
0798:
0799:                public void setValueAt(Object value, int row, int col) {
0800:                    if (col == COLUMN_FILENAME) {
0801:                        JFileChooser chooser = getFileChooser();
0802:                        File f = (File) getValueAt(row, col);
0803:                        if (f != null) {
0804:                            String oldDisplayName = chooser.getName(f);
0805:                            String oldFileName = f.getName();
0806:                            String newDisplayName = ((String) value).trim();
0807:                            String newFileName;
0808:
0809:                            if (!newDisplayName.equals(oldDisplayName)) {
0810:                                newFileName = newDisplayName;
0811:                                //Check if extension is hidden from user
0812:                                int i1 = oldFileName.length();
0813:                                int i2 = oldDisplayName.length();
0814:                                if (i1 > i2 && oldFileName.charAt(i2) == '.') {
0815:                                    newFileName = newDisplayName
0816:                                            + oldFileName.substring(i2);
0817:                                }
0818:
0819:                                // rename
0820:                                FileSystemView fsv = chooser
0821:                                        .getFileSystemView();
0822:                                File f2 = fsv.createFileObject(f
0823:                                        .getParentFile(), newFileName);
0824:                                if (!f2.exists()
0825:                                        && FilePane.this .getModel().renameFile(
0826:                                                f, f2)) {
0827:                                    if (fsv.isParent(chooser
0828:                                            .getCurrentDirectory(), f2)) {
0829:                                        if (chooser.isMultiSelectionEnabled()) {
0830:                                            chooser
0831:                                                    .setSelectedFiles(new File[] { f2 });
0832:                                        } else {
0833:                                            chooser.setSelectedFile(f2);
0834:                                        }
0835:                                    } else {
0836:                                        //Could be because of delay in updating Desktop folder
0837:                                        //chooser.setSelectedFile(null);
0838:                                    }
0839:                                } else {
0840:                                    // PENDING(jeff) - show a dialog indicating failure
0841:                                }
0842:                            }
0843:                        }
0844:                    }
0845:                }
0846:
0847:                public boolean isCellEditable(int row, int column) {
0848:                    File currentDirectory = getFileChooser()
0849:                            .getCurrentDirectory();
0850:                    return (!readOnly && column == COLUMN_FILENAME && canWrite(currentDirectory));
0851:                }
0852:
0853:                public void contentsChanged(ListDataEvent e) {
0854:                    // Update the selection after the model has been updated
0855:                    new DelayedSelectionUpdater();
0856:                    fireTableDataChanged();
0857:                }
0858:
0859:                public void intervalAdded(ListDataEvent e) {
0860:                    int i0 = e.getIndex0();
0861:                    int i1 = e.getIndex1();
0862:                    if (i0 == i1) {
0863:                        File file = (File) getModel().getElementAt(i0);
0864:                        if (file.equals(newFolderFile)) {
0865:                            new DelayedSelectionUpdater(file);
0866:                            newFolderFile = null;
0867:                        }
0868:                    }
0869:
0870:                    fireTableRowsInserted(e.getIndex0(), e.getIndex1());
0871:                }
0872:
0873:                public void intervalRemoved(ListDataEvent e) {
0874:                    fireTableRowsDeleted(e.getIndex0(), e.getIndex1());
0875:                }
0876:
0877:                public ShellFolderColumnInfo[] getColumns() {
0878:                    return columns;
0879:                }
0880:            }
0881:
0882:            private void updateDetailsColumnModel(JTable table) {
0883:                if (table != null) {
0884:                    ShellFolderColumnInfo[] columns = detailsTableModel
0885:                            .getColumns();
0886:
0887:                    TableColumnModel columnModel = new DefaultTableColumnModel();
0888:                    for (int i = 0; i < columns.length; i++) {
0889:                        ShellFolderColumnInfo dataItem = columns[i];
0890:                        TableColumn column = new TableColumn(i);
0891:
0892:                        String title = dataItem.getTitle();
0893:                        if (title != null && title.startsWith("FileChooser.")
0894:                                && title.endsWith("HeaderText")) {
0895:                            // the column must have a string resource that we try to get
0896:                            String uiTitle = UIManager.getString(title, table
0897:                                    .getLocale());
0898:                            if (uiTitle != null) {
0899:                                title = uiTitle;
0900:                            }
0901:                        }
0902:                        column.setHeaderValue(title);
0903:
0904:                        Integer width = dataItem.getWidth();
0905:                        if (width != null) {
0906:                            column.setPreferredWidth(width);
0907:                            // otherwise we let JTable to decide the actual width
0908:                        }
0909:
0910:                        columnModel.addColumn(column);
0911:                    }
0912:
0913:                    // Install cell editor for editing file name
0914:                    if (!readOnly
0915:                            && columnModel.getColumnCount() > COLUMN_FILENAME) {
0916:                        columnModel.getColumn(COLUMN_FILENAME).setCellEditor(
0917:                                getDetailsTableCellEditor());
0918:                    }
0919:
0920:                    table.setColumnModel(columnModel);
0921:                }
0922:            }
0923:
0924:            private DetailsTableRowSorter getRowSorter() {
0925:                if (rowSorter == null) {
0926:                    rowSorter = new DetailsTableRowSorter();
0927:                }
0928:                return rowSorter;
0929:            }
0930:
0931:            private class DetailsTableRowSorter extends TableRowSorter {
0932:                public DetailsTableRowSorter() {
0933:                    setModelWrapper(new SorterModelWrapper());
0934:                }
0935:
0936:                public void updateComparators(ShellFolderColumnInfo[] columns) {
0937:                    for (int i = 0; i < columns.length; i++) {
0938:                        Comparator c = columns[i].getComparator();
0939:                        if (c != null) {
0940:                            c = new DirectoriesFirstComparatorWrapper(i, c);
0941:                        }
0942:                        setComparator(i, c);
0943:                    }
0944:                }
0945:
0946:                public void modelStructureChanged() {
0947:                    super .modelStructureChanged();
0948:                    updateComparators(detailsTableModel.getColumns());
0949:                }
0950:
0951:                private class SorterModelWrapper extends ModelWrapper {
0952:                    public Object getModel() {
0953:                        return getDetailsTableModel();
0954:                    }
0955:
0956:                    public int getColumnCount() {
0957:                        return getDetailsTableModel().getColumnCount();
0958:                    }
0959:
0960:                    public int getRowCount() {
0961:                        return getDetailsTableModel().getRowCount();
0962:                    }
0963:
0964:                    public Object getValueAt(int row, int column) {
0965:                        return FilePane.this .getModel().getElementAt(row);
0966:                    }
0967:
0968:                    public Object getIdentifier(int row) {
0969:                        return row;
0970:                    }
0971:                }
0972:            }
0973:
0974:            /**
0975:             * This class sorts directories before files, comparing directory to
0976:             * directory and file to file using the wrapped comparator.
0977:             */
0978:            private class DirectoriesFirstComparatorWrapper implements 
0979:                    Comparator<File> {
0980:                private Comparator comparator;
0981:                private int column;
0982:
0983:                public DirectoriesFirstComparatorWrapper(int column,
0984:                        Comparator comparator) {
0985:                    this .column = column;
0986:                    this .comparator = comparator;
0987:                }
0988:
0989:                public int compare(File f1, File f2) {
0990:                    if (f1 != null && f2 != null) {
0991:                        boolean traversable1 = getFileChooser().isTraversable(
0992:                                f1);
0993:                        boolean traversable2 = getFileChooser().isTraversable(
0994:                                f2);
0995:                        // directories go first
0996:                        if (traversable1 && !traversable2) {
0997:                            return -1;
0998:                        }
0999:                        if (!traversable1 && traversable2) {
1000:                            return 1;
1001:                        }
1002:                    }
1003:                    if (detailsTableModel.getColumns()[column]
1004:                            .isCompareByColumn()) {
1005:                        return comparator.compare(getDetailsTableModel()
1006:                                .getFileColumnValue(f1, column),
1007:                                getDetailsTableModel().getFileColumnValue(f2,
1008:                                        column));
1009:                    }
1010:                    // For this column we need to pass the file itself (not a
1011:                    // column value) to the comparator
1012:                    return comparator.compare(f1, f2);
1013:                }
1014:            }
1015:
1016:            private DetailsTableCellEditor tableCellEditor;
1017:
1018:            private DetailsTableCellEditor getDetailsTableCellEditor() {
1019:                if (tableCellEditor == null) {
1020:                    tableCellEditor = new DetailsTableCellEditor(
1021:                            new JTextField());
1022:                }
1023:                return tableCellEditor;
1024:            }
1025:
1026:            private class DetailsTableCellEditor extends DefaultCellEditor {
1027:                private final JTextField tf;
1028:
1029:                public DetailsTableCellEditor(JTextField tf) {
1030:                    super (tf);
1031:                    this .tf = tf;
1032:                    tf.addFocusListener(editorFocusListener);
1033:                }
1034:
1035:                public Component getTableCellEditorComponent(JTable table,
1036:                        Object value, boolean isSelected, int row, int column) {
1037:                    Component comp = super .getTableCellEditorComponent(table,
1038:                            value, isSelected, row, column);
1039:                    if (value instanceof  File) {
1040:                        tf.setText(getFileChooser().getName((File) value));
1041:                        tf.selectAll();
1042:                    }
1043:                    return comp;
1044:                }
1045:            }
1046:
1047:            class DetailsTableCellRenderer extends DefaultTableCellRenderer {
1048:                JFileChooser chooser;
1049:                DateFormat df;
1050:
1051:                DetailsTableCellRenderer(JFileChooser chooser) {
1052:                    this .chooser = chooser;
1053:                    df = DateFormat.getDateTimeInstance(DateFormat.SHORT,
1054:                            DateFormat.SHORT, chooser.getLocale());
1055:                }
1056:
1057:                public void setBounds(int x, int y, int width, int height) {
1058:                    if (getHorizontalAlignment() == SwingConstants.LEADING) {
1059:                        // Restrict width to actual text
1060:                        width = Math.min(width,
1061:                                this .getPreferredSize().width + 4);
1062:                    } else {
1063:                        x -= 4;
1064:                    }
1065:                    super .setBounds(x, y, width, height);
1066:                }
1067:
1068:                public Insets getInsets(Insets i) {
1069:                    // Provide some space between columns
1070:                    i = super .getInsets(i);
1071:                    i.left += 4;
1072:                    i.right += 4;
1073:                    return i;
1074:                }
1075:
1076:                public Component getTableCellRendererComponent(JTable table,
1077:                        Object value, boolean isSelected, boolean hasFocus,
1078:                        int row, int column) {
1079:
1080:                    if (table.convertColumnIndexToModel(column) != COLUMN_FILENAME
1081:                            || (listViewWindowsStyle && !table.isFocusOwner())) {
1082:
1083:                        isSelected = false;
1084:                    }
1085:
1086:                    super .getTableCellRendererComponent(table, value,
1087:                            isSelected, hasFocus, row, column);
1088:
1089:                    setIcon(null);
1090:
1091:                    int modelColumn = table.convertColumnIndexToModel(column);
1092:                    ShellFolderColumnInfo columnInfo = detailsTableModel
1093:                            .getColumns()[modelColumn];
1094:
1095:                    Integer alignment = columnInfo.getAlignment();
1096:                    if (alignment == null) {
1097:                        alignment = (value instanceof  Number) ? SwingConstants.RIGHT
1098:                                : SwingConstants.LEADING;
1099:                    }
1100:
1101:                    setHorizontalAlignment(alignment);
1102:
1103:                    // formatting cell text
1104:                    // TODO: it's rather a temporary trick, to be revised
1105:                    String text;
1106:
1107:                    if (value == null) {
1108:                        text = "";
1109:
1110:                    } else if (value instanceof  File) {
1111:                        File file = (File) value;
1112:                        text = chooser.getName(file);
1113:                        Icon icon = chooser.getIcon(file);
1114:                        setIcon(icon);
1115:
1116:                    } else if (value instanceof  Long) {
1117:                        long len = ((Long) value) / 1024L;
1118:                        if (listViewWindowsStyle) {
1119:                            text = MessageFormat
1120:                                    .format(kiloByteString, len + 1);
1121:                        } else if (len < 1024L) {
1122:                            text = MessageFormat.format(kiloByteString,
1123:                                    (len == 0L) ? 1L : len);
1124:                        } else {
1125:                            len /= 1024L;
1126:                            if (len < 1024L) {
1127:                                text = MessageFormat
1128:                                        .format(megaByteString, len);
1129:                            } else {
1130:                                len /= 1024L;
1131:                                text = MessageFormat
1132:                                        .format(gigaByteString, len);
1133:                            }
1134:                        }
1135:
1136:                    } else if (value instanceof  Date) {
1137:                        text = df.format((Date) value);
1138:
1139:                    } else {
1140:                        text = value.toString();
1141:                    }
1142:
1143:                    setText(text);
1144:
1145:                    return this ;
1146:                }
1147:            }
1148:
1149:            public JPanel createDetailsView() {
1150:                final JFileChooser chooser = getFileChooser();
1151:
1152:                JPanel p = new JPanel(new BorderLayout());
1153:
1154:                final JTable detailsTable = new JTable(getDetailsTableModel()) {
1155:                    // Handle Escape key events here
1156:                    protected boolean processKeyBinding(KeyStroke ks,
1157:                            KeyEvent e, int condition, boolean pressed) {
1158:                        if (e.getKeyCode() == KeyEvent.VK_ESCAPE
1159:                                && getCellEditor() == null) {
1160:                            // We are not editing, forward to filechooser.
1161:                            chooser.dispatchEvent(e);
1162:                            return true;
1163:                        }
1164:                        return super .processKeyBinding(ks, e, condition,
1165:                                pressed);
1166:                    }
1167:
1168:                    public void tableChanged(TableModelEvent e) {
1169:                        super .tableChanged(e);
1170:
1171:                        if (e.getFirstRow() == TableModelEvent.HEADER_ROW) {
1172:                            // update header with possibly changed column set
1173:                            updateDetailsColumnModel(this );
1174:                        }
1175:                    }
1176:                };
1177:
1178:                detailsTable.setRowSorter(getRowSorter());
1179:                detailsTable.setAutoCreateColumnsFromModel(false);
1180:                detailsTable.setComponentOrientation(chooser
1181:                        .getComponentOrientation());
1182:                detailsTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
1183:                detailsTable.setShowGrid(false);
1184:                detailsTable.putClientProperty("JTable.autoStartsEdit",
1185:                        Boolean.FALSE);
1186:                detailsTable.addKeyListener(detailsKeyListener);
1187:
1188:                Font font = list.getFont();
1189:                detailsTable.setFont(font);
1190:                detailsTable.setIntercellSpacing(new Dimension(0, 0));
1191:
1192:                TableCellRenderer headerRenderer = new AlignableTableHeaderRenderer(
1193:                        detailsTable.getTableHeader().getDefaultRenderer());
1194:                detailsTable.getTableHeader()
1195:                        .setDefaultRenderer(headerRenderer);
1196:                TableCellRenderer cellRenderer = new DetailsTableCellRenderer(
1197:                        chooser);
1198:                detailsTable.setDefaultRenderer(Object.class, cellRenderer);
1199:
1200:                // So that drag can be started on a mouse press
1201:                detailsTable.getColumnModel().getSelectionModel()
1202:                        .setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
1203:
1204:                detailsTable.addMouseListener(getMouseHandler());
1205:                // No need to addListSelectionListener because selections are forwarded
1206:                // to our JList.
1207:
1208:                // 4835633 : tell BasicTableUI that this is a file list
1209:                detailsTable
1210:                        .putClientProperty("Table.isFileList", Boolean.TRUE);
1211:
1212:                if (listViewWindowsStyle) {
1213:                    detailsTable.addFocusListener(repaintListener);
1214:                }
1215:
1216:                // TAB/SHIFT-TAB should transfer focus and ENTER should select an item.
1217:                // We don't want them to navigate within the table
1218:                ActionMap am = SwingUtilities.getUIActionMap(detailsTable);
1219:                am.remove("selectNextRowCell");
1220:                am.remove("selectPreviousRowCell");
1221:                am.remove("selectNextColumnCell");
1222:                am.remove("selectPreviousColumnCell");
1223:                detailsTable.setFocusTraversalKeys(
1224:                        KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, null);
1225:                detailsTable.setFocusTraversalKeys(
1226:                        KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, null);
1227:
1228:                JScrollPane scrollpane = new JScrollPane(detailsTable);
1229:                scrollpane.setComponentOrientation(chooser
1230:                        .getComponentOrientation());
1231:                LookAndFeel.installColors(scrollpane.getViewport(),
1232:                        "Table.background", "Table.foreground");
1233:
1234:                // Adjust width of first column so the table fills the viewport when
1235:                // first displayed (temporary listener).
1236:                scrollpane.addComponentListener(new ComponentAdapter() {
1237:                    public void componentResized(ComponentEvent e) {
1238:                        JScrollPane sp = (JScrollPane) e.getComponent();
1239:                        fixNameColumnWidth(sp.getViewport().getSize().width);
1240:                        sp.removeComponentListener(this );
1241:                    }
1242:                });
1243:
1244:                // 4835633.
1245:                // If the mouse is pressed in the area below the Details view table, the
1246:                // event is not dispatched to the Table MouseListener but to the
1247:                // scrollpane.  Listen for that here so we can clear the selection.
1248:                scrollpane.addMouseListener(new MouseAdapter() {
1249:                    public void mousePressed(MouseEvent e) {
1250:                        JScrollPane jsp = ((JScrollPane) e.getComponent());
1251:                        JTable table = (JTable) jsp.getViewport().getView();
1252:
1253:                        if (!e.isShiftDown()
1254:                                || table.getSelectionModel().getSelectionMode() == ListSelectionModel.SINGLE_SELECTION) {
1255:                            clearSelection();
1256:                            TableCellEditor tce = table.getCellEditor();
1257:                            if (tce != null) {
1258:                                tce.stopCellEditing();
1259:                            }
1260:                        }
1261:                    }
1262:                });
1263:
1264:                detailsTable.setForeground(list.getForeground());
1265:                detailsTable.setBackground(list.getBackground());
1266:
1267:                if (listViewBorder != null) {
1268:                    scrollpane.setBorder(listViewBorder);
1269:                }
1270:                p.add(scrollpane, BorderLayout.CENTER);
1271:
1272:                detailsTableModel.fireTableStructureChanged();
1273:
1274:                return p;
1275:            } // createDetailsView
1276:
1277:            private class AlignableTableHeaderRenderer implements 
1278:                    TableCellRenderer {
1279:                TableCellRenderer wrappedRenderer;
1280:
1281:                public AlignableTableHeaderRenderer(
1282:                        TableCellRenderer wrappedRenderer) {
1283:                    this .wrappedRenderer = wrappedRenderer;
1284:                }
1285:
1286:                public Component getTableCellRendererComponent(JTable table,
1287:                        Object value, boolean isSelected, boolean hasFocus,
1288:                        int row, int column) {
1289:
1290:                    Component c = wrappedRenderer
1291:                            .getTableCellRendererComponent(table, value,
1292:                                    isSelected, hasFocus, row, column);
1293:
1294:                    int modelColumn = table.convertColumnIndexToModel(column);
1295:                    ShellFolderColumnInfo columnInfo = detailsTableModel
1296:                            .getColumns()[modelColumn];
1297:
1298:                    Integer alignment = columnInfo.getAlignment();
1299:                    if (alignment == null) {
1300:                        alignment = SwingConstants.CENTER;
1301:                    }
1302:                    if (c instanceof  JLabel) {
1303:                        ((JLabel) c).setHorizontalAlignment(alignment);
1304:                    }
1305:
1306:                    return c;
1307:                }
1308:            }
1309:
1310:            private void fixNameColumnWidth(int viewWidth) {
1311:                TableColumn nameCol = detailsTable.getColumnModel().getColumn(
1312:                        COLUMN_FILENAME);
1313:                int tableWidth = detailsTable.getPreferredSize().width;
1314:
1315:                if (tableWidth < viewWidth) {
1316:                    nameCol.setPreferredWidth(nameCol.getPreferredWidth()
1317:                            + viewWidth - tableWidth);
1318:                }
1319:            }
1320:
1321:            private class DelayedSelectionUpdater implements  Runnable {
1322:                File editFile;
1323:
1324:                DelayedSelectionUpdater() {
1325:                    this (null);
1326:                }
1327:
1328:                DelayedSelectionUpdater(File editFile) {
1329:                    this .editFile = editFile;
1330:                    if (isShowing()) {
1331:                        SwingUtilities.invokeLater(this );
1332:                    }
1333:                }
1334:
1335:                public void run() {
1336:                    setFileSelected();
1337:                    if (editFile != null) {
1338:                        editFileName(getRowSorter().convertRowIndexToView(
1339:                                getModel().indexOf(editFile)));
1340:                        editFile = null;
1341:                    }
1342:                }
1343:            }
1344:
1345:            /**
1346:             * Creates a selection listener for the list of files and directories.
1347:             *
1348:             * @return a <code>ListSelectionListener</code>
1349:             */
1350:            public ListSelectionListener createListSelectionListener() {
1351:                return fileChooserUIAccessor.createListSelectionListener();
1352:            }
1353:
1354:            int lastIndex = -1;
1355:            File editFile = null;
1356:            int editX = 20;
1357:
1358:            private int getEditIndex() {
1359:                return lastIndex;
1360:            }
1361:
1362:            private void setEditIndex(int i) {
1363:                lastIndex = i;
1364:            }
1365:
1366:            private void resetEditIndex() {
1367:                lastIndex = -1;
1368:            }
1369:
1370:            private void cancelEdit() {
1371:                if (editFile != null) {
1372:                    editFile = null;
1373:                    list.remove(editCell);
1374:                    repaint();
1375:                } else if (detailsTable != null && detailsTable.isEditing()) {
1376:                    detailsTable.getCellEditor().cancelCellEditing();
1377:                }
1378:            }
1379:
1380:            JTextField editCell = null;
1381:
1382:            /**
1383:             * @param index visual index of the file to be edited
1384:             */
1385:            private void editFileName(int index) {
1386:                File currentDirectory = getFileChooser().getCurrentDirectory();
1387:                if (readOnly || !canWrite(currentDirectory)) {
1388:                    return;
1389:                }
1390:
1391:                ensureIndexIsVisible(index);
1392:                switch (viewType) {
1393:                case VIEWTYPE_LIST:
1394:                    editFile = (File) getModel().getElementAt(
1395:                            getRowSorter().convertRowIndexToModel(index));
1396:                    Rectangle r = list.getCellBounds(index, index);
1397:                    if (editCell == null) {
1398:                        editCell = new JTextField();
1399:                        editCell.addActionListener(new EditActionListener());
1400:                        editCell.addFocusListener(editorFocusListener);
1401:                        editCell.setNextFocusableComponent(list);
1402:                    }
1403:                    list.add(editCell);
1404:                    editCell.setText(getFileChooser().getName(editFile));
1405:                    ComponentOrientation orientation = list
1406:                            .getComponentOrientation();
1407:                    editCell.setComponentOrientation(orientation);
1408:                    if (orientation.isLeftToRight()) {
1409:                        editCell.setBounds(editX + r.x, r.y, r.width - editX,
1410:                                r.height);
1411:                    } else {
1412:                        editCell.setBounds(r.x, r.y, r.width - editX, r.height);
1413:                    }
1414:                    editCell.requestFocus();
1415:                    editCell.selectAll();
1416:                    break;
1417:
1418:                case VIEWTYPE_DETAILS:
1419:                    detailsTable.editCellAt(index, COLUMN_FILENAME);
1420:                    break;
1421:                }
1422:            }
1423:
1424:            class EditActionListener implements  ActionListener {
1425:                public void actionPerformed(ActionEvent e) {
1426:                    applyEdit();
1427:                }
1428:            }
1429:
1430:            private void applyEdit() {
1431:                if (editFile != null && editFile.exists()) {
1432:                    JFileChooser chooser = getFileChooser();
1433:                    String oldDisplayName = chooser.getName(editFile);
1434:                    String oldFileName = editFile.getName();
1435:                    String newDisplayName = editCell.getText().trim();
1436:                    String newFileName;
1437:
1438:                    if (!newDisplayName.equals(oldDisplayName)) {
1439:                        newFileName = newDisplayName;
1440:                        //Check if extension is hidden from user
1441:                        int i1 = oldFileName.length();
1442:                        int i2 = oldDisplayName.length();
1443:                        if (i1 > i2 && oldFileName.charAt(i2) == '.') {
1444:                            newFileName = newDisplayName
1445:                                    + oldFileName.substring(i2);
1446:                        }
1447:
1448:                        // rename
1449:                        FileSystemView fsv = chooser.getFileSystemView();
1450:                        File f2 = fsv.createFileObject(
1451:                                editFile.getParentFile(), newFileName);
1452:                        if (!f2.exists() && getModel().renameFile(editFile, f2)) {
1453:                            if (fsv.isParent(chooser.getCurrentDirectory(), f2)) {
1454:                                if (chooser.isMultiSelectionEnabled()) {
1455:                                    chooser.setSelectedFiles(new File[] { f2 });
1456:                                } else {
1457:                                    chooser.setSelectedFile(f2);
1458:                                }
1459:                            } else {
1460:                                //Could be because of delay in updating Desktop folder
1461:                                //chooser.setSelectedFile(null);
1462:                            }
1463:                        } else {
1464:                            // PENDING(jeff) - show a dialog indicating failure
1465:                        }
1466:                    }
1467:                }
1468:                if (detailsTable != null && detailsTable.isEditing()) {
1469:                    detailsTable.getCellEditor().stopCellEditing();
1470:                }
1471:                cancelEdit();
1472:            }
1473:
1474:            protected Action newFolderAction;
1475:
1476:            public Action getNewFolderAction() {
1477:                if (!readOnly && newFolderAction == null) {
1478:                    newFolderAction = new AbstractAction(
1479:                            newFolderActionLabelText) {
1480:                        private Action basicNewFolderAction;
1481:
1482:                        // Initializer
1483:                        {
1484:                            putValue(Action.ACTION_COMMAND_KEY,
1485:                                    FilePane.ACTION_NEW_FOLDER);
1486:
1487:                            File currentDirectory = getFileChooser()
1488:                                    .getCurrentDirectory();
1489:                            if (currentDirectory != null) {
1490:                                setEnabled(canWrite(currentDirectory));
1491:                            }
1492:                        }
1493:
1494:                        public void actionPerformed(ActionEvent ev) {
1495:                            if (basicNewFolderAction == null) {
1496:                                basicNewFolderAction = fileChooserUIAccessor
1497:                                        .getNewFolderAction();
1498:                            }
1499:                            JFileChooser fc = getFileChooser();
1500:                            File oldFile = fc.getSelectedFile();
1501:                            basicNewFolderAction.actionPerformed(ev);
1502:                            File newFile = fc.getSelectedFile();
1503:                            if (newFile != null && !newFile.equals(oldFile)
1504:                                    && newFile.isDirectory()) {
1505:                                newFolderFile = newFile;
1506:                            }
1507:                        }
1508:                    };
1509:                }
1510:                return newFolderAction;
1511:            }
1512:
1513:            protected class FileRenderer extends DefaultListCellRenderer {
1514:
1515:                public Component getListCellRendererComponent(JList list,
1516:                        Object value, int index, boolean isSelected,
1517:                        boolean cellHasFocus) {
1518:
1519:                    if (listViewWindowsStyle && !list.isFocusOwner()) {
1520:                        isSelected = false;
1521:                    }
1522:
1523:                    super .getListCellRendererComponent(list, value, index,
1524:                            isSelected, cellHasFocus);
1525:                    File file = (File) value;
1526:                    String fileName = getFileChooser().getName(file);
1527:                    setText(fileName);
1528:                    setFont(list.getFont());
1529:
1530:                    Icon icon = getFileChooser().getIcon(file);
1531:                    if (icon != null) {
1532:                        setIcon(icon);
1533:
1534:                        if (isSelected) {
1535:                            // PENDING - grab padding (4) below from defaults table.
1536:                            editX = icon.getIconWidth() + 4;
1537:                        }
1538:                    } else {
1539:                        if (getFileChooser().getFileSystemView().isTraversable(
1540:                                file)) {
1541:                            setText(fileName + File.separator);
1542:                        }
1543:                    }
1544:
1545:                    return this ;
1546:                }
1547:            }
1548:
1549:            void setFileSelected() {
1550:                if (getFileChooser().isMultiSelectionEnabled()
1551:                        && !isDirectorySelected()) {
1552:                    File[] files = getFileChooser().getSelectedFiles(); // Should be selected
1553:                    Object[] selectedObjects = list.getSelectedValues(); // Are actually selected
1554:
1555:                    listSelectionModel.setValueIsAdjusting(true);
1556:                    try {
1557:                        int lead = listSelectionModel.getLeadSelectionIndex();
1558:                        int anchor = listSelectionModel
1559:                                .getAnchorSelectionIndex();
1560:
1561:                        Arrays.sort(files);
1562:                        Arrays.sort(selectedObjects);
1563:
1564:                        int shouldIndex = 0;
1565:                        int actuallyIndex = 0;
1566:
1567:                        // Remove files that shouldn't be selected and add files which should be selected
1568:                        // Note: Assume files are already sorted in compareTo order.
1569:                        while (shouldIndex < files.length
1570:                                && actuallyIndex < selectedObjects.length) {
1571:                            int comparison = files[shouldIndex]
1572:                                    .compareTo((File) selectedObjects[actuallyIndex]);
1573:                            if (comparison < 0) {
1574:                                doSelectFile(files[shouldIndex++]);
1575:                            } else if (comparison > 0) {
1576:                                doDeselectFile(selectedObjects[actuallyIndex++]);
1577:                            } else {
1578:                                // Do nothing
1579:                                shouldIndex++;
1580:                                actuallyIndex++;
1581:                            }
1582:
1583:                        }
1584:
1585:                        while (shouldIndex < files.length) {
1586:                            doSelectFile(files[shouldIndex++]);
1587:                        }
1588:
1589:                        while (actuallyIndex < selectedObjects.length) {
1590:                            doDeselectFile(selectedObjects[actuallyIndex++]);
1591:                        }
1592:
1593:                        // restore the anchor and lead
1594:                        if (listSelectionModel instanceof  DefaultListSelectionModel) {
1595:                            ((DefaultListSelectionModel) listSelectionModel)
1596:                                    .moveLeadSelectionIndex(lead);
1597:                            listSelectionModel.setAnchorSelectionIndex(anchor);
1598:                        }
1599:                    } finally {
1600:                        listSelectionModel.setValueIsAdjusting(false);
1601:                    }
1602:                } else {
1603:                    JFileChooser chooser = getFileChooser();
1604:                    File f;
1605:                    if (isDirectorySelected()) {
1606:                        f = getDirectory();
1607:                    } else {
1608:                        f = chooser.getSelectedFile();
1609:                    }
1610:                    int i;
1611:                    if (f != null && (i = getModel().indexOf(f)) >= 0) {
1612:                        int viewIndex = getRowSorter().convertRowIndexToView(i);
1613:                        listSelectionModel.setSelectionInterval(viewIndex,
1614:                                viewIndex);
1615:                        ensureIndexIsVisible(viewIndex);
1616:                    } else {
1617:                        clearSelection();
1618:                    }
1619:                }
1620:            }
1621:
1622:            private void doSelectFile(File fileToSelect) {
1623:                int index = getModel().indexOf(fileToSelect);
1624:                // could be missed in the current directory if it changed
1625:                if (index >= 0) {
1626:                    index = getRowSorter().convertRowIndexToView(index);
1627:                    listSelectionModel.addSelectionInterval(index, index);
1628:                }
1629:            }
1630:
1631:            private void doDeselectFile(Object fileToDeselect) {
1632:                int index = getRowSorter().convertRowIndexToView(
1633:                        getModel().indexOf(fileToDeselect));
1634:                listSelectionModel.removeSelectionInterval(index, index);
1635:            }
1636:
1637:            /* The following methods are used by the PropertyChange Listener */
1638:
1639:            private void doSelectedFileChanged(PropertyChangeEvent e) {
1640:                applyEdit();
1641:                File f = (File) e.getNewValue();
1642:                JFileChooser fc = getFileChooser();
1643:                if (f != null
1644:                        && ((fc.isFileSelectionEnabled() && !f.isDirectory()) || (f
1645:                                .isDirectory() && fc
1646:                                .isDirectorySelectionEnabled()))) {
1647:
1648:                    setFileSelected();
1649:                }
1650:            }
1651:
1652:            private void doSelectedFilesChanged(PropertyChangeEvent e) {
1653:                applyEdit();
1654:                File[] files = (File[]) e.getNewValue();
1655:                JFileChooser fc = getFileChooser();
1656:                if (files != null
1657:                        && files.length > 0
1658:                        && (files.length > 1
1659:                                || fc.isDirectorySelectionEnabled() || !files[0]
1660:                                .isDirectory())) {
1661:                    setFileSelected();
1662:                }
1663:            }
1664:
1665:            private void doDirectoryChanged(PropertyChangeEvent e) {
1666:                getDetailsTableModel().updateColumnInfo();
1667:
1668:                JFileChooser fc = getFileChooser();
1669:                FileSystemView fsv = fc.getFileSystemView();
1670:
1671:                applyEdit();
1672:                resetEditIndex();
1673:                ensureIndexIsVisible(0);
1674:                File currentDirectory = fc.getCurrentDirectory();
1675:                if (currentDirectory != null) {
1676:                    if (!readOnly) {
1677:                        getNewFolderAction().setEnabled(
1678:                                canWrite(currentDirectory));
1679:                    }
1680:                    fileChooserUIAccessor.getChangeToParentDirectoryAction()
1681:                            .setEnabled(!fsv.isRoot(currentDirectory));
1682:                }
1683:            }
1684:
1685:            private void doFilterChanged(PropertyChangeEvent e) {
1686:                applyEdit();
1687:                resetEditIndex();
1688:                clearSelection();
1689:            }
1690:
1691:            private void doFileSelectionModeChanged(PropertyChangeEvent e) {
1692:                applyEdit();
1693:                resetEditIndex();
1694:                clearSelection();
1695:            }
1696:
1697:            private void doMultiSelectionChanged(PropertyChangeEvent e) {
1698:                if (getFileChooser().isMultiSelectionEnabled()) {
1699:                    listSelectionModel
1700:                            .setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
1701:                } else {
1702:                    listSelectionModel
1703:                            .setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
1704:                    clearSelection();
1705:                    getFileChooser().setSelectedFiles(null);
1706:                }
1707:            }
1708:
1709:            /*
1710:             * Listen for filechooser property changes, such as
1711:             * the selected file changing, or the type of the dialog changing.
1712:             */
1713:            public void propertyChange(PropertyChangeEvent e) {
1714:                if (viewType == -1) {
1715:                    setViewType(VIEWTYPE_LIST);
1716:                }
1717:
1718:                String s = e.getPropertyName();
1719:                if (s.equals(JFileChooser.SELECTED_FILE_CHANGED_PROPERTY)) {
1720:                    doSelectedFileChanged(e);
1721:                } else if (s
1722:                        .equals(JFileChooser.SELECTED_FILES_CHANGED_PROPERTY)) {
1723:                    doSelectedFilesChanged(e);
1724:                } else if (s.equals(JFileChooser.DIRECTORY_CHANGED_PROPERTY)) {
1725:                    doDirectoryChanged(e);
1726:                } else if (s.equals(JFileChooser.FILE_FILTER_CHANGED_PROPERTY)) {
1727:                    doFilterChanged(e);
1728:                } else if (s
1729:                        .equals(JFileChooser.FILE_SELECTION_MODE_CHANGED_PROPERTY)) {
1730:                    doFileSelectionModeChanged(e);
1731:                } else if (s
1732:                        .equals(JFileChooser.MULTI_SELECTION_ENABLED_CHANGED_PROPERTY)) {
1733:                    doMultiSelectionChanged(e);
1734:                } else if (s.equals(JFileChooser.CANCEL_SELECTION)) {
1735:                    applyEdit();
1736:                } else if (s.equals("busy")) {
1737:                    setCursor((Boolean) e.getNewValue() ? waitCursor : null);
1738:                } else if (s.equals("componentOrientation")) {
1739:                    ComponentOrientation o = (ComponentOrientation) e
1740:                            .getNewValue();
1741:                    JFileChooser cc = (JFileChooser) e.getSource();
1742:                    if (o != e.getOldValue()) {
1743:                        cc.applyComponentOrientation(o);
1744:                    }
1745:                    if (detailsTable != null) {
1746:                        detailsTable.setComponentOrientation(o);
1747:                        detailsTable.getParent().getParent()
1748:                                .setComponentOrientation(o);
1749:                    }
1750:                }
1751:            }
1752:
1753:            private void ensureIndexIsVisible(int i) {
1754:                if (i >= 0) {
1755:                    if (list != null) {
1756:                        list.ensureIndexIsVisible(i);
1757:                    }
1758:                    if (detailsTable != null) {
1759:                        detailsTable.scrollRectToVisible(detailsTable
1760:                                .getCellRect(i, COLUMN_FILENAME, true));
1761:                    }
1762:                }
1763:            }
1764:
1765:            public void ensureFileIsVisible(JFileChooser fc, File f) {
1766:                int modelIndex = getModel().indexOf(f);
1767:                if (modelIndex >= 0) {
1768:                    ensureIndexIsVisible(getRowSorter().convertRowIndexToView(
1769:                            modelIndex));
1770:                }
1771:            }
1772:
1773:            public void rescanCurrentDirectory() {
1774:                getModel().validateFileCache();
1775:            }
1776:
1777:            public void clearSelection() {
1778:                if (listSelectionModel != null) {
1779:                    listSelectionModel.clearSelection();
1780:                    if (listSelectionModel instanceof  DefaultListSelectionModel) {
1781:                        ((DefaultListSelectionModel) listSelectionModel)
1782:                                .moveLeadSelectionIndex(0);
1783:                        listSelectionModel.setAnchorSelectionIndex(0);
1784:                    }
1785:                }
1786:            }
1787:
1788:            public JMenu getViewMenu() {
1789:                if (viewMenu == null) {
1790:                    viewMenu = new JMenu(viewMenuLabelText);
1791:                    ButtonGroup viewButtonGroup = new ButtonGroup();
1792:
1793:                    for (int i = 0; i < VIEWTYPE_COUNT; i++) {
1794:                        JRadioButtonMenuItem mi = new JRadioButtonMenuItem(
1795:                                new ViewTypeAction(i));
1796:                        viewButtonGroup.add(mi);
1797:                        viewMenu.add(mi);
1798:                    }
1799:                    updateViewMenu();
1800:                }
1801:                return viewMenu;
1802:            }
1803:
1804:            private void updateViewMenu() {
1805:                if (viewMenu != null) {
1806:                    Component[] comps = viewMenu.getMenuComponents();
1807:                    for (int i = 0; i < comps.length; i++) {
1808:                        if (comps[i] instanceof  JRadioButtonMenuItem) {
1809:                            JRadioButtonMenuItem mi = (JRadioButtonMenuItem) comps[i];
1810:                            if (((ViewTypeAction) mi.getAction()).viewType == viewType) {
1811:                                mi.setSelected(true);
1812:                            }
1813:                        }
1814:                    }
1815:                }
1816:            }
1817:
1818:            public JPopupMenu getComponentPopupMenu() {
1819:                JPopupMenu popupMenu = getFileChooser().getComponentPopupMenu();
1820:                if (popupMenu != null) {
1821:                    return popupMenu;
1822:                }
1823:
1824:                JMenu viewMenu = getViewMenu();
1825:                if (contextMenu == null) {
1826:                    contextMenu = new JPopupMenu();
1827:                    if (viewMenu != null) {
1828:                        contextMenu.add(viewMenu);
1829:                        if (listViewWindowsStyle) {
1830:                            contextMenu.addSeparator();
1831:                        }
1832:                    }
1833:                    ActionMap actionMap = getActionMap();
1834:                    Action refreshAction = actionMap.get(ACTION_REFRESH);
1835:                    Action newFolderAction = actionMap.get(ACTION_NEW_FOLDER);
1836:                    if (refreshAction != null) {
1837:                        contextMenu.add(refreshAction);
1838:                        if (listViewWindowsStyle && newFolderAction != null) {
1839:                            contextMenu.addSeparator();
1840:                        }
1841:                    }
1842:                    if (newFolderAction != null) {
1843:                        contextMenu.add(newFolderAction);
1844:                    }
1845:                }
1846:                if (viewMenu != null) {
1847:                    viewMenu.getPopupMenu().setInvoker(viewMenu);
1848:                }
1849:                return contextMenu;
1850:            }
1851:
1852:            private Handler handler;
1853:
1854:            protected Handler getMouseHandler() {
1855:                if (handler == null) {
1856:                    handler = new Handler();
1857:                }
1858:                return handler;
1859:            }
1860:
1861:            private class Handler implements  MouseListener {
1862:                private MouseListener doubleClickListener;
1863:
1864:                public void mouseClicked(MouseEvent evt) {
1865:                    JComponent source = (JComponent) evt.getSource();
1866:
1867:                    int index;
1868:                    if (source instanceof  JList) {
1869:                        index = SwingUtilities2.loc2IndexFileList(list, evt
1870:                                .getPoint());
1871:                    } else if (source instanceof  JTable) {
1872:                        JTable table = (JTable) source;
1873:                        Point p = evt.getPoint();
1874:                        index = table.rowAtPoint(p);
1875:
1876:                        if (SwingUtilities2.pointOutsidePrefSize(table, index,
1877:                                table.columnAtPoint(p), p)) {
1878:
1879:                            return;
1880:                        }
1881:
1882:                        // Translate point from table to list
1883:                        if (index >= 0 && list != null
1884:                                && listSelectionModel.isSelectedIndex(index)) {
1885:
1886:                            // Make a new event with the list as source, placing the
1887:                            // click in the corresponding list cell.
1888:                            Rectangle r = list.getCellBounds(index, index);
1889:                            evt = new MouseEvent(list, evt.getID(), evt
1890:                                    .getWhen(), evt.getModifiers(), r.x + 1,
1891:                                    r.y + r.height / 2, evt.getXOnScreen(), evt
1892:                                            .getYOnScreen(), evt
1893:                                            .getClickCount(), evt
1894:                                            .isPopupTrigger(), evt.getButton());
1895:                        }
1896:                    } else {
1897:                        return;
1898:                    }
1899:
1900:                    if (index >= 0 && SwingUtilities.isLeftMouseButton(evt)) {
1901:                        JFileChooser fc = getFileChooser();
1902:
1903:                        // For single click, we handle editing file name
1904:                        if (evt.getClickCount() == 1 && source instanceof  JList) {
1905:                            if ((!fc.isMultiSelectionEnabled() || fc
1906:                                    .getSelectedFiles().length <= 1)
1907:                                    && index >= 0
1908:                                    && listSelectionModel
1909:                                            .isSelectedIndex(index)
1910:                                    && getEditIndex() == index
1911:                                    && editFile == null) {
1912:
1913:                                editFileName(index);
1914:                            } else {
1915:                                if (index >= 0) {
1916:                                    setEditIndex(index);
1917:                                } else {
1918:                                    resetEditIndex();
1919:                                }
1920:                            }
1921:                        } else if (evt.getClickCount() == 2) {
1922:                            // on double click (open or drill down one directory) be
1923:                            // sure to clear the edit index
1924:                            resetEditIndex();
1925:                        }
1926:                    }
1927:
1928:                    // Forward event to Basic
1929:                    if (getDoubleClickListener() != null) {
1930:                        getDoubleClickListener().mouseClicked(evt);
1931:                    }
1932:                }
1933:
1934:                public void mouseEntered(MouseEvent evt) {
1935:                    JComponent source = (JComponent) evt.getSource();
1936:                    if (source instanceof  JTable) {
1937:                        JTable table = (JTable) evt.getSource();
1938:
1939:                        TransferHandler th1 = getFileChooser()
1940:                                .getTransferHandler();
1941:                        TransferHandler th2 = table.getTransferHandler();
1942:                        if (th1 != th2) {
1943:                            table.setTransferHandler(th1);
1944:                        }
1945:
1946:                        boolean dragEnabled = getFileChooser().getDragEnabled();
1947:                        if (dragEnabled != table.getDragEnabled()) {
1948:                            table.setDragEnabled(dragEnabled);
1949:                        }
1950:                    } else if (source instanceof  JList) {
1951:                        // Forward event to Basic
1952:                        if (getDoubleClickListener() != null) {
1953:                            getDoubleClickListener().mouseEntered(evt);
1954:                        }
1955:                    }
1956:                }
1957:
1958:                public void mouseExited(MouseEvent evt) {
1959:                    if (evt.getSource() instanceof  JList) {
1960:                        // Forward event to Basic
1961:                        if (getDoubleClickListener() != null) {
1962:                            getDoubleClickListener().mouseExited(evt);
1963:                        }
1964:                    }
1965:                }
1966:
1967:                public void mousePressed(MouseEvent evt) {
1968:                    if (evt.getSource() instanceof  JList) {
1969:                        // Forward event to Basic
1970:                        if (getDoubleClickListener() != null) {
1971:                            getDoubleClickListener().mousePressed(evt);
1972:                        }
1973:                    }
1974:                }
1975:
1976:                public void mouseReleased(MouseEvent evt) {
1977:                    if (evt.getSource() instanceof  JList) {
1978:                        // Forward event to Basic
1979:                        if (getDoubleClickListener() != null) {
1980:                            getDoubleClickListener().mouseReleased(evt);
1981:                        }
1982:                    }
1983:                }
1984:
1985:                private MouseListener getDoubleClickListener() {
1986:                    // Lazy creation of Basic's listener
1987:                    if (doubleClickListener == null && list != null) {
1988:                        doubleClickListener = fileChooserUIAccessor
1989:                                .createDoubleClickListener(list);
1990:                    }
1991:                    return doubleClickListener;
1992:                }
1993:            }
1994:
1995:            /**
1996:             * Property to remember whether a directory is currently selected in the UI.
1997:             *
1998:             * @return <code>true</code> iff a directory is currently selected.
1999:             */
2000:            protected boolean isDirectorySelected() {
2001:                return fileChooserUIAccessor.isDirectorySelected();
2002:            }
2003:
2004:            /**
2005:             * Property to remember the directory that is currently selected in the UI.
2006:             *
2007:             * @return the value of the <code>directory</code> property
2008:             * @see javax.swing.plaf.basic.BasicFileChooserUI#setDirectory
2009:             */
2010:            protected File getDirectory() {
2011:                return fileChooserUIAccessor.getDirectory();
2012:            }
2013:
2014:            private Component findChildComponent(Container container, Class cls) {
2015:                int n = container.getComponentCount();
2016:                for (int i = 0; i < n; i++) {
2017:                    Component comp = container.getComponent(i);
2018:                    if (cls.isInstance(comp)) {
2019:                        return comp;
2020:                    } else if (comp instanceof  Container) {
2021:                        Component c = findChildComponent((Container) comp, cls);
2022:                        if (c != null) {
2023:                            return c;
2024:                        }
2025:                    }
2026:                }
2027:                return null;
2028:            }
2029:
2030:            public static boolean canWrite(File f) {
2031:                boolean writeable = false;
2032:                if (f != null) {
2033:                    try {
2034:                        writeable = f.canWrite();
2035:                    } catch (AccessControlException ex) {
2036:                        writeable = false;
2037:                    }
2038:                }
2039:                return writeable;
2040:            }
2041:
2042:            // This interface is used to access methods in the FileChooserUI
2043:            // that are not public.
2044:            public interface FileChooserUIAccessor {
2045:                public JFileChooser getFileChooser();
2046:
2047:                public BasicDirectoryModel getModel();
2048:
2049:                public JPanel createList();
2050:
2051:                public JPanel createDetailsView();
2052:
2053:                public boolean isDirectorySelected();
2054:
2055:                public File getDirectory();
2056:
2057:                public Action getApproveSelectionAction();
2058:
2059:                public Action getChangeToParentDirectoryAction();
2060:
2061:                public Action getNewFolderAction();
2062:
2063:                public MouseListener createDoubleClickListener(JList list);
2064:
2065:                public ListSelectionListener createListSelectionListener();
2066:
2067:                public boolean usesShellFolder();
2068:            }
2069:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.