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