source: josm/trunk/src/org/openstreetmap/josm/gui/widgets/FileChooserManager.java@ 9134

Last change on this file since 9134 was 8540, checked in by Don-vip, 9 years ago

fix remaining checkstyle issues

  • Property svn:eol-style set to native
File size: 11.1 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.widgets;
3
4import java.awt.Component;
5import java.io.File;
6import java.util.Collection;
7import java.util.Collections;
8
9import javax.swing.JFileChooser;
10import javax.swing.filechooser.FileFilter;
11
12import org.openstreetmap.josm.Main;
13import org.openstreetmap.josm.actions.DiskAccessAction;
14import org.openstreetmap.josm.actions.ExtensionFileFilter;
15import org.openstreetmap.josm.actions.SaveActionBase;
16import org.openstreetmap.josm.data.preferences.BooleanProperty;
17
18/**
19 * A chained utility class used to create and open {@link AbstractFileChooser} dialogs.<br>
20 * Use only this class if you need to control specifically your AbstractFileChooser dialog.<br>
21 * <p>
22 * A simpler usage is to call the {@link DiskAccessAction#createAndOpenFileChooser} methods.
23 *
24 * @since 5438 (creation)
25 * @since 7578 (rename)
26 */
27public class FileChooserManager {
28
29 /**
30 * Property to enable use of native file dialogs.
31 */
32 public static final BooleanProperty PROP_USE_NATIVE_FILE_DIALOG = new BooleanProperty("use.native.file.dialog",
33 // Native dialogs do not support file filters, so do not set them as default, except for OS X where they never worked
34 Main.isPlatformOsx());
35
36 private final boolean open;
37 private final String lastDirProperty;
38 private final String curDir;
39
40 private AbstractFileChooser fc;
41
42 /**
43 * Creates a new {@code FileChooserManager}.
44 * @param open If true, "Open File" dialogs will be created. If false, "Save File" dialogs will be created.
45 * @see #createFileChooser
46 */
47 public FileChooserManager(boolean open) {
48 this(open, null);
49 }
50
51 // CHECKSTYLE.OFF: LineLength
52
53 /**
54 * Creates a new {@code FileChooserManager}.
55 * @param open If true, "Open File" dialogs will be created. If false, "Save File" dialogs will be created.
56 * @param lastDirProperty The name of the property used to get the last directory. This directory is used to initialize the AbstractFileChooser.
57 * Then, if the user effectively chooses a file or a directory, this property will be updated to the directory path.
58 * @see #createFileChooser
59 */
60 public FileChooserManager(boolean open, String lastDirProperty) {
61 this(open, lastDirProperty, null);
62 }
63
64 /**
65 * Creates a new {@code FileChooserManager}.
66 * @param open If true, "Open File" dialogs will be created. If false, "Save File" dialogs will be created.
67 * @param lastDirProperty The name of the property used to get the last directory. This directory is used to initialize the AbstractFileChooser.
68 * Then, if the user effectively chooses a file or a directory, this property will be updated to the directory path.
69 * @param defaultDir The default directory used to initialize the AbstractFileChooser if the {@code lastDirProperty} property value is missing.
70 * @see #createFileChooser
71 */
72 public FileChooserManager(boolean open, String lastDirProperty, String defaultDir) {
73 this.open = open;
74 this.lastDirProperty = lastDirProperty == null || lastDirProperty.isEmpty() ? "lastDirectory" : lastDirProperty;
75 this.curDir = Main.pref.get(this.lastDirProperty).isEmpty() ?
76 defaultDir == null || defaultDir.isEmpty() ? "." : defaultDir
77 : Main.pref.get(this.lastDirProperty);
78 }
79
80 // CHECKSTYLE.ON: LineLength
81
82 /**
83 * Replies the {@code AbstractFileChooser} that has been previously created.
84 * @return The {@code AbstractFileChooser} that has been previously created, or {@code null} if it has not been created yet.
85 * @see #createFileChooser
86 */
87 public final AbstractFileChooser getFileChooser() {
88 return fc;
89 }
90
91 /**
92 * Replies the initial directory used to construct the {@code AbstractFileChooser}.
93 * @return The initial directory used to construct the {@code AbstractFileChooser}.
94 */
95 public final String getInitialDirectory() {
96 return curDir;
97 }
98
99 /**
100 * Creates a new {@link AbstractFileChooser} with default settings. All files will be accepted.
101 * @return this
102 */
103 public final FileChooserManager createFileChooser() {
104 return doCreateFileChooser(false, null, null, null, null, JFileChooser.FILES_ONLY, false);
105 }
106
107 /**
108 * Creates a new {@link AbstractFileChooser} with given settings for a single {@code FileFilter}.
109 *
110 * @param multiple If true, makes the dialog allow multiple file selections
111 * @param title The string that goes in the dialog window's title bar
112 * @param filter The only file filter that will be proposed by the dialog
113 * @param selectionMode The selection mode that allows the user to:<br><ul>
114 * <li>just select files ({@code JFileChooser.FILES_ONLY})</li>
115 * <li>just select directories ({@code JFileChooser.DIRECTORIES_ONLY})</li>
116 * <li>select both files and directories ({@code JFileChooser.FILES_AND_DIRECTORIES})</li></ul>
117 * @return this
118 * @see DiskAccessAction#createAndOpenFileChooser(boolean, boolean, String, FileFilter, int, String)
119 */
120 public final FileChooserManager createFileChooser(boolean multiple, String title, FileFilter filter, int selectionMode) {
121 doCreateFileChooser(multiple, title, Collections.singleton(filter), filter, null, selectionMode, false);
122 getFileChooser().setAcceptAllFileFilterUsed(false);
123 return this;
124 }
125
126 /**
127 * Creates a new {@link AbstractFileChooser} with given settings for a collection of {@code FileFilter}s.
128 *
129 * @param multiple If true, makes the dialog allow multiple file selections
130 * @param title The string that goes in the dialog window's title bar
131 * @param filters The file filters that will be proposed by the dialog
132 * @param defaultFilter The file filter that will be selected by default
133 * @param selectionMode The selection mode that allows the user to:<br><ul>
134 * <li>just select files ({@code JFileChooser.FILES_ONLY})</li>
135 * <li>just select directories ({@code JFileChooser.DIRECTORIES_ONLY})</li>
136 * <li>select both files and directories ({@code JFileChooser.FILES_AND_DIRECTORIES})</li></ul>
137 * @return this
138 * @see DiskAccessAction#createAndOpenFileChooser(boolean, boolean, String, Collection, FileFilter, int, String)
139 */
140 public final FileChooserManager createFileChooser(boolean multiple, String title, Collection<? extends FileFilter> filters,
141 FileFilter defaultFilter, int selectionMode) {
142 return doCreateFileChooser(multiple, title, filters, defaultFilter, null, selectionMode, false);
143 }
144
145 /**
146 * Creates a new {@link AbstractFileChooser} with given settings for a file extension.
147 *
148 * @param multiple If true, makes the dialog allow multiple file selections
149 * @param title The string that goes in the dialog window's title bar
150 * @param extension The file extension that will be selected as the default file filter
151 * @param allTypes If true, all the files types known by JOSM will be proposed in the "file type" combobox.
152 * If false, only the file filters that include {@code extension} will be proposed
153 * @param selectionMode The selection mode that allows the user to:<br><ul>
154 * <li>just select files ({@code JFileChooser.FILES_ONLY})</li>
155 * <li>just select directories ({@code JFileChooser.DIRECTORIES_ONLY})</li>
156 * <li>select both files and directories ({@code JFileChooser.FILES_AND_DIRECTORIES})</li></ul>
157 * @return this
158 * @see DiskAccessAction#createAndOpenFileChooser(boolean, boolean, String, FileFilter, int, String)
159 */
160 public final FileChooserManager createFileChooser(boolean multiple, String title, String extension, boolean allTypes, int selectionMode) {
161 return doCreateFileChooser(multiple, title, null, null, extension, selectionMode, allTypes);
162 }
163
164 private FileChooserManager doCreateFileChooser(boolean multiple, String title, Collection<? extends FileFilter> filters,
165 FileFilter defaultFilter, String extension, int selectionMode, boolean allTypes) {
166 File file = new File(curDir);
167 // Use native dialog is preference is set, unless an unsupported selection mode is specifically wanted
168 if (PROP_USE_NATIVE_FILE_DIALOG.get() && NativeFileChooser.supportsSelectionMode(selectionMode)) {
169 fc = new NativeFileChooser(file);
170 } else {
171 fc = new SwingFileChooser(file);
172 }
173
174 if (title != null) {
175 fc.setDialogTitle(title);
176 }
177
178 fc.setFileSelectionMode(selectionMode);
179 fc.setMultiSelectionEnabled(multiple);
180 fc.setAcceptAllFileFilterUsed(false);
181
182 if (filters != null) {
183 for (FileFilter filter : filters) {
184 fc.addChoosableFileFilter(filter);
185 }
186 if (defaultFilter != null) {
187 fc.setFileFilter(defaultFilter);
188 }
189 } else if (open) {
190 ExtensionFileFilter.applyChoosableImportFileFilters(fc, extension, allTypes);
191 } else {
192 ExtensionFileFilter.applyChoosableExportFileFilters(fc, extension, allTypes);
193 }
194 return this;
195 }
196
197 /**
198 * Opens the {@code AbstractFileChooser} that has been created. Nothing happens if it has not been created yet.
199 * @return the {@code AbstractFileChooser} if the user effectively choses a file or directory. {@code null} if the user cancelled the dialog.
200 */
201 public final AbstractFileChooser openFileChooser() {
202 return openFileChooser(null);
203 }
204
205 /**
206 * Opens the {@code AbstractFileChooser} that has been created and waits for the user to choose a file/directory, or cancel the dialog.<br>
207 * Nothing happens if the dialog has not been created yet.<br>
208 * When the user choses a file or directory, the {@code lastDirProperty} is updated to the chosen directory path.
209 *
210 * @param parent The Component used as the parent of the AbstractFileChooser. If null, uses {@code Main.parent}.
211 * @return the {@code AbstractFileChooser} if the user effectively choses a file or directory. {@code null} if the user cancelled the dialog.
212 */
213 public AbstractFileChooser openFileChooser(Component parent) {
214 if (fc != null) {
215 if (parent == null) {
216 parent = Main.parent;
217 }
218
219 int answer = open ? fc.showOpenDialog(parent) : fc.showSaveDialog(parent);
220 if (answer != JFileChooser.APPROVE_OPTION) {
221 return null;
222 }
223
224 if (!fc.getCurrentDirectory().getAbsolutePath().equals(curDir)) {
225 Main.pref.put(lastDirProperty, fc.getCurrentDirectory().getAbsolutePath());
226 }
227
228 if (!open) {
229 File file = fc.getSelectedFile();
230 if (!SaveActionBase.confirmOverwrite(file)) {
231 return null;
232 }
233 }
234 }
235 return fc;
236 }
237}
Note: See TracBrowser for help on using the repository browser.