585 lines · 20.3 KB · Java
RawDownload
/* * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.  Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */package sun.swing.plaf.synth; import javax.swing.plaf.synth.*;import java.awt.*;import java.awt.event.*;import java.beans.*;import java.io.File;import java.util.regex.*; import javax.swing.*;import javax.swing.border.*;import javax.swing.event.*;import javax.swing.filechooser.*;import javax.swing.plaf.*;import javax.swing.plaf.basic.BasicFileChooserUI; /** * Synth FileChooserUI. * * Note: This class is abstract. It does not actually create the file chooser GUI. * <p> * Note that the classes in the com.sun.java.swing.plaf.synth * package are not * part of the core Java APIs. They are a part of Sun's JDK and JRE * distributions. Although other licensees may choose to distribute * these classes, developers cannot depend on their availability in * non-Sun implementations. Additionally this API may change in * incompatible ways between releases. While this class is public, it * shoud be considered an implementation detail, and subject to change. * * @author Leif Samuelsson * @author Jeff Dinkins */public abstract class SynthFileChooserUI extends BasicFileChooserUI implements                           SynthUI {    private JButton approveButton, cancelButton;     private SynthStyle style;     // Some generic FileChooser functions    private Action fileNameCompletionAction = new FileNameCompletionAction();     private FileFilter actualFileFilter = null;    private GlobFilter globFilter = null;     public static ComponentUI createUI(JComponent c) {        return new SynthFileChooserUIImpl((JFileChooser)c);    }     public SynthFileChooserUI(JFileChooser b) {        super(b);    }     public SynthContext getContext(JComponent c) {        return new SynthContext(c, Region.FILE_CHOOSER, style,                                getComponentState(c));    }     protected SynthContext getContext(JComponent c, int state) {        Region region = SynthLookAndFeel.getRegion(c);        return new SynthContext(c, Region.FILE_CHOOSER, style, state);    }     private Region getRegion(JComponent c) {        return SynthLookAndFeel.getRegion(c);    }     private int getComponentState(JComponent c) {        if (c.isEnabled()) {            if (c.isFocusOwner()) {                return ENABLED | FOCUSED;            }            return ENABLED;        }        return DISABLED;    }     private void updateStyle(JComponent c) {        SynthStyle newStyle = SynthLookAndFeel.getStyleFactory().getStyle(c,                                               Region.FILE_CHOOSER);        if (newStyle != style) {            if (style != null) {                style.uninstallDefaults(getContext(c, ENABLED));            }            style = newStyle;            SynthContext context = getContext(c, ENABLED);            style.installDefaults(context);            Border border = c.getBorder();            if (border == null || border instanceof UIResource) {                c.setBorder(new UIBorder(style.getInsets(context, null)));            }             directoryIcon = style.getIcon(context, "FileView.directoryIcon");            fileIcon = style.getIcon(context, "FileView.fileIcon");            computerIcon = style.getIcon(context, "FileView.computerIcon");            hardDriveIcon = style.getIcon(context, "FileView.hardDriveIcon");            floppyDriveIcon = style.getIcon(context, "FileView.floppyDriveIcon");             newFolderIcon    = style.getIcon(context, "FileChooser.newFolderIcon");            upFolderIcon     = style.getIcon(context, "FileChooser.upFolderIcon");            homeFolderIcon   = style.getIcon(context, "FileChooser.homeFolderIcon");            detailsViewIcon  = style.getIcon(context, "FileChooser.detailsViewIcon");            listViewIcon     = style.getIcon(context, "FileChooser.listViewIcon");        }    }     public void installUI(JComponent c) {        super.installUI(c);        SwingUtilities.replaceUIActionMap(c, createActionMap());    }     public void installComponents(JFileChooser fc) {        SynthContext context = getContext(fc, ENABLED);         cancelButton = new JButton(cancelButtonText);        cancelButton.setName("SynthFileChooser.cancelButton");        cancelButton.setIcon(context.getStyle().getIcon(context, "FileChooser.cancelIcon"));        cancelButton.setMnemonic(cancelButtonMnemonic);        cancelButton.setToolTipText(cancelButtonToolTipText);        cancelButton.addActionListener(getCancelSelectionAction());         approveButton = new JButton(getApproveButtonText(fc));        approveButton.setName("SynthFileChooser.approveButton");        approveButton.setIcon(context.getStyle().getIcon(context, "FileChooser.okIcon"));        approveButton.setMnemonic(getApproveButtonMnemonic(fc));        approveButton.setToolTipText(getApproveButtonToolTipText(fc));        approveButton.addActionListener(getApproveSelectionAction());     }     public void uninstallComponents(JFileChooser fc) {        fc.removeAll();    }     protected void installListeners(JFileChooser fc) {        super.installListeners(fc);         getModel().addListDataListener(new ListDataListener() {            public void contentsChanged(ListDataEvent e) {                // Update the selection after JList has been updated                new DelayedSelectionUpdater();            }            public void intervalAdded(ListDataEvent e) {                new DelayedSelectionUpdater();            }            public void intervalRemoved(ListDataEvent e) {            }        });     }     private class DelayedSelectionUpdater implements Runnable {        DelayedSelectionUpdater() {            SwingUtilities.invokeLater(this);        }         public void run() {            updateFileNameCompletion();        }    }     protected abstract ActionMap createActionMap();      protected void installDefaults(JFileChooser fc) {        super.installDefaults(fc);        updateStyle(fc);    }     protected void uninstallDefaults(JFileChooser fc) {        super.uninstallDefaults(fc);         SynthContext context = getContext(getFileChooser(), ENABLED);        style.uninstallDefaults(context);        style = null;    }     protected void installIcons(JFileChooser fc) {        // The icons are installed in updateStyle, not here    }     public void update(Graphics g, JComponent c) {        SynthContext context = getContext(c);         if (c.isOpaque()) {            g.setColor(style.getColor(context, ColorType.BACKGROUND));            g.fillRect(0, 0, c.getWidth(), c.getHeight());        }         style.getPainter(context).paintFileChooserBackground(context,                                    g, 0, 0, c.getWidth(), c.getHeight());        paint(context, g);    }     public void paintBorder(SynthContext context, Graphics g, int x, int y, int w, int h) {    }     public void paint(Graphics g, JComponent c) {        SynthContext context = getContext(c);         paint(context, g);    }     protected void paint(SynthContext context, Graphics g) {    }     abstract public void setFileName(String fileName);    abstract public String getFileName();     protected void doSelectedFileChanged(PropertyChangeEvent e) {    }     protected void doSelectedFilesChanged(PropertyChangeEvent e) {    }     protected void doDirectoryChanged(PropertyChangeEvent e) {    }     protected void doAccessoryChanged(PropertyChangeEvent e) {    }     protected void doFileSelectionModeChanged(PropertyChangeEvent e) {    }     protected void doMultiSelectionChanged(PropertyChangeEvent e) {        if (!getFileChooser().isMultiSelectionEnabled()) {            getFileChooser().setSelectedFiles(null);        }    }     protected void doControlButtonsChanged(PropertyChangeEvent e) {        if (getFileChooser().getControlButtonsAreShown()) {            approveButton.setText(getApproveButtonText(getFileChooser()));            approveButton.setToolTipText(getApproveButtonToolTipText(getFileChooser()));        }    }     protected void doAncestorChanged(PropertyChangeEvent e) {    }     public PropertyChangeListener createPropertyChangeListener(JFileChooser fc) {        return new SynthFCPropertyChangeListener();    }     private class SynthFCPropertyChangeListener implements PropertyChangeListener {        public void propertyChange(PropertyChangeEvent e) {            String prop = e.getPropertyName();            if (prop.equals(JFileChooser.FILE_SELECTION_MODE_CHANGED_PROPERTY)) {                doFileSelectionModeChanged(e);            } else if (prop.equals(JFileChooser.SELECTED_FILE_CHANGED_PROPERTY)) {                doSelectedFileChanged(e);            } else if (prop.equals(JFileChooser.SELECTED_FILES_CHANGED_PROPERTY)) {                doSelectedFilesChanged(e);            } else if (prop.equals(JFileChooser.DIRECTORY_CHANGED_PROPERTY)) {                doDirectoryChanged(e);            } else if (prop == JFileChooser.MULTI_SELECTION_ENABLED_CHANGED_PROPERTY) {                doMultiSelectionChanged(e);            } else if (prop == JFileChooser.ACCESSORY_CHANGED_PROPERTY) {                doAccessoryChanged(e);            } else if (prop == JFileChooser.APPROVE_BUTTON_TEXT_CHANGED_PROPERTY ||                       prop == JFileChooser.APPROVE_BUTTON_TOOL_TIP_TEXT_CHANGED_PROPERTY ||                       prop == JFileChooser.DIALOG_TYPE_CHANGED_PROPERTY ||                       prop == JFileChooser.CONTROL_BUTTONS_ARE_SHOWN_CHANGED_PROPERTY) {                doControlButtonsChanged(e);            } else if (prop.equals("componentOrientation")) {                ComponentOrientation o = (ComponentOrientation)e.getNewValue();                JFileChooser cc = (JFileChooser)e.getSource();                if (o != (ComponentOrientation)e.getOldValue()) {                    cc.applyComponentOrientation(o);                }            } else if (prop.equals("ancestor")) {                doAncestorChanged(e);            }        }    }      /**     * Responds to a File Name completion request (e.g. Tab)     */    private class FileNameCompletionAction extends AbstractAction {        protected FileNameCompletionAction() {            super("fileNameCompletion");        }         public void actionPerformed(ActionEvent e) {            JFileChooser chooser = getFileChooser();             String fileName = getFileName();             if (fileName != null) {                // Remove whitespace from beginning and end of filename                fileName = fileName.trim();            }             resetGlobFilter();             if (fileName == null || fileName.equals("") ||                    (chooser.isMultiSelectionEnabled() && fileName.startsWith("\""))) {                return;            }             FileFilter currentFilter = chooser.getFileFilter();            if (globFilter == null) {                globFilter = new GlobFilter();            }            try {                globFilter.setPattern(!isGlobPattern(fileName) ? fileName + "*" : fileName);                if (!(currentFilter instanceof GlobFilter)) {                    actualFileFilter = currentFilter;                }                chooser.setFileFilter(null);                chooser.setFileFilter(globFilter);                fileNameCompletionString = fileName;            } catch (PatternSyntaxException pse) {                // Not a valid glob pattern. Abandon filter.            }        }    }     private String fileNameCompletionString;     private void updateFileNameCompletion() {        if (fileNameCompletionString != null) {            if (fileNameCompletionString.equals(getFileName())) {                File[] files = getModel().getFiles().toArray(new File[0]);                String str = getCommonStartString(files);                if (str != null && str.startsWith(fileNameCompletionString)) {                    setFileName(str);                }                fileNameCompletionString = null;            }        }    }     private String getCommonStartString(File[] files) {        String str = null;        String str2 = null;        int i = 0;        if (files.length == 0) {            return null;        }        while (true) {            for (int f = 0; f < files.length; f++) {                String name = files[f].getName();                if (f == 0) {                    if (name.length() == i) {                        return str;                    }                    str2 = name.substring(0, i+1);                }                if (!name.startsWith(str2)) {                    return str;                }            }            str = str2;            i++;        }    }     private void resetGlobFilter() {        if (actualFileFilter != null) {            JFileChooser chooser = getFileChooser();            FileFilter currentFilter = chooser.getFileFilter();            if (currentFilter != null && currentFilter.equals(globFilter)) {                chooser.setFileFilter(actualFileFilter);                chooser.removeChoosableFileFilter(globFilter);            }            actualFileFilter = null;        }    }     private static boolean isGlobPattern(String fileName) {        return ((File.separatorChar == '\\' && fileName.indexOf('*') >= 0)                || (File.separatorChar == '/' && (fileName.indexOf('*') >= 0                                                  || fileName.indexOf('?') >= 0                                                  || fileName.indexOf('[') >= 0)));    }      /* A file filter which accepts file patterns containing     * the special wildcard '*' on windows, plus '?', and '[ ]' on Unix.     */    class GlobFilter extends FileFilter {        Pattern pattern;        String globPattern;         public void setPattern(String globPattern) {            char[] gPat = globPattern.toCharArray();            char[] rPat = new char[gPat.length * 2];            boolean isWin32 = (File.separatorChar == '\\');            boolean inBrackets = false;            int j = 0;             this.globPattern = globPattern;             if (isWin32) {                // On windows, a pattern ending with *.* is equal to ending with *                int len = gPat.length;                if (globPattern.endsWith("*.*")) {                    len -= 2;                }                for (int i = 0; i < len; i++) {                    if (gPat[i] == '*') {                        rPat[j++] = '.';                    }                    rPat[j++] = gPat[i];                }            } else {                for (int i = 0; i < gPat.length; i++) {                    switch(gPat[i]) {                      case '*':                        if (!inBrackets) {                            rPat[j++] = '.';                        }                        rPat[j++] = '*';                        break;                       case '?':                        rPat[j++] = inBrackets ? '?' : '.';                        break;                       case '[':                        inBrackets = true;                        rPat[j++] = gPat[i];                         if (i < gPat.length - 1) {                            switch (gPat[i+1]) {                              case '!':                              case '^':                                rPat[j++] = '^';                                i++;                                break;                               case ']':                                rPat[j++] = gPat[++i];                                break;                            }                        }                        break;                       case ']':                        rPat[j++] = gPat[i];                        inBrackets = false;                        break;                       case '\\':                        if (i == 0 && gPat.length > 1 && gPat[1] == '~') {                            rPat[j++] = gPat[++i];                        } else {                            rPat[j++] = '\\';                            if (i < gPat.length - 1 && "*?[]".indexOf(gPat[i+1]) >= 0) {                                rPat[j++] = gPat[++i];                            } else {                                rPat[j++] = '\\';                            }                        }                        break;                       default:                        //if ("+()|^$.{}<>".indexOf(gPat[i]) >= 0) {                        if (!Character.isLetterOrDigit(gPat[i])) {                            rPat[j++] = '\\';                        }                        rPat[j++] = gPat[i];                        break;                    }                }            }            this.pattern = Pattern.compile(new String(rPat, 0, j), Pattern.CASE_INSENSITIVE);        }         public boolean accept(File f) {            if (f == null) {                return false;            }

Lines 1–500 of 585.