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