Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/swing/plaf/synth/SynthFileChooserUI.java
38918 views
1
/*
2
* Copyright (c) 2002, 2012, 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
approveButton.setMnemonic(getApproveButtonMnemonic(getFileChooser()));
260
}
261
}
262
263
protected void doAncestorChanged(PropertyChangeEvent e) {
264
}
265
266
public PropertyChangeListener createPropertyChangeListener(JFileChooser fc) {
267
return new SynthFCPropertyChangeListener();
268
}
269
270
private class SynthFCPropertyChangeListener implements PropertyChangeListener {
271
public void propertyChange(PropertyChangeEvent e) {
272
String prop = e.getPropertyName();
273
if (prop.equals(JFileChooser.FILE_SELECTION_MODE_CHANGED_PROPERTY)) {
274
doFileSelectionModeChanged(e);
275
} else if (prop.equals(JFileChooser.SELECTED_FILE_CHANGED_PROPERTY)) {
276
doSelectedFileChanged(e);
277
} else if (prop.equals(JFileChooser.SELECTED_FILES_CHANGED_PROPERTY)) {
278
doSelectedFilesChanged(e);
279
} else if (prop.equals(JFileChooser.DIRECTORY_CHANGED_PROPERTY)) {
280
doDirectoryChanged(e);
281
} else if (prop == JFileChooser.MULTI_SELECTION_ENABLED_CHANGED_PROPERTY) {
282
doMultiSelectionChanged(e);
283
} else if (prop == JFileChooser.ACCESSORY_CHANGED_PROPERTY) {
284
doAccessoryChanged(e);
285
} else if (prop == JFileChooser.APPROVE_BUTTON_TEXT_CHANGED_PROPERTY ||
286
prop == JFileChooser.APPROVE_BUTTON_TOOL_TIP_TEXT_CHANGED_PROPERTY ||
287
prop == JFileChooser.DIALOG_TYPE_CHANGED_PROPERTY ||
288
prop == JFileChooser.CONTROL_BUTTONS_ARE_SHOWN_CHANGED_PROPERTY) {
289
doControlButtonsChanged(e);
290
} else if (prop.equals("componentOrientation")) {
291
ComponentOrientation o = (ComponentOrientation)e.getNewValue();
292
JFileChooser cc = (JFileChooser)e.getSource();
293
if (o != (ComponentOrientation)e.getOldValue()) {
294
cc.applyComponentOrientation(o);
295
}
296
} else if (prop.equals("ancestor")) {
297
doAncestorChanged(e);
298
}
299
}
300
}
301
302
303
/**
304
* Responds to a File Name completion request (e.g. Tab)
305
*/
306
private class FileNameCompletionAction extends AbstractAction {
307
protected FileNameCompletionAction() {
308
super("fileNameCompletion");
309
}
310
311
public void actionPerformed(ActionEvent e) {
312
JFileChooser chooser = getFileChooser();
313
314
String fileName = getFileName();
315
316
if (fileName != null) {
317
// Remove whitespace from beginning and end of filename
318
fileName = fileName.trim();
319
}
320
321
resetGlobFilter();
322
323
if (fileName == null || fileName.equals("") ||
324
(chooser.isMultiSelectionEnabled() && fileName.startsWith("\""))) {
325
return;
326
}
327
328
FileFilter currentFilter = chooser.getFileFilter();
329
if (globFilter == null) {
330
globFilter = new GlobFilter();
331
}
332
try {
333
globFilter.setPattern(!isGlobPattern(fileName) ? fileName + "*" : fileName);
334
if (!(currentFilter instanceof GlobFilter)) {
335
actualFileFilter = currentFilter;
336
}
337
chooser.setFileFilter(null);
338
chooser.setFileFilter(globFilter);
339
fileNameCompletionString = fileName;
340
} catch (PatternSyntaxException pse) {
341
// Not a valid glob pattern. Abandon filter.
342
}
343
}
344
}
345
346
private String fileNameCompletionString;
347
348
private void updateFileNameCompletion() {
349
if (fileNameCompletionString != null) {
350
if (fileNameCompletionString.equals(getFileName())) {
351
File[] files = getModel().getFiles().toArray(new File[0]);
352
String str = getCommonStartString(files);
353
if (str != null && str.startsWith(fileNameCompletionString)) {
354
setFileName(str);
355
}
356
fileNameCompletionString = null;
357
}
358
}
359
}
360
361
private String getCommonStartString(File[] files) {
362
String str = null;
363
String str2 = null;
364
int i = 0;
365
if (files.length == 0) {
366
return null;
367
}
368
while (true) {
369
for (int f = 0; f < files.length; f++) {
370
String name = files[f].getName();
371
if (f == 0) {
372
if (name.length() == i) {
373
return str;
374
}
375
str2 = name.substring(0, i+1);
376
}
377
if (!name.startsWith(str2)) {
378
return str;
379
}
380
}
381
str = str2;
382
i++;
383
}
384
}
385
386
private void resetGlobFilter() {
387
if (actualFileFilter != null) {
388
JFileChooser chooser = getFileChooser();
389
FileFilter currentFilter = chooser.getFileFilter();
390
if (currentFilter != null && currentFilter.equals(globFilter)) {
391
chooser.setFileFilter(actualFileFilter);
392
chooser.removeChoosableFileFilter(globFilter);
393
}
394
actualFileFilter = null;
395
}
396
}
397
398
private static boolean isGlobPattern(String fileName) {
399
return ((File.separatorChar == '\\' && fileName.indexOf('*') >= 0)
400
|| (File.separatorChar == '/' && (fileName.indexOf('*') >= 0
401
|| fileName.indexOf('?') >= 0
402
|| fileName.indexOf('[') >= 0)));
403
}
404
405
406
/* A file filter which accepts file patterns containing
407
* the special wildcard '*' on windows, plus '?', and '[ ]' on Unix.
408
*/
409
class GlobFilter extends FileFilter {
410
Pattern pattern;
411
String globPattern;
412
413
public void setPattern(String globPattern) {
414
char[] gPat = globPattern.toCharArray();
415
char[] rPat = new char[gPat.length * 2];
416
boolean isWin32 = (File.separatorChar == '\\');
417
boolean inBrackets = false;
418
int j = 0;
419
420
this.globPattern = globPattern;
421
422
if (isWin32) {
423
// On windows, a pattern ending with *.* is equal to ending with *
424
int len = gPat.length;
425
if (globPattern.endsWith("*.*")) {
426
len -= 2;
427
}
428
for (int i = 0; i < len; i++) {
429
if (gPat[i] == '*') {
430
rPat[j++] = '.';
431
}
432
rPat[j++] = gPat[i];
433
}
434
} else {
435
for (int i = 0; i < gPat.length; i++) {
436
switch(gPat[i]) {
437
case '*':
438
if (!inBrackets) {
439
rPat[j++] = '.';
440
}
441
rPat[j++] = '*';
442
break;
443
444
case '?':
445
rPat[j++] = inBrackets ? '?' : '.';
446
break;
447
448
case '[':
449
inBrackets = true;
450
rPat[j++] = gPat[i];
451
452
if (i < gPat.length - 1) {
453
switch (gPat[i+1]) {
454
case '!':
455
case '^':
456
rPat[j++] = '^';
457
i++;
458
break;
459
460
case ']':
461
rPat[j++] = gPat[++i];
462
break;
463
}
464
}
465
break;
466
467
case ']':
468
rPat[j++] = gPat[i];
469
inBrackets = false;
470
break;
471
472
case '\\':
473
if (i == 0 && gPat.length > 1 && gPat[1] == '~') {
474
rPat[j++] = gPat[++i];
475
} else {
476
rPat[j++] = '\\';
477
if (i < gPat.length - 1 && "*?[]".indexOf(gPat[i+1]) >= 0) {
478
rPat[j++] = gPat[++i];
479
} else {
480
rPat[j++] = '\\';
481
}
482
}
483
break;
484
485
default:
486
//if ("+()|^$.{}<>".indexOf(gPat[i]) >= 0) {
487
if (!Character.isLetterOrDigit(gPat[i])) {
488
rPat[j++] = '\\';
489
}
490
rPat[j++] = gPat[i];
491
break;
492
}
493
}
494
}
495
this.pattern = Pattern.compile(new String(rPat, 0, j), Pattern.CASE_INSENSITIVE);
496
}
497
498
public boolean accept(File f) {
499
if (f == null) {
500
return false;
501
}
502
if (f.isDirectory()) {
503
return true;
504
}
505
return pattern.matcher(f.getName()).matches();
506
}
507
508
public String getDescription() {
509
return globPattern;
510
}
511
}
512
513
514
// *******************************************************
515
// ************ FileChooser UI PLAF methods **************
516
// *******************************************************
517
518
519
// *****************************
520
// ***** Directory Actions *****
521
// *****************************
522
523
public Action getFileNameCompletionAction() {
524
return fileNameCompletionAction;
525
}
526
527
528
protected JButton getApproveButton(JFileChooser fc) {
529
return approveButton;
530
}
531
532
protected JButton getCancelButton(JFileChooser fc) {
533
return cancelButton;
534
}
535
536
537
// Overload to do nothing. We don't have and icon cache.
538
public void clearIconCache() { }
539
540
// Copied as SynthBorder is package private in synth
541
private class UIBorder extends AbstractBorder implements UIResource {
542
private Insets _insets;
543
UIBorder(Insets insets) {
544
if (insets != null) {
545
_insets = new Insets(insets.top, insets.left, insets.bottom,
546
insets.right);
547
}
548
else {
549
_insets = null;
550
}
551
}
552
553
public void paintBorder(Component c, Graphics g, int x, int y,
554
int width, int height) {
555
if (!(c instanceof JComponent)) {
556
return;
557
}
558
JComponent jc = (JComponent)c;
559
SynthContext context = getContext(jc);
560
SynthStyle style = context.getStyle();
561
if (style != null) {
562
style.getPainter(context).paintFileChooserBorder(
563
context, g, x, y, width, height);
564
}
565
}
566
567
public Insets getBorderInsets(Component c, Insets insets) {
568
if (insets == null) {
569
insets = new Insets(0, 0, 0, 0);
570
}
571
if (_insets != null) {
572
insets.top = _insets.top;
573
insets.bottom = _insets.bottom;
574
insets.left = _insets.left;
575
insets.right = _insets.right;
576
}
577
else {
578
insets.top = insets.bottom = insets.right = insets.left = 0;
579
}
580
return insets;
581
}
582
public boolean isBorderOpaque() {
583
return false;
584
}
585
}
586
}
587
588