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 */
25package sun.swing.plaf.synth;
26
27import javax.swing.plaf.synth.*;
28import java.awt.*;
29import java.awt.event.*;
30import java.beans.*;
31import java.io.File;
32import java.util.regex.*;
33
34import javax.swing.*;
35import javax.swing.border.*;
36import javax.swing.event.*;
37import javax.swing.filechooser.*;
38import javax.swing.plaf.*;
39import 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 */
58public 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}