History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/swing/plaf/synth/SynthFileChooserUI.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/swing/plaf/synth/SynthFileChooserUI.java+585−0
@@ -0,0 +1,585 @@
1+/*
2+ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+package sun.swing.plaf.synth;
26+
27+import javax.swing.plaf.synth.*;
28+import java.awt.*;
29+import java.awt.event.*;
30+import java.beans.*;
31+import java.io.File;
32+import java.util.regex.*;
33+
34+import javax.swing.*;
35+import javax.swing.border.*;
36+import javax.swing.event.*;
37+import javax.swing.filechooser.*;
38+import javax.swing.plaf.*;
39+import javax.swing.plaf.basic.BasicFileChooserUI;
40+
41+/**
42+ * Synth FileChooserUI.
43+ *
44+ * Note: This class is abstract. It does not actually create the file chooser GUI.
45+ * <p>
46+ * Note that the classes in the com.sun.java.swing.plaf.synth
47+ * package are not
48+ * part of the core Java APIs. They are a part of Sun's JDK and JRE
49+ * distributions. Although other licensees may choose to distribute
50+ * these classes, developers cannot depend on their availability in
51+ * non-Sun implementations. Additionally this API may change in
52+ * incompatible ways between releases. While this class is public, it
53+ * shoud be considered an implementation detail, and subject to change.
54+ *
55+ * @author Leif Samuelsson
56+ * @author Jeff Dinkins
57+ */
58+public abstract class SynthFileChooserUI extends BasicFileChooserUI implements
59+ SynthUI {
60+ private JButton approveButton, cancelButton;
61+
62+ private SynthStyle style;
63+
64+ // Some generic FileChooser functions
65+ private Action fileNameCompletionAction = new FileNameCompletionAction();
66+
67+ private FileFilter actualFileFilter = null;
68+ private GlobFilter globFilter = null;
69+
70+ public static ComponentUI createUI(JComponent c) {
71+ return new SynthFileChooserUIImpl((JFileChooser)c);
72+ }
73+
74+ public SynthFileChooserUI(JFileChooser b) {
75+ super(b);
76+ }
77+
78+ public SynthContext getContext(JComponent c) {
79+ return new SynthContext(c, Region.FILE_CHOOSER, style,
80+ getComponentState(c));
81+ }
82+
83+ protected SynthContext getContext(JComponent c, int state) {
84+ Region region = SynthLookAndFeel.getRegion(c);
85+ return new SynthContext(c, Region.FILE_CHOOSER, style, state);
86+ }
87+
88+ private Region getRegion(JComponent c) {
89+ return SynthLookAndFeel.getRegion(c);
90+ }
91+
92+ private int getComponentState(JComponent c) {
93+ if (c.isEnabled()) {
94+ if (c.isFocusOwner()) {
95+ return ENABLED | FOCUSED;
96+ }
97+ return ENABLED;
98+ }
99+ return DISABLED;
100+ }
101+
102+ private void updateStyle(JComponent c) {
103+ SynthStyle newStyle = SynthLookAndFeel.getStyleFactory().getStyle(c,
104+ Region.FILE_CHOOSER);
105+ if (newStyle != style) {
106+ if (style != null) {
107+ style.uninstallDefaults(getContext(c, ENABLED));
108+ }
109+ style = newStyle;
110+ SynthContext context = getContext(c, ENABLED);
111+ style.installDefaults(context);
112+ Border border = c.getBorder();
113+ if (border == null || border instanceof UIResource) {
114+ c.setBorder(new UIBorder(style.getInsets(context, null)));
115+ }
116+
117+ directoryIcon = style.getIcon(context, "FileView.directoryIcon");
118+ fileIcon = style.getIcon(context, "FileView.fileIcon");
119+ computerIcon = style.getIcon(context, "FileView.computerIcon");
120+ hardDriveIcon = style.getIcon(context, "FileView.hardDriveIcon");
121+ floppyDriveIcon = style.getIcon(context, "FileView.floppyDriveIcon");
122+
123+ newFolderIcon = style.getIcon(context, "FileChooser.newFolderIcon");
124+ upFolderIcon = style.getIcon(context, "FileChooser.upFolderIcon");
125+ homeFolderIcon = style.getIcon(context, "FileChooser.homeFolderIcon");
126+ detailsViewIcon = style.getIcon(context, "FileChooser.detailsViewIcon");
127+ listViewIcon = style.getIcon(context, "FileChooser.listViewIcon");
128+ }
129+ }
130+
131+ public void installUI(JComponent c) {
132+ super.installUI(c);
133+ SwingUtilities.replaceUIActionMap(c, createActionMap());
134+ }
135+
136+ public void installComponents(JFileChooser fc) {
137+ SynthContext context = getContext(fc, ENABLED);
138+
139+ cancelButton = new JButton(cancelButtonText);
140+ cancelButton.setName("SynthFileChooser.cancelButton");
141+ cancelButton.setIcon(context.getStyle().getIcon(context, "FileChooser.cancelIcon"));
142+ cancelButton.setMnemonic(cancelButtonMnemonic);
143+ cancelButton.setToolTipText(cancelButtonToolTipText);
144+ cancelButton.addActionListener(getCancelSelectionAction());
145+
146+ approveButton = new JButton(getApproveButtonText(fc));
147+ approveButton.setName("SynthFileChooser.approveButton");
148+ approveButton.setIcon(context.getStyle().getIcon(context, "FileChooser.okIcon"));
149+ approveButton.setMnemonic(getApproveButtonMnemonic(fc));
150+ approveButton.setToolTipText(getApproveButtonToolTipText(fc));
151+ approveButton.addActionListener(getApproveSelectionAction());
152+
153+ }
154+
155+ public void uninstallComponents(JFileChooser fc) {
156+ fc.removeAll();
157+ }
158+
159+ protected void installListeners(JFileChooser fc) {
160+ super.installListeners(fc);
161+
162+ getModel().addListDataListener(new ListDataListener() {
163+ public void contentsChanged(ListDataEvent e) {
164+ // Update the selection after JList has been updated
165+ new DelayedSelectionUpdater();
166+ }
167+ public void intervalAdded(ListDataEvent e) {
168+ new DelayedSelectionUpdater();
169+ }
170+ public void intervalRemoved(ListDataEvent e) {
171+ }
172+ });
173+
174+ }
175+
176+ private class DelayedSelectionUpdater implements Runnable {
177+ DelayedSelectionUpdater() {
178+ SwingUtilities.invokeLater(this);
179+ }
180+
181+ public void run() {
182+ updateFileNameCompletion();
183+ }
184+ }
185+
186+ protected abstract ActionMap createActionMap();
187+
188+
189+ protected void installDefaults(JFileChooser fc) {
190+ super.installDefaults(fc);
191+ updateStyle(fc);
192+ }
193+
194+ protected void uninstallDefaults(JFileChooser fc) {
195+ super.uninstallDefaults(fc);
196+
197+ SynthContext context = getContext(getFileChooser(), ENABLED);
198+ style.uninstallDefaults(context);
199+ style = null;
200+ }
201+
202+ protected void installIcons(JFileChooser fc) {
203+ // The icons are installed in updateStyle, not here
204+ }
205+
206+ public void update(Graphics g, JComponent c) {
207+ SynthContext context = getContext(c);
208+
209+ if (c.isOpaque()) {
210+ g.setColor(style.getColor(context, ColorType.BACKGROUND));
211+ g.fillRect(0, 0, c.getWidth(), c.getHeight());
212+ }
213+
214+ style.getPainter(context).paintFileChooserBackground(context,
215+ g, 0, 0, c.getWidth(), c.getHeight());
216+ paint(context, g);
217+ }
218+
219+ public void paintBorder(SynthContext context, Graphics g, int x, int y, int w, int h) {
220+ }
221+
222+ public void paint(Graphics g, JComponent c) {
223+ SynthContext context = getContext(c);
224+
225+ paint(context, g);
226+ }
227+
228+ protected void paint(SynthContext context, Graphics g) {
229+ }
230+
231+ abstract public void setFileName(String fileName);
232+ abstract public String getFileName();
233+
234+ protected void doSelectedFileChanged(PropertyChangeEvent e) {
235+ }
236+
237+ protected void doSelectedFilesChanged(PropertyChangeEvent e) {
238+ }
239+
240+ protected void doDirectoryChanged(PropertyChangeEvent e) {
241+ }
242+
243+ protected void doAccessoryChanged(PropertyChangeEvent e) {
244+ }
245+
246+ protected void doFileSelectionModeChanged(PropertyChangeEvent e) {
247+ }
248+
249+ protected void doMultiSelectionChanged(PropertyChangeEvent e) {
250+ if (!getFileChooser().isMultiSelectionEnabled()) {
251+ getFileChooser().setSelectedFiles(null);
252+ }
253+ }
254+
255+ protected void doControlButtonsChanged(PropertyChangeEvent e) {
256+ if (getFileChooser().getControlButtonsAreShown()) {
257+ approveButton.setText(getApproveButtonText(getFileChooser()));
258+ approveButton.setToolTipText(getApproveButtonToolTipText(getFileChooser()));
259+ }
260+ }
261+
262+ protected void doAncestorChanged(PropertyChangeEvent e) {
263+ }
264+
265+ public PropertyChangeListener createPropertyChangeListener(JFileChooser fc) {
266+ return new SynthFCPropertyChangeListener();
267+ }
268+
269+ private class SynthFCPropertyChangeListener implements PropertyChangeListener {
270+ public void propertyChange(PropertyChangeEvent e) {
271+ String prop = e.getPropertyName();
272+ if (prop.equals(JFileChooser.FILE_SELECTION_MODE_CHANGED_PROPERTY)) {
273+ doFileSelectionModeChanged(e);
274+ } else if (prop.equals(JFileChooser.SELECTED_FILE_CHANGED_PROPERTY)) {
275+ doSelectedFileChanged(e);
276+ } else if (prop.equals(JFileChooser.SELECTED_FILES_CHANGED_PROPERTY)) {
277+ doSelectedFilesChanged(e);
278+ } else if (prop.equals(JFileChooser.DIRECTORY_CHANGED_PROPERTY)) {
279+ doDirectoryChanged(e);
280+ } else if (prop == JFileChooser.MULTI_SELECTION_ENABLED_CHANGED_PROPERTY) {
281+ doMultiSelectionChanged(e);
282+ } else if (prop == JFileChooser.ACCESSORY_CHANGED_PROPERTY) {
283+ doAccessoryChanged(e);
284+ } else if (prop == JFileChooser.APPROVE_BUTTON_TEXT_CHANGED_PROPERTY ||
285+ prop == JFileChooser.APPROVE_BUTTON_TOOL_TIP_TEXT_CHANGED_PROPERTY ||
286+ prop == JFileChooser.DIALOG_TYPE_CHANGED_PROPERTY ||
287+ prop == JFileChooser.CONTROL_BUTTONS_ARE_SHOWN_CHANGED_PROPERTY) {
288+ doControlButtonsChanged(e);
289+ } else if (prop.equals("componentOrientation")) {
290+ ComponentOrientation o = (ComponentOrientation)e.getNewValue();
291+ JFileChooser cc = (JFileChooser)e.getSource();
292+ if (o != (ComponentOrientation)e.getOldValue()) {
293+ cc.applyComponentOrientation(o);
294+ }
295+ } else if (prop.equals("ancestor")) {
296+ doAncestorChanged(e);
297+ }
298+ }
299+ }
300+
301+
302+ /**
303+ * Responds to a File Name completion request (e.g. Tab)
304+ */
305+ private class FileNameCompletionAction extends AbstractAction {
306+ protected FileNameCompletionAction() {
307+ super("fileNameCompletion");
308+ }
309+
310+ public void actionPerformed(ActionEvent e) {
311+ JFileChooser chooser = getFileChooser();
312+
313+ String fileName = getFileName();
314+
315+ if (fileName != null) {
316+ // Remove whitespace from beginning and end of filename
317+ fileName = fileName.trim();
318+ }
319+
320+ resetGlobFilter();
321+
322+ if (fileName == null || fileName.equals("") ||
323+ (chooser.isMultiSelectionEnabled() && fileName.startsWith("\""))) {
324+ return;
325+ }
326+
327+ FileFilter currentFilter = chooser.getFileFilter();
328+ if (globFilter == null) {
329+ globFilter = new GlobFilter();
330+ }
331+ try {
332+ globFilter.setPattern(!isGlobPattern(fileName) ? fileName + "*" : fileName);
333+ if (!(currentFilter instanceof GlobFilter)) {
334+ actualFileFilter = currentFilter;
335+ }
336+ chooser.setFileFilter(null);
337+ chooser.setFileFilter(globFilter);
338+ fileNameCompletionString = fileName;
339+ } catch (PatternSyntaxException pse) {
340+ // Not a valid glob pattern. Abandon filter.
341+ }
342+ }
343+ }
344+
345+ private String fileNameCompletionString;
346+
347+ private void updateFileNameCompletion() {
348+ if (fileNameCompletionString != null) {
349+ if (fileNameCompletionString.equals(getFileName())) {
350+ File[] files = getModel().getFiles().toArray(new File[0]);
351+ String str = getCommonStartString(files);
352+ if (str != null && str.startsWith(fileNameCompletionString)) {
353+ setFileName(str);
354+ }
355+ fileNameCompletionString = null;
356+ }
357+ }
358+ }
359+
360+ private String getCommonStartString(File[] files) {
361+ String str = null;
362+ String str2 = null;
363+ int i = 0;
364+ if (files.length == 0) {
365+ return null;
366+ }
367+ while (true) {
368+ for (int f = 0; f < files.length; f++) {
369+ String name = files[f].getName();
370+ if (f == 0) {
371+ if (name.length() == i) {
372+ return str;
373+ }
374+ str2 = name.substring(0, i+1);
375+ }
376+ if (!name.startsWith(str2)) {
377+ return str;
378+ }
379+ }
380+ str = str2;
381+ i++;
382+ }
383+ }
384+
385+ private void resetGlobFilter() {
386+ if (actualFileFilter != null) {
387+ JFileChooser chooser = getFileChooser();
388+ FileFilter currentFilter = chooser.getFileFilter();
389+ if (currentFilter != null && currentFilter.equals(globFilter)) {
390+ chooser.setFileFilter(actualFileFilter);
391+ chooser.removeChoosableFileFilter(globFilter);
392+ }
393+ actualFileFilter = null;
394+ }
395+ }
396+
397+ private static boolean isGlobPattern(String fileName) {
398+ return ((File.separatorChar == '\\' && fileName.indexOf('*') >= 0)
399+ || (File.separatorChar == '/' && (fileName.indexOf('*') >= 0
400+ || fileName.indexOf('?') >= 0
401+ || fileName.indexOf('[') >= 0)));
402+ }
403+
404+
405+ /* A file filter which accepts file patterns containing
406+ * the special wildcard '*' on windows, plus '?', and '[ ]' on Unix.
407+ */
408+ class GlobFilter extends FileFilter {
409+ Pattern pattern;
410+ String globPattern;
411+
412+ public void setPattern(String globPattern) {
413+ char[] gPat = globPattern.toCharArray();
414+ char[] rPat = new char[gPat.length * 2];
415+ boolean isWin32 = (File.separatorChar == '\\');
416+ boolean inBrackets = false;
417+ int j = 0;
418+
419+ this.globPattern = globPattern;
420+
421+ if (isWin32) {
422+ // On windows, a pattern ending with *.* is equal to ending with *
423+ int len = gPat.length;
424+ if (globPattern.endsWith("*.*")) {
425+ len -= 2;
426+ }
427+ for (int i = 0; i < len; i++) {
428+ if (gPat[i] == '*') {
429+ rPat[j++] = '.';
430+ }
431+ rPat[j++] = gPat[i];
432+ }
433+ } else {
434+ for (int i = 0; i < gPat.length; i++) {
435+ switch(gPat[i]) {
436+ case '*':
437+ if (!inBrackets) {
438+ rPat[j++] = '.';
439+ }
440+ rPat[j++] = '*';
441+ break;
442+
443+ case '?':
444+ rPat[j++] = inBrackets ? '?' : '.';
445+ break;
446+
447+ case '[':
448+ inBrackets = true;
449+ rPat[j++] = gPat[i];
450+
451+ if (i < gPat.length - 1) {
452+ switch (gPat[i+1]) {
453+ case '!':
454+ case '^':
455+ rPat[j++] = '^';
456+ i++;
457+ break;
458+
459+ case ']':
460+ rPat[j++] = gPat[++i];
461+ break;
462+ }
463+ }
464+ break;
465+
466+ case ']':
467+ rPat[j++] = gPat[i];
468+ inBrackets = false;
469+ break;
470+
471+ case '\\':
472+ if (i == 0 && gPat.length > 1 && gPat[1] == '~') {
473+ rPat[j++] = gPat[++i];
474+ } else {
475+ rPat[j++] = '\\';
476+ if (i < gPat.length - 1 && "*?[]".indexOf(gPat[i+1]) >= 0) {
477+ rPat[j++] = gPat[++i];
478+ } else {
479+ rPat[j++] = '\\';
480+ }
481+ }
482+ break;
483+
484+ default:
485+ //if ("+()|^$.{}<>".indexOf(gPat[i]) >= 0) {
486+ if (!Character.isLetterOrDigit(gPat[i])) {
487+ rPat[j++] = '\\';
488+ }
489+ rPat[j++] = gPat[i];
490+ break;
491+ }
492+ }
493+ }
494+ this.pattern = Pattern.compile(new String(rPat, 0, j), Pattern.CASE_INSENSITIVE);
495+ }
496+
497+ public boolean accept(File f) {
498+ if (f == null) {
499+ return false;
500+ }
501+ if (f.isDirectory()) {
502+ return true;
503+ }
504+ return pattern.matcher(f.getName()).matches();
505+ }
506+
507+ public String getDescription() {
508+ return globPattern;
509+ }
510+ }
511+
512+
513+ // *******************************************************
514+ // ************ FileChooser UI PLAF methods **************
515+ // *******************************************************
516+
517+
518+ // *****************************
519+ // ***** Directory Actions *****
520+ // *****************************
521+
522+ public Action getFileNameCompletionAction() {
523+ return fileNameCompletionAction;
524+ }
525+
526+
527+ protected JButton getApproveButton(JFileChooser fc) {
528+ return approveButton;
529+ }
530+
531+ protected JButton getCancelButton(JFileChooser fc) {
532+ return cancelButton;
533+ }
534+
535+
536+ // Overload to do nothing. We don't have and icon cache.
537+ public void clearIconCache() { }
538+
539+ // Copied as SynthBorder is package private in synth
540+ private class UIBorder extends AbstractBorder implements UIResource {
541+ private Insets _insets;
542+ UIBorder(Insets insets) {
543+ if (insets != null) {
544+ _insets = new Insets(insets.top, insets.left, insets.bottom,
545+ insets.right);
546+ }
547+ else {
548+ _insets = null;
549+ }
550+ }
551+
552+ public void paintBorder(Component c, Graphics g, int x, int y,
553+ int width, int height) {
554+ if (!(c instanceof JComponent)) {
555+ return;
556+ }
557+ JComponent jc = (JComponent)c;
558+ SynthContext context = getContext(jc);
559+ SynthStyle style = context.getStyle();
560+ if (style != null) {
561+ style.getPainter(context).paintFileChooserBorder(
562+ context, g, x, y, width, height);
563+ }
564+ }
565+
566+ public Insets getBorderInsets(Component c, Insets insets) {
567+ if (insets == null) {
568+ insets = new Insets(0, 0, 0, 0);
569+ }
570+ if (_insets != null) {
571+ insets.top = _insets.top;
572+ insets.bottom = _insets.bottom;
573+ insets.left = _insets.left;
574+ insets.right = _insets.right;
575+ }
576+ else {
577+ insets.top = insets.bottom = insets.right = insets.left = 0;
578+ }
579+ return insets;
580+ }
581+ public boolean isBorderOpaque() {
582+ return false;
583+ }
584+ }
585+}