SynthFileChooserUI.java :  » 6.0-JDK-Modules-sun » swing » sun » swing » plaf » synth » Java Open Source

Java Open Source » 6.0 JDK Modules sun » swing 
swing » sun » swing » plaf » synth » SynthFileChooserUI.java
/*
 * Copyright 2002-2005 Sun Microsystems, Inc.  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.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.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.io.IOException;
import java.util.*;
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.BasicDirectoryModel;
import javax.swing.plaf.basic.BasicFileChooserUI;

import sun.swing.*;

/**
 * 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.
 *
 * @version 1.24, 05/05/07
 * @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;

    private boolean readOnly;

    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();
  }
    }

    ActionMap createActionMap() {
  ActionMap map = new ActionMapUIResource();
        map.put("approveSelection", getApproveSelectionAction());
  map.put("cancelSelection", getCancelSelectionAction());
        map.put("Go Up", getChangeToParentDirectoryAction());
        map.put("fileNameCompletion", getFileNameCompletionAction());
  return map;
    }


    protected void installDefaults(JFileChooser fc) {
        super.installDefaults(fc);
        updateStyle(fc);
  readOnly = UIManager.getBoolean("FileChooser.readOnly");
    }

    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) {
  File currentDirectory = getFileChooser().getCurrentDirectory();
  if (!readOnly && currentDirectory != null) {
      getNewFolderAction().setEnabled(FilePane.canWrite(currentDirectory));
  }
    }

    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 = (File[])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;
      StringBuffer buf = new StringBuffer();
      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;
      }
      if (f.isDirectory()) {
    return true;
      }
      return pattern.matcher(f.getName()).matches();
  }

  public String getDescription() {
      return globPattern;
  }
    }


    // *******************************************************
    // ************ FileChooser UI PLAF methods **************
    // *******************************************************


    // *****************************
    // ***** Directory Actions *****
    // *****************************

    public Action getFileNameCompletionAction() {
  return fileNameCompletionAction;
    }


    protected JButton getApproveButton(JFileChooser fc) {
  return approveButton;
    }

    protected JButton getCancelButton(JFileChooser fc) {
  return cancelButton;
    }


    // Overload to do nothing.   We don't have and icon cache.
    public void clearIconCache() { }

    // Copied as SynthBorder is package private in synth
    private class UIBorder extends AbstractBorder implements UIResource {
        private Insets _insets;
        UIBorder(Insets insets) {
            if (insets != null) {
                _insets = new Insets(insets.top, insets.left, insets.bottom,
                                     insets.right);
            }
            else {
                _insets = null;
            }
        }

        public void paintBorder(Component c, Graphics g, int x, int y,
                                int width, int height) {
            JComponent jc = (JComponent)c;
            SynthContext context = getContext(jc);
            SynthStyle style = context.getStyle();
            if (style != null) {
                style.getPainter(context).paintFileChooserBorder(
                      context, g, x, y, width, height);
            }
        }
        public Insets getBorderInsets(Component c) { 
            return getBorderInsets(c, null);
        }
        public Insets getBorderInsets(Component c, Insets insets) {
            if (insets == null) {
                insets = new Insets(0, 0, 0, 0);
            }
            if (_insets != null) {
                insets.top = _insets.top;
                insets.bottom = _insets.bottom;
                insets.left = _insets.left;
                insets.right = _insets.right;
            }
            else {
                insets.top = insets.bottom = insets.right = insets.left = 0;
            }
            return insets;
        }
        public boolean isBorderOpaque() {
            return false;
        }
    }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.