source: josm/trunk/src/org/openstreetmap/josm/gui/widgets/NativeFileChooser.java@ 7578

Last change on this file since 7578 was 7578, checked in by Don-vip, 10 years ago

fix #10024 - Add an option in Preferences/Look-and-Feel to use native file-choosing dialogs.
They look nicer but they do not support file filters, so we cannot use them (yet) as default.
Based on patch by Lesath and code review by simon04.
The native dialogs are not used if selection mode is not supported ("files and directories" on all platforms, "directories" on systems other than OS X)

File size: 6.6 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.widgets;
3
4import java.awt.Component;
5import java.awt.FileDialog;
6import java.awt.Frame;
7import java.io.File;
8import java.io.FilenameFilter;
9
10import javax.swing.JFileChooser;
11import javax.swing.filechooser.FileFilter;
12
13import org.openstreetmap.josm.Main;
14
15/**
16 * File chooser based on the AWT's {@link FileDialog} implementation,
17 * which looks like more a native file chooser than the Swing implementation.
18 * @since 7578
19 */
20public class NativeFileChooser extends AbstractFileChooser {
21
22 /** The instance of the fileDialog */
23 private final FileDialog fileDialog;
24 private FileFilter fileFilter;
25 private int selectionMode;
26
27 /**
28 * Constructs a new {@code NativeFileChooser}.
29 * @param file the current file/directory to point to
30 */
31 public NativeFileChooser(File file) {
32 fileDialog = new FileDialog((Frame) Main.parent);
33 if (file != null) {
34 fileDialog.setDirectory(file.getAbsolutePath());
35 fileDialog.setFile(file.toString());
36 }
37 }
38
39 @Override
40 public void addChoosableFileFilter(FileFilter filter) {
41 // TODO implement this after Oracle fixes JDK-4811090 / JDK-6192906
42 // https://bugs.openjdk.java.net/browse/JDK-4811090 : Extend awt filedialog
43 // https://bugs.openjdk.java.net/browse/JDK-6192906 : Add more features to java.awt.FileDialog
44 }
45
46 @Override
47 public FileFilter[] getChoosableFileFilters() {
48 // TODO implement this after Oracle fixes JDK-4811090 / JDK-6192906
49 // https://bugs.openjdk.java.net/browse/JDK-4811090 : Extend awt filedialog
50 // https://bugs.openjdk.java.net/browse/JDK-6192906 : Add more features to java.awt.FileDialog
51 return new FileFilter[]{};
52 }
53
54 @Override
55 public File getCurrentDirectory() {
56 return new File(fileDialog.getDirectory());
57 }
58
59 @Override
60 public FileFilter getFileFilter() {
61 return fileFilter;
62 }
63
64 @Override
65 public File getSelectedFile() {
66 return new File(fileDialog.getDirectory() + fileDialog.getFile());
67 }
68
69 @Override
70 public File[] getSelectedFiles() {
71 return fileDialog.getFiles();
72 }
73
74 @Override
75 public boolean isMultiSelectionEnabled() {
76 return fileDialog.isMultipleMode();
77 }
78
79 @Override
80 public void setAcceptAllFileFilterUsed(boolean b) {
81 // TODO implement this after Oracle fixes JDK-4811090 / JDK-6192906
82 // https://bugs.openjdk.java.net/browse/JDK-4811090 : Extend awt filedialog
83 // https://bugs.openjdk.java.net/browse/JDK-6192906 : Add more features to java.awt.FileDialog
84 }
85
86 @Override
87 public void setCurrentDirectory(File f) {
88 fileDialog.setDirectory(f.toString());
89 }
90
91 @Override
92 public void setDialogTitle(String title) {
93 fileDialog.setTitle(title);
94 }
95
96 @Override
97 public void setFileFilter(final FileFilter cff) {
98 FilenameFilter filter = new FilenameFilter() {
99 public boolean accept(File Directory, String fileName) {
100 return cff.accept(new File(Directory.getAbsolutePath() + fileName));
101 }
102 };
103 fileDialog.setFilenameFilter(filter);
104 fileFilter = cff;
105 }
106
107 @Override
108 public void setFileSelectionMode(int selectionMode) {
109 // TODO implement this after Oracle fixes JDK-6192906 / JDK-6699863 / JDK-6927978 / JDK-7125172:
110 // https://bugs.openjdk.java.net/browse/JDK-6192906 : Add more features to java.awt.FileDialog
111 // https://bugs.openjdk.java.net/browse/JDK-6699863 : awt filedialog cannot select directories
112 // https://bugs.openjdk.java.net/browse/JDK-6927978 : Directory Selection standard dialog support
113 // https://bugs.openjdk.java.net/browse/JDK-7125172 : FileDialog objects don't allow directory AND files selection simultaneously
114
115 // There is however a basic support for directory selection on OS X, with Java >= 7u40:
116 // http://stackoverflow.com/questions/1224714/how-can-i-make-a-java-filedialog-accept-directories-as-its-filetype-in-os-x/1224744#1224744
117 // https://bugs.openjdk.java.net/browse/JDK-7161437 : [macosx] awt.FileDialog doesn't respond appropriately for mac when selecting folders
118 this.selectionMode = selectionMode;
119 }
120
121 @Override
122 public void setMultiSelectionEnabled(boolean multiple) {
123 fileDialog.setMultipleMode(multiple);
124 }
125
126 @Override
127 public void setSelectedFile(File file) {
128 fileDialog.setDirectory(file.getAbsolutePath());
129 fileDialog.setFile(file.getName());
130 }
131
132 @Override
133 public int showOpenDialog(Component parent) {
134 boolean appleProperty = Main.isPlatformOsx() && selectionMode == JFileChooser.DIRECTORIES_ONLY;
135 if (appleProperty) {
136 System.setProperty("apple.awt.fileDialogForDirectories", "true");
137 }
138 try {
139 fileDialog.setLocale(locale);
140 fileDialog.setMode(FileDialog.LOAD);
141 fileDialog.setVisible(true);
142 return fileDialog.getFile() == null ? JFileChooser.CANCEL_OPTION : JFileChooser.APPROVE_OPTION;
143 } finally {
144 if (appleProperty) {
145 System.setProperty("apple.awt.fileDialogForDirectories", "false");
146 }
147 }
148 }
149
150 @Override
151 public int showSaveDialog(Component parent) {
152 fileDialog.setLocale(locale);
153 fileDialog.setMode(FileDialog.SAVE);
154 fileDialog.setVisible(true);
155 return fileDialog.getFile() == null ? JFileChooser.CANCEL_OPTION : JFileChooser.APPROVE_OPTION;
156 }
157
158 /**
159 * Determines if the selection mode is suuported by the native file chooser.
160 * @param selectionMode the selection mode
161 * @return {@code true} if the selection mode is supported, {@code false} otherwise
162 */
163 public static boolean supportsSelectionMode(int selectionMode) {
164 switch (selectionMode) {
165 case JFileChooser.FILES_AND_DIRECTORIES:
166 // https://bugs.openjdk.java.net/browse/JDK-7125172 : FileDialog objects don't allow directory AND files selection simultaneously
167 return false;
168 case JFileChooser.DIRECTORIES_ONLY:
169 // http://stackoverflow.com/questions/1224714/how-can-i-make-a-java-filedialog-accept-directories-as-its-filetype-in-os-x/1224744#1224744
170 return Main.isPlatformOsx();
171 case JFileChooser.FILES_ONLY:
172 default:
173 return true;
174 }
175 }
176}
Note: See TracBrowser for help on using the repository browser.