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/SynthFileChooserUIImpl.java
41161 views
1
/*
2
* Copyright (c) 2003, 2014, 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 java.awt.*;
28
import java.awt.event.*;
29
import java.beans.*;
30
import java.io.*;
31
import java.util.*;
32
import java.security.AccessController;
33
import java.security.PrivilegedAction;
34
35
import javax.swing.*;
36
import javax.swing.event.*;
37
import javax.swing.filechooser.*;
38
import javax.swing.filechooser.FileFilter;
39
import javax.swing.plaf.basic.*;
40
import javax.swing.plaf.synth.*;
41
import javax.swing.plaf.ActionMapUIResource;
42
43
import sun.awt.shell.ShellFolder;
44
import sun.swing.*;
45
46
/**
47
* Synth FileChooserUI implementation.
48
* <p>
49
* Note that the classes in the com.sun.java.swing.plaf.synth
50
* package are not
51
* part of the core Java APIs. They are a part of Sun's JDK and JRE
52
* distributions. Although other licensees may choose to distribute
53
* these classes, developers cannot depend on their availability in
54
* non-Sun implementations. Additionally this API may change in
55
* incompatible ways between releases. While this class is public, it
56
* shoud be considered an implementation detail, and subject to change.
57
*
58
* @author Leif Samuelsson
59
* @author Jeff Dinkins
60
*/
61
public class SynthFileChooserUIImpl extends SynthFileChooserUI {
62
private JLabel lookInLabel;
63
private JComboBox<File> directoryComboBox;
64
private DirectoryComboBoxModel directoryComboBoxModel;
65
private Action directoryComboBoxAction = new DirectoryComboBoxAction();
66
67
private FilterComboBoxModel filterComboBoxModel;
68
69
private JTextField fileNameTextField;
70
71
private FilePane filePane;
72
private JToggleButton listViewButton;
73
private JToggleButton detailsViewButton;
74
75
private boolean readOnly;
76
77
private JPanel buttonPanel;
78
private JPanel bottomPanel;
79
80
private JComboBox<FileFilter> filterComboBox;
81
82
private static final Dimension hstrut5 = new Dimension(5, 1);
83
84
private static final Insets shrinkwrap = new Insets(0,0,0,0);
85
86
// Preferred and Minimum sizes for the dialog box
87
private static Dimension LIST_PREF_SIZE = new Dimension(405, 135);
88
89
// Labels, mnemonics, and tooltips (oh my!)
90
private int lookInLabelMnemonic = 0;
91
private String lookInLabelText = null;
92
private String saveInLabelText = null;
93
94
private int fileNameLabelMnemonic = 0;
95
private String fileNameLabelText = null;
96
private int folderNameLabelMnemonic = 0;
97
private String folderNameLabelText = null;
98
99
private int filesOfTypeLabelMnemonic = 0;
100
private String filesOfTypeLabelText = null;
101
102
private String upFolderToolTipText = null;
103
private String upFolderAccessibleName = null;
104
105
private String homeFolderToolTipText = null;
106
private String homeFolderAccessibleName = null;
107
108
private String newFolderToolTipText = null;
109
private String newFolderAccessibleName = null;
110
111
private String listViewButtonToolTipText = null;
112
private String listViewButtonAccessibleName = null;
113
114
private String detailsViewButtonToolTipText = null;
115
private String detailsViewButtonAccessibleName = null;
116
117
private AlignedLabel fileNameLabel;
118
private final PropertyChangeListener modeListener = new PropertyChangeListener() {
119
public void propertyChange(PropertyChangeEvent event) {
120
if (fileNameLabel != null) {
121
populateFileNameLabel();
122
}
123
}
124
};
125
126
private void populateFileNameLabel() {
127
if (getFileChooser().getFileSelectionMode() == JFileChooser.DIRECTORIES_ONLY) {
128
fileNameLabel.setText(folderNameLabelText);
129
fileNameLabel.setDisplayedMnemonic(folderNameLabelMnemonic);
130
} else {
131
fileNameLabel.setText(fileNameLabelText);
132
fileNameLabel.setDisplayedMnemonic(fileNameLabelMnemonic);
133
}
134
}
135
136
public SynthFileChooserUIImpl(JFileChooser b) {
137
super(b);
138
}
139
140
141
private class SynthFileChooserUIAccessor implements FilePane.FileChooserUIAccessor {
142
public JFileChooser getFileChooser() {
143
return SynthFileChooserUIImpl.this.getFileChooser();
144
}
145
146
public BasicDirectoryModel getModel() {
147
return SynthFileChooserUIImpl.this.getModel();
148
}
149
150
public JPanel createList() {
151
return null;
152
}
153
154
public JPanel createDetailsView() {
155
return null;
156
}
157
158
public boolean isDirectorySelected() {
159
return SynthFileChooserUIImpl.this.isDirectorySelected();
160
}
161
162
public File getDirectory() {
163
return SynthFileChooserUIImpl.this.getDirectory();
164
}
165
166
public Action getChangeToParentDirectoryAction() {
167
return SynthFileChooserUIImpl.this.getChangeToParentDirectoryAction();
168
}
169
170
public Action getApproveSelectionAction() {
171
return SynthFileChooserUIImpl.this.getApproveSelectionAction();
172
}
173
174
public Action getNewFolderAction() {
175
return SynthFileChooserUIImpl.this.getNewFolderAction();
176
}
177
178
public MouseListener createDoubleClickListener(JList<?> list) {
179
return SynthFileChooserUIImpl.this.createDoubleClickListener(getFileChooser(),
180
list);
181
}
182
183
public ListSelectionListener createListSelectionListener() {
184
return SynthFileChooserUIImpl.this.createListSelectionListener(getFileChooser());
185
}
186
}
187
188
protected void installDefaults(JFileChooser fc) {
189
super.installDefaults(fc);
190
readOnly = UIManager.getBoolean("FileChooser.readOnly");
191
}
192
193
@SuppressWarnings("serial") // anonymous classes inside
194
public void installComponents(JFileChooser fc) {
195
super.installComponents(fc);
196
197
SynthContext context = getContext(fc, ENABLED);
198
199
fc.setLayout(new BorderLayout(0, 11));
200
201
// ********************************* //
202
// **** Construct the top panel **** //
203
// ********************************* //
204
205
// Directory manipulation buttons
206
JPanel topPanel = new JPanel(new BorderLayout(11, 0));
207
JPanel topButtonPanel = new JPanel();
208
topButtonPanel.setLayout(new BoxLayout(topButtonPanel, BoxLayout.LINE_AXIS));
209
topPanel.add(topButtonPanel, BorderLayout.AFTER_LINE_ENDS);
210
211
// Add the top panel to the fileChooser
212
fc.add(topPanel, BorderLayout.NORTH);
213
214
// ComboBox Label
215
lookInLabel = new JLabel(lookInLabelText);
216
lookInLabel.setDisplayedMnemonic(lookInLabelMnemonic);
217
topPanel.add(lookInLabel, BorderLayout.BEFORE_LINE_BEGINS);
218
219
// CurrentDir ComboBox
220
directoryComboBox = new JComboBox<File>();
221
directoryComboBox.getAccessibleContext().setAccessibleDescription(lookInLabelText);
222
directoryComboBox.putClientProperty( "JComboBox.isTableCellEditor", Boolean.TRUE );
223
lookInLabel.setLabelFor(directoryComboBox);
224
directoryComboBoxModel = createDirectoryComboBoxModel(fc);
225
directoryComboBox.setModel(directoryComboBoxModel);
226
directoryComboBox.addActionListener(directoryComboBoxAction);
227
directoryComboBox.setRenderer(createDirectoryComboBoxRenderer(fc));
228
directoryComboBox.setAlignmentX(JComponent.LEFT_ALIGNMENT);
229
directoryComboBox.setAlignmentY(JComponent.TOP_ALIGNMENT);
230
directoryComboBox.setMaximumRowCount(8);
231
topPanel.add(directoryComboBox, BorderLayout.CENTER);
232
233
filePane = new FilePane(new SynthFileChooserUIAccessor());
234
fc.addPropertyChangeListener(filePane);
235
236
// Add 'Go Up' to context menu, plus 'Go Home' if on Unix
237
JPopupMenu contextMenu = filePane.getComponentPopupMenu();
238
if (contextMenu != null) {
239
contextMenu.insert(getChangeToParentDirectoryAction(), 0);
240
if (File.separatorChar == '/') {
241
contextMenu.insert(getGoHomeAction(), 1);
242
}
243
}
244
245
FileSystemView fsv = fc.getFileSystemView();
246
247
// Up Button
248
JButton upFolderButton = new JButton(getChangeToParentDirectoryAction());
249
upFolderButton.setText(null);
250
upFolderButton.setIcon(upFolderIcon);
251
upFolderButton.setToolTipText(upFolderToolTipText);
252
upFolderButton.getAccessibleContext().setAccessibleName(upFolderAccessibleName);
253
upFolderButton.setAlignmentX(JComponent.LEFT_ALIGNMENT);
254
upFolderButton.setAlignmentY(JComponent.CENTER_ALIGNMENT);
255
upFolderButton.setMargin(shrinkwrap);
256
257
topButtonPanel.add(upFolderButton);
258
topButtonPanel.add(Box.createRigidArea(hstrut5));
259
260
// Home Button
261
File homeDir = fsv.getHomeDirectory();
262
String toolTipText = homeFolderToolTipText;
263
264
JButton b = new JButton(homeFolderIcon);
265
b.setToolTipText(toolTipText);
266
b.getAccessibleContext().setAccessibleName(homeFolderAccessibleName);
267
b.setAlignmentX(JComponent.LEFT_ALIGNMENT);
268
b.setAlignmentY(JComponent.CENTER_ALIGNMENT);
269
b.setMargin(shrinkwrap);
270
271
b.addActionListener(getGoHomeAction());
272
topButtonPanel.add(b);
273
topButtonPanel.add(Box.createRigidArea(hstrut5));
274
275
// New Directory Button
276
if (!readOnly) {
277
b = new JButton(filePane.getNewFolderAction());
278
b.setText(null);
279
b.setIcon(newFolderIcon);
280
b.setToolTipText(newFolderToolTipText);
281
b.getAccessibleContext().setAccessibleName(newFolderAccessibleName);
282
b.setAlignmentX(JComponent.LEFT_ALIGNMENT);
283
b.setAlignmentY(JComponent.CENTER_ALIGNMENT);
284
b.setMargin(shrinkwrap);
285
topButtonPanel.add(b);
286
topButtonPanel.add(Box.createRigidArea(hstrut5));
287
}
288
289
// View button group
290
ButtonGroup viewButtonGroup = new ButtonGroup();
291
292
// List Button
293
listViewButton = new JToggleButton(listViewIcon);
294
listViewButton.setToolTipText(listViewButtonToolTipText);
295
listViewButton.getAccessibleContext().setAccessibleName(listViewButtonAccessibleName);
296
listViewButton.setSelected(true);
297
listViewButton.setAlignmentX(JComponent.LEFT_ALIGNMENT);
298
listViewButton.setAlignmentY(JComponent.CENTER_ALIGNMENT);
299
listViewButton.setMargin(shrinkwrap);
300
listViewButton.addActionListener(filePane.getViewTypeAction(FilePane.VIEWTYPE_LIST));
301
topButtonPanel.add(listViewButton);
302
viewButtonGroup.add(listViewButton);
303
304
// Details Button
305
detailsViewButton = new JToggleButton(detailsViewIcon);
306
detailsViewButton.setToolTipText(detailsViewButtonToolTipText);
307
detailsViewButton.getAccessibleContext().setAccessibleName(detailsViewButtonAccessibleName);
308
detailsViewButton.setAlignmentX(JComponent.LEFT_ALIGNMENT);
309
detailsViewButton.setAlignmentY(JComponent.CENTER_ALIGNMENT);
310
detailsViewButton.setMargin(shrinkwrap);
311
detailsViewButton.addActionListener(filePane.getViewTypeAction(FilePane.VIEWTYPE_DETAILS));
312
topButtonPanel.add(detailsViewButton);
313
viewButtonGroup.add(detailsViewButton);
314
315
filePane.addPropertyChangeListener(new PropertyChangeListener() {
316
public void propertyChange(PropertyChangeEvent e) {
317
if ("viewType".equals(e.getPropertyName())) {
318
int viewType = filePane.getViewType();
319
switch (viewType) {
320
case FilePane.VIEWTYPE_LIST:
321
listViewButton.setSelected(true);
322
break;
323
case FilePane.VIEWTYPE_DETAILS:
324
detailsViewButton.setSelected(true);
325
break;
326
}
327
}
328
}
329
});
330
331
// ************************************** //
332
// ******* Add the directory pane ******* //
333
// ************************************** //
334
fc.add(getAccessoryPanel(), BorderLayout.AFTER_LINE_ENDS);
335
JComponent accessory = fc.getAccessory();
336
if (accessory != null) {
337
getAccessoryPanel().add(accessory);
338
}
339
filePane.setPreferredSize(LIST_PREF_SIZE);
340
fc.add(filePane, BorderLayout.CENTER);
341
342
343
// ********************************** //
344
// **** Construct the bottom panel ** //
345
// ********************************** //
346
bottomPanel = new JPanel();
347
bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.Y_AXIS));
348
fc.add(bottomPanel, BorderLayout.SOUTH);
349
350
// FileName label and textfield
351
JPanel fileNamePanel = new JPanel();
352
fileNamePanel.setLayout(new BoxLayout(fileNamePanel, BoxLayout.LINE_AXIS));
353
bottomPanel.add(fileNamePanel);
354
bottomPanel.add(Box.createRigidArea(new Dimension(1, 5)));
355
356
fileNameLabel = new AlignedLabel();
357
populateFileNameLabel();
358
fileNamePanel.add(fileNameLabel);
359
360
fileNameTextField = new JTextField(35) {
361
public Dimension getMaximumSize() {
362
return new Dimension(Short.MAX_VALUE, super.getPreferredSize().height);
363
}
364
};
365
fileNamePanel.add(fileNameTextField);
366
fileNameLabel.setLabelFor(fileNameTextField);
367
fileNameTextField.addFocusListener(
368
new FocusAdapter() {
369
public void focusGained(FocusEvent e) {
370
if (!getFileChooser().isMultiSelectionEnabled()) {
371
filePane.clearSelection();
372
}
373
}
374
}
375
);
376
if (fc.isMultiSelectionEnabled()) {
377
setFileName(fileNameString(fc.getSelectedFiles()));
378
} else {
379
setFileName(fileNameString(fc.getSelectedFile()));
380
}
381
382
383
// Filetype label and combobox
384
JPanel filesOfTypePanel = new JPanel();
385
filesOfTypePanel.setLayout(new BoxLayout(filesOfTypePanel, BoxLayout.LINE_AXIS));
386
bottomPanel.add(filesOfTypePanel);
387
388
AlignedLabel filesOfTypeLabel = new AlignedLabel(filesOfTypeLabelText);
389
filesOfTypeLabel.setDisplayedMnemonic(filesOfTypeLabelMnemonic);
390
filesOfTypePanel.add(filesOfTypeLabel);
391
392
filterComboBoxModel = createFilterComboBoxModel();
393
fc.addPropertyChangeListener(filterComboBoxModel);
394
filterComboBox = new JComboBox<FileFilter>(filterComboBoxModel);
395
filterComboBox.getAccessibleContext().setAccessibleDescription(filesOfTypeLabelText);
396
filesOfTypeLabel.setLabelFor(filterComboBox);
397
filterComboBox.setRenderer(createFilterComboBoxRenderer());
398
filesOfTypePanel.add(filterComboBox);
399
400
401
// buttons
402
buttonPanel = new JPanel();
403
buttonPanel.setLayout(new ButtonAreaLayout());
404
405
buttonPanel.add(getApproveButton(fc));
406
buttonPanel.add(getCancelButton(fc));
407
408
if (fc.getControlButtonsAreShown()) {
409
addControlButtons();
410
}
411
412
groupLabels(new AlignedLabel[] { fileNameLabel, filesOfTypeLabel });
413
}
414
415
protected void installListeners(JFileChooser fc) {
416
super.installListeners(fc);
417
fc.addPropertyChangeListener(JFileChooser.FILE_SELECTION_MODE_CHANGED_PROPERTY, modeListener);
418
}
419
420
protected void uninstallListeners(JFileChooser fc) {
421
fc.removePropertyChangeListener(JFileChooser.FILE_SELECTION_MODE_CHANGED_PROPERTY, modeListener);
422
super.uninstallListeners(fc);
423
}
424
425
private String fileNameString(File file) {
426
if (file == null) {
427
return null;
428
} else {
429
JFileChooser fc = getFileChooser();
430
if (fc.isDirectorySelectionEnabled() && !fc.isFileSelectionEnabled()) {
431
return file.getPath();
432
} else {
433
return file.getName();
434
}
435
}
436
}
437
438
private String fileNameString(File[] files) {
439
StringBuilder sb = new StringBuilder();
440
for (int i = 0; files != null && i < files.length; i++) {
441
if (i > 0) {
442
sb.append(" ");
443
}
444
if (files.length > 1) {
445
sb.append("\"");
446
}
447
sb.append(fileNameString(files[i]));
448
if (files.length > 1) {
449
sb.append("\"");
450
}
451
}
452
return sb.toString();
453
}
454
455
public void uninstallUI(JComponent c) {
456
// Remove listeners
457
c.removePropertyChangeListener(filterComboBoxModel);
458
c.removePropertyChangeListener(filePane);
459
460
if (filePane != null) {
461
filePane.uninstallUI();
462
filePane = null;
463
}
464
465
super.uninstallUI(c);
466
}
467
468
protected void installStrings(JFileChooser fc) {
469
super.installStrings(fc);
470
471
Locale l = fc.getLocale();
472
473
lookInLabelMnemonic = getMnemonic("FileChooser.lookInLabelMnemonic", l);
474
lookInLabelText = UIManager.getString("FileChooser.lookInLabelText", l);
475
saveInLabelText = UIManager.getString("FileChooser.saveInLabelText", l);
476
477
fileNameLabelMnemonic = getMnemonic("FileChooser.fileNameLabelMnemonic", l);
478
fileNameLabelText = UIManager.getString("FileChooser.fileNameLabelText", l);
479
folderNameLabelMnemonic = getMnemonic("FileChooser.folderNameLabelMnemonic", l);
480
folderNameLabelText = UIManager.getString("FileChooser.folderNameLabelText", l);
481
482
filesOfTypeLabelMnemonic = getMnemonic("FileChooser.filesOfTypeLabelMnemonic", l);
483
filesOfTypeLabelText = UIManager.getString("FileChooser.filesOfTypeLabelText", l);
484
485
upFolderToolTipText = UIManager.getString("FileChooser.upFolderToolTipText",l);
486
upFolderAccessibleName = UIManager.getString("FileChooser.upFolderAccessibleName",l);
487
488
homeFolderToolTipText = UIManager.getString("FileChooser.homeFolderToolTipText",l);
489
homeFolderAccessibleName = UIManager.getString("FileChooser.homeFolderAccessibleName",l);
490
491
newFolderToolTipText = UIManager.getString("FileChooser.newFolderToolTipText",l);
492
newFolderAccessibleName = UIManager.getString("FileChooser.newFolderAccessibleName",l);
493
494
listViewButtonToolTipText = UIManager.getString("FileChooser.listViewButtonToolTipText",l);
495
listViewButtonAccessibleName = UIManager.getString("FileChooser.listViewButtonAccessibleName",l);
496
497
detailsViewButtonToolTipText = UIManager.getString("FileChooser.detailsViewButtonToolTipText",l);
498
detailsViewButtonAccessibleName = UIManager.getString("FileChooser.detailsViewButtonAccessibleName",l);
499
}
500
501
private int getMnemonic(String key, Locale l) {
502
return SwingUtilities2.getUIDefaultsInt(key, l);
503
}
504
505
506
public String getFileName() {
507
if (fileNameTextField != null) {
508
return fileNameTextField.getText();
509
} else {
510
return null;
511
}
512
}
513
514
public void setFileName(String fileName) {
515
if (fileNameTextField != null) {
516
fileNameTextField.setText(fileName);
517
}
518
}
519
520
@Override public void rescanCurrentDirectory(JFileChooser fc) {
521
filePane.rescanCurrentDirectory();
522
}
523
524
protected void doSelectedFileChanged(PropertyChangeEvent e) {
525
super.doSelectedFileChanged(e);
526
527
File f = (File) e.getNewValue();
528
JFileChooser fc = getFileChooser();
529
if (f != null
530
&& ((fc.isFileSelectionEnabled() && !f.isDirectory())
531
|| (f.isDirectory() && fc.isDirectorySelectionEnabled()))) {
532
533
setFileName(fileNameString(f));
534
}
535
}
536
537
protected void doSelectedFilesChanged(PropertyChangeEvent e) {
538
super.doSelectedFilesChanged(e);
539
540
File[] files = (File[]) e.getNewValue();
541
JFileChooser fc = getFileChooser();
542
if (files != null
543
&& files.length > 0
544
&& (files.length > 1 || fc.isDirectorySelectionEnabled() || !files[0].isDirectory())) {
545
setFileName(fileNameString(files));
546
}
547
}
548
549
protected void doDirectoryChanged(PropertyChangeEvent e) {
550
super.doDirectoryChanged(e);
551
552
JFileChooser fc = getFileChooser();
553
FileSystemView fsv = fc.getFileSystemView();
554
File currentDirectory = fc.getCurrentDirectory();
555
556
if (!readOnly && currentDirectory != null) {
557
getNewFolderAction().setEnabled(filePane.canWrite(currentDirectory));
558
}
559
560
if (currentDirectory != null) {
561
JComponent cb = getDirectoryComboBox();
562
if (cb instanceof JComboBox) {
563
ComboBoxModel<?> model = ((JComboBox)cb).getModel();
564
if (model instanceof DirectoryComboBoxModel) {
565
((DirectoryComboBoxModel)model).addItem(currentDirectory);
566
}
567
}
568
569
if (fc.isDirectorySelectionEnabled() && !fc.isFileSelectionEnabled()) {
570
if (fsv.isFileSystem(currentDirectory)) {
571
setFileName(currentDirectory.getPath());
572
} else {
573
setFileName(null);
574
}
575
}
576
}
577
}
578
579
580
protected void doFileSelectionModeChanged(PropertyChangeEvent e) {
581
super.doFileSelectionModeChanged(e);
582
583
JFileChooser fc = getFileChooser();
584
File currentDirectory = fc.getCurrentDirectory();
585
if (currentDirectory != null
586
&& fc.isDirectorySelectionEnabled()
587
&& !fc.isFileSelectionEnabled()
588
&& fc.getFileSystemView().isFileSystem(currentDirectory)) {
589
590
setFileName(currentDirectory.getPath());
591
} else {
592
setFileName(null);
593
}
594
}
595
596
protected void doAccessoryChanged(PropertyChangeEvent e) {
597
if (getAccessoryPanel() != null) {
598
if (e.getOldValue() != null) {
599
getAccessoryPanel().remove((JComponent)e.getOldValue());
600
}
601
JComponent accessory = (JComponent)e.getNewValue();
602
if (accessory != null) {
603
getAccessoryPanel().add(accessory, BorderLayout.CENTER);
604
}
605
}
606
}
607
608
protected void doControlButtonsChanged(PropertyChangeEvent e) {
609
super.doControlButtonsChanged(e);
610
611
if (getFileChooser().getControlButtonsAreShown()) {
612
addControlButtons();
613
} else {
614
removeControlButtons();
615
}
616
}
617
618
protected void addControlButtons() {
619
if (bottomPanel != null) {
620
bottomPanel.add(buttonPanel);
621
}
622
}
623
624
protected void removeControlButtons() {
625
if (bottomPanel != null) {
626
bottomPanel.remove(buttonPanel);
627
}
628
}
629
630
631
632
633
// *******************************************************
634
// ************ FileChooser UI PLAF methods **************
635
// *******************************************************
636
637
protected ActionMap createActionMap() {
638
ActionMap map = new ActionMapUIResource();
639
// add standard actions
640
FilePane.addActionsToMap(map, filePane.getActions());
641
// add synth only actions
642
map.put("fileNameCompletion", getFileNameCompletionAction());
643
return map;
644
}
645
646
// *****************************
647
// ***** Directory Actions *****
648
// *****************************
649
650
protected JComponent getDirectoryComboBox() {
651
return directoryComboBox;
652
}
653
654
protected Action getDirectoryComboBoxAction() {
655
return directoryComboBoxAction;
656
}
657
658
protected DirectoryComboBoxRenderer createDirectoryComboBoxRenderer(JFileChooser fc) {
659
return new DirectoryComboBoxRenderer(directoryComboBox.getRenderer());
660
}
661
662
//
663
// Renderer for DirectoryComboBox
664
//
665
// Synth has some odd behavior with regards to renderers. Renderers are styled
666
// in a specific manner by the SynthComboBoxUI. If we extend DefaultListCellRenderer
667
// here, then we get none of those benefits or behaviors, leading to poor
668
// looking combo boxes.
669
// So what we do here is delegate most jobs to the "real" or original renderer,
670
// and simply monkey with the icon and text of the renderer.
671
private class DirectoryComboBoxRenderer implements ListCellRenderer<File> {
672
private ListCellRenderer<? super File> delegate;
673
IndentIcon ii = new IndentIcon();
674
675
private DirectoryComboBoxRenderer(ListCellRenderer<? super File> delegate) {
676
this.delegate = delegate;
677
}
678
679
@Override
680
public Component getListCellRendererComponent(JList<? extends File> list, File value, int index, boolean isSelected, boolean cellHasFocus) {
681
Component c = delegate.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
682
683
assert c instanceof JLabel;
684
JLabel label = (JLabel)c;
685
if (value == null) {
686
label.setText("");
687
return label;
688
}
689
label.setText(getFileChooser().getName(value));
690
Icon icon = getFileChooser().getIcon(value);
691
ii.icon = icon;
692
ii.depth = directoryComboBoxModel.getDepth(index);
693
label.setIcon(ii);
694
695
return label;
696
}
697
}
698
699
static final int space = 10;
700
class IndentIcon implements Icon {
701
702
Icon icon = null;
703
int depth = 0;
704
705
public void paintIcon(Component c, Graphics g, int x, int y) {
706
if (icon != null) {
707
if (c.getComponentOrientation().isLeftToRight()) {
708
icon.paintIcon(c, g, x+depth*space, y);
709
} else {
710
icon.paintIcon(c, g, x, y);
711
}
712
}
713
}
714
715
public int getIconWidth() {
716
return ((icon != null) ? icon.getIconWidth() : 0) + depth*space;
717
}
718
719
public int getIconHeight() {
720
return (icon != null) ? icon.getIconHeight() : 0;
721
}
722
723
}
724
725
//
726
// DataModel for DirectoryComboxbox
727
//
728
protected DirectoryComboBoxModel createDirectoryComboBoxModel(JFileChooser fc) {
729
return new DirectoryComboBoxModel();
730
}
731
732
/**
733
* Data model for a type-face selection combo-box.
734
*/
735
@SuppressWarnings("serial") // JDK-implementation class
736
protected class DirectoryComboBoxModel extends AbstractListModel<File> implements ComboBoxModel<File> {
737
Vector<File> directories = new Vector<File>();
738
int[] depths = null;
739
File selectedDirectory = null;
740
JFileChooser chooser = getFileChooser();
741
FileSystemView fsv = chooser.getFileSystemView();
742
743
public DirectoryComboBoxModel() {
744
// Add the current directory to the model, and make it the
745
// selectedDirectory
746
File dir = getFileChooser().getCurrentDirectory();
747
if (dir != null) {
748
addItem(dir);
749
}
750
}
751
752
/**
753
* Adds the directory to the model and sets it to be selected,
754
* additionally clears out the previous selected directory and
755
* the paths leading up to it, if any.
756
*/
757
public void addItem(File directory) {
758
759
if (directory == null) {
760
return;
761
}
762
763
boolean useShellFolder = FilePane.usesShellFolder(chooser);
764
765
int oldSize = directories.size();
766
directories.clear();
767
if (oldSize > 0) {
768
fireIntervalRemoved(this, 0, oldSize);
769
}
770
771
File[] baseFolders = (useShellFolder)
772
? (File[]) ShellFolder.get("fileChooserComboBoxFolders")
773
: fsv.getRoots();
774
directories.addAll(Arrays.asList(baseFolders));
775
776
// Get the canonical (full) path. This has the side
777
// benefit of removing extraneous chars from the path,
778
// for example /foo/bar/ becomes /foo/bar
779
File canonical;
780
try {
781
canonical = ShellFolder.getNormalizedFile(directory);
782
} catch (IOException e) {
783
// Maybe drive is not ready. Can't abort here.
784
canonical = directory;
785
}
786
787
// create File instances of each directory leading up to the top
788
try {
789
File sf = useShellFolder ? ShellFolder.getShellFolder(canonical)
790
: canonical;
791
File f = sf;
792
Vector<File> path = new Vector<File>(10);
793
do {
794
path.addElement(f);
795
} while ((f = f.getParentFile()) != null);
796
797
int pathCount = path.size();
798
// Insert chain at appropriate place in vector
799
for (int i = 0; i < pathCount; i++) {
800
f = path.get(i);
801
if (directories.contains(f)) {
802
int topIndex = directories.indexOf(f);
803
for (int j = i-1; j >= 0; j--) {
804
directories.insertElementAt(path.get(j), topIndex+i-j);
805
}
806
break;
807
}
808
}
809
calculateDepths();
810
setSelectedItem(sf);
811
} catch (FileNotFoundException ex) {
812
calculateDepths();
813
}
814
}
815
816
private void calculateDepths() {
817
depths = new int[directories.size()];
818
for (int i = 0; i < depths.length; i++) {
819
File dir = directories.get(i);
820
File parent = dir.getParentFile();
821
depths[i] = 0;
822
if (parent != null) {
823
for (int j = i-1; j >= 0; j--) {
824
if (parent.equals(directories.get(j))) {
825
depths[i] = depths[j] + 1;
826
break;
827
}
828
}
829
}
830
}
831
}
832
833
public int getDepth(int i) {
834
return (depths != null && i >= 0 && i < depths.length) ? depths[i] : 0;
835
}
836
837
public void setSelectedItem(Object selectedDirectory) {
838
this.selectedDirectory = (File)selectedDirectory;
839
fireContentsChanged(this, -1, -1);
840
}
841
842
public Object getSelectedItem() {
843
return selectedDirectory;
844
}
845
846
public int getSize() {
847
return directories.size();
848
}
849
850
public File getElementAt(int index) {
851
return directories.elementAt(index);
852
}
853
}
854
855
/**
856
* Acts when DirectoryComboBox has changed the selected item.
857
*/
858
@SuppressWarnings("serial") // JDK-implementation class
859
protected class DirectoryComboBoxAction extends AbstractAction {
860
protected DirectoryComboBoxAction() {
861
super("DirectoryComboBoxAction");
862
}
863
864
public void actionPerformed(ActionEvent e) {
865
directoryComboBox.hidePopup();
866
JComponent cb = getDirectoryComboBox();
867
if (cb instanceof JComboBox) {
868
File f = (File)((JComboBox)cb).getSelectedItem();
869
getFileChooser().setCurrentDirectory(f);
870
}
871
}
872
}
873
874
//
875
// Renderer for Types ComboBox
876
//
877
protected FilterComboBoxRenderer createFilterComboBoxRenderer() {
878
return new FilterComboBoxRenderer(filterComboBox.getRenderer());
879
}
880
881
/**
882
* Render different type sizes and styles.
883
*/
884
public class FilterComboBoxRenderer implements ListCellRenderer<FileFilter> {
885
private ListCellRenderer<? super FileFilter> delegate;
886
private FilterComboBoxRenderer(ListCellRenderer<? super FileFilter> delegate) {
887
this.delegate = delegate;
888
}
889
890
public Component getListCellRendererComponent(JList<? extends FileFilter> list, FileFilter value, int index,
891
boolean isSelected, boolean cellHasFocus) {
892
Component c = delegate.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
893
894
String text = null;
895
if (value != null) {
896
text = value.getDescription();
897
}
898
899
//this should always be true, since SynthComboBoxUI's SynthComboBoxRenderer
900
//extends JLabel
901
assert c instanceof JLabel;
902
if (text != null) {
903
((JLabel)c).setText(text);
904
}
905
return c;
906
}
907
}
908
909
//
910
// DataModel for Types Comboxbox
911
//
912
protected FilterComboBoxModel createFilterComboBoxModel() {
913
return new FilterComboBoxModel();
914
}
915
916
/**
917
* Data model for a type-face selection combo-box.
918
*/
919
@SuppressWarnings("serial") // JDK-implementation class
920
protected class FilterComboBoxModel extends AbstractListModel<FileFilter> implements ComboBoxModel<FileFilter>,
921
PropertyChangeListener {
922
protected FileFilter[] filters;
923
protected FilterComboBoxModel() {
924
super();
925
filters = getFileChooser().getChoosableFileFilters();
926
}
927
928
public void propertyChange(PropertyChangeEvent e) {
929
String prop = e.getPropertyName();
930
if(prop == JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) {
931
filters = (FileFilter[]) e.getNewValue();
932
fireContentsChanged(this, -1, -1);
933
} else if (prop == JFileChooser.FILE_FILTER_CHANGED_PROPERTY) {
934
fireContentsChanged(this, -1, -1);
935
}
936
}
937
938
public void setSelectedItem(Object filter) {
939
if(filter != null) {
940
getFileChooser().setFileFilter((FileFilter) filter);
941
fireContentsChanged(this, -1, -1);
942
}
943
}
944
945
public Object getSelectedItem() {
946
// Ensure that the current filter is in the list.
947
// NOTE: we shouldnt' have to do this, since JFileChooser adds
948
// the filter to the choosable filters list when the filter
949
// is set. Lets be paranoid just in case someone overrides
950
// setFileFilter in JFileChooser.
951
FileFilter currentFilter = getFileChooser().getFileFilter();
952
boolean found = false;
953
if(currentFilter != null) {
954
for (FileFilter filter : filters) {
955
if (filter == currentFilter) {
956
found = true;
957
}
958
}
959
if(found == false) {
960
getFileChooser().addChoosableFileFilter(currentFilter);
961
}
962
}
963
return getFileChooser().getFileFilter();
964
}
965
966
public int getSize() {
967
if(filters != null) {
968
return filters.length;
969
} else {
970
return 0;
971
}
972
}
973
974
public FileFilter getElementAt(int index) {
975
if(index > getSize() - 1) {
976
// This shouldn't happen. Try to recover gracefully.
977
return getFileChooser().getFileFilter();
978
}
979
if(filters != null) {
980
return filters[index];
981
} else {
982
return null;
983
}
984
}
985
}
986
987
988
989
/**
990
* <code>ButtonAreaLayout</code> behaves in a similar manner to
991
* <code>FlowLayout</code>. It lays out all components from left to
992
* right, flushed right. The widths of all components will be set
993
* to the largest preferred size width.
994
*/
995
private static class ButtonAreaLayout implements LayoutManager {
996
private int hGap = 5;
997
private int topMargin = 17;
998
999
public void addLayoutComponent(String string, Component comp) {
1000
}
1001
1002
public void layoutContainer(Container container) {
1003
Component[] children = container.getComponents();
1004
1005
if (children != null && children.length > 0) {
1006
int numChildren = children.length;
1007
Dimension[] sizes = new Dimension[numChildren];
1008
Insets insets = container.getInsets();
1009
int yLocation = insets.top + topMargin;
1010
int maxWidth = 0;
1011
1012
for (int counter = 0; counter < numChildren; counter++) {
1013
sizes[counter] = children[counter].getPreferredSize();
1014
maxWidth = Math.max(maxWidth, sizes[counter].width);
1015
}
1016
int xLocation, xOffset;
1017
if (container.getComponentOrientation().isLeftToRight()) {
1018
xLocation = container.getSize().width - insets.left - maxWidth;
1019
xOffset = hGap + maxWidth;
1020
} else {
1021
xLocation = insets.left;
1022
xOffset = -(hGap + maxWidth);
1023
}
1024
for (int counter = numChildren - 1; counter >= 0; counter--) {
1025
children[counter].setBounds(xLocation, yLocation,
1026
maxWidth, sizes[counter].height);
1027
xLocation -= xOffset;
1028
}
1029
}
1030
}
1031
1032
public Dimension minimumLayoutSize(Container c) {
1033
if (c != null) {
1034
Component[] children = c.getComponents();
1035
1036
if (children != null && children.length > 0) {
1037
int numChildren = children.length;
1038
int height = 0;
1039
Insets cInsets = c.getInsets();
1040
int extraHeight = topMargin + cInsets.top + cInsets.bottom;
1041
int extraWidth = cInsets.left + cInsets.right;
1042
int maxWidth = 0;
1043
1044
for (int counter = 0; counter < numChildren; counter++) {
1045
Dimension aSize = children[counter].getPreferredSize();
1046
height = Math.max(height, aSize.height);
1047
maxWidth = Math.max(maxWidth, aSize.width);
1048
}
1049
return new Dimension(extraWidth + numChildren * maxWidth +
1050
(numChildren - 1) * hGap,
1051
extraHeight + height);
1052
}
1053
}
1054
return new Dimension(0, 0);
1055
}
1056
1057
public Dimension preferredLayoutSize(Container c) {
1058
return minimumLayoutSize(c);
1059
}
1060
1061
public void removeLayoutComponent(Component c) { }
1062
}
1063
1064
private static void groupLabels(AlignedLabel[] group) {
1065
for (int i = 0; i < group.length; i++) {
1066
group[i].group = group;
1067
}
1068
}
1069
1070
@SuppressWarnings("serial") // JDK-implementation class
1071
private class AlignedLabel extends JLabel {
1072
private AlignedLabel[] group;
1073
private int maxWidth = 0;
1074
1075
AlignedLabel() {
1076
super();
1077
setAlignmentX(JComponent.LEFT_ALIGNMENT);
1078
}
1079
1080
AlignedLabel(String text) {
1081
super(text);
1082
setAlignmentX(JComponent.LEFT_ALIGNMENT);
1083
}
1084
1085
public Dimension getPreferredSize() {
1086
Dimension d = super.getPreferredSize();
1087
// Align the width with all other labels in group.
1088
return new Dimension(getMaxWidth() + 11, d.height);
1089
}
1090
1091
private int getMaxWidth() {
1092
if (maxWidth == 0 && group != null) {
1093
int max = 0;
1094
for (int i = 0; i < group.length; i++) {
1095
max = Math.max(group[i].getSuperPreferredWidth(), max);
1096
}
1097
for (int i = 0; i < group.length; i++) {
1098
group[i].maxWidth = max;
1099
}
1100
}
1101
return maxWidth;
1102
}
1103
1104
private int getSuperPreferredWidth() {
1105
return super.getPreferredSize().width;
1106
}
1107
}
1108
}
1109
1110