001 /*
002 * Copyright (c) 1998-2009, The University of Sheffield.
003 * Copyright (c) 2009-2009, Ontotext, Bulgaria.
004 *
005 * This file is part of GATE (see http://gate.ac.uk/), and is free
006 * software, licenced under the GNU Library General Public License,
007 * Version 2, June 1991 (in the distribution as file licence.html,
008 * and also available at http://gate.ac.uk/gate/licence.html).
009 *
010 * Thomas Heitz - 15/09/2009
011 *
012 * $Id:$
013 *
014 */
015
016 package gate.swing;
017
018 import gate.gui.MainFrame;
019 import gate.Gate;
020
021 import javax.swing.JFileChooser;
022 import javax.swing.event.AncestorListener;
023 import javax.swing.event.AncestorEvent;
024 import javax.swing.filechooser.FileFilter;
025 import java.awt.Component;
026 import java.awt.HeadlessException;
027 import java.io.File;
028 import java.io.IOException;
029 import java.util.Map;
030
031 /**
032 * Extends {@link javax.swing.JFileChooser} to make sure the shared
033 * {@link MainFrame} instance is used as a parent when no parent is specified.
034 * <br><br>
035 * Remember the last path used for each resource type.
036 * The path is saved when the user confirm the dialog.
037 * The resource name must be set with the method {@link #setResource(String)}.
038 * Use {@link #setSelectedFile(java.io.File)} to preselect a different file
039 * or use {@link #setFileName(String)} to use a different file name but the
040 * saved directory.
041 * <br><br>
042 * Resource paths are saved in the user config file.
043 */
044 public class XJFileChooser extends JFileChooser {
045 /** key used when saving the file location to be retrieved later */
046 private String resource;
047 /** file name used instead of the one saved in the preferences */
048 private String fileName;
049 /** set to true when setSelectedFile has been used */
050 private boolean isFileSelected = false;
051 /** map for (resource name -> path) saved in the user config file */
052 private Map<String, String> locations;
053
054 public XJFileChooser() {
055 addAncestorListener(new AncestorListener() {
056 public void ancestorAdded(AncestorEvent event) { /* do nothing */ }
057 public void ancestorRemoved(AncestorEvent event) {
058 // reinitialise fields when the file chooser is hidden
059 resource = null;
060 fileName = null;
061 isFileSelected = false;
062 resetChoosableFileFilters();
063 }
064 public void ancestorMoved(AncestorEvent event) { /* do nothing */ }
065 });
066 }
067
068 /**
069 * Overridden to make sure the shared MainFrame instance is used as
070 * a parent when no parent is specified
071 */
072 public int showDialog(Component parent, String approveButtonText)
073 throws HeadlessException {
074 setSelectedFileFromPreferences();
075 return super.showDialog((parent != null) ? parent :
076 (MainFrame.getFileChooser() != null) ? MainFrame.getInstance() :
077 null, approveButtonText);
078 }
079
080 /**
081 * If possible, select the last directory/file used for the resource
082 * otherwise use the last file chooser selection directory or if null
083 * use the user home directory.
084 */
085 public void setSelectedFileFromPreferences() {
086 String lastUsedPath = getLocationForResource(resource);
087 File file;
088 String specifiedDefaultDir =
089 System.getProperty("gate.user.filechooser.defaultdir");
090 if (isFileSelected) {
091 // a file has already been selected so do not use the saved one
092 return;
093 } else if (lastUsedPath != null && fileName != null) {
094 file = new File(lastUsedPath);
095 if (!file.isDirectory()) {
096 file = file.getParentFile();
097 }
098 file = new File(file, fileName);
099 } else if (lastUsedPath != null) {
100 file = new File(lastUsedPath);
101 } else if (fileName != null) {
102 // if the property for setting a default directory has been set,
103 // use that for finding the file, otherwise use whatever the
104 // user home directory is on this operating system.
105 if(specifiedDefaultDir != null) {
106 file = new File(specifiedDefaultDir, fileName);
107 } else {
108 file = new File(System.getProperty("user.home"), fileName);
109 }
110 } else {
111 // if the property for setting a default directory has been set,
112 // let the filechooser know, otherwise just do whatever the
113 // default behavior is.
114 if(specifiedDefaultDir != null) {
115 this.setCurrentDirectory(new File(specifiedDefaultDir));
116 }
117 return;
118 }
119 setSelectedFile(file);
120 ensureFileIsVisible(file);
121 }
122
123 public String getLocationForResource(String resource) {
124 locations = getLocations();
125 return (resource == null) ? null : locations.get(resource);
126 }
127
128 /**
129 * Useful to modify the locations used by this file chooser.
130 * @return a map of resource (name * file location)
131 * @see #setLocations(java.util.Map)
132 */
133 public Map<String, String> getLocations() {
134 return Gate.getUserConfig().getMap(XJFileChooser.class.getName());
135 }
136
137 /**
138 * Useful to modify the locations used by this file chooser.
139 * @param locations a map of (resource name * file location)
140 * @see #getLocations()
141 */
142 public void setLocations(Map<String, String> locations) {
143 Gate.getUserConfig().put(XJFileChooser.class.getName(), locations);
144 }
145
146 /**
147 * Set the file name to be used instead of the one saved in the preferences.
148 * @param fileName file name
149 */
150 public void setFileName(String fileName) {
151 this.fileName = fileName;
152 }
153
154 /** overriden to first save the location of the file chooser
155 * for the current resource. */
156 public void approveSelection() {
157 if (resource != null && getSelectedFile() != null) {
158 try {
159 String filePath = getSelectedFile().getCanonicalPath();
160 locations.put(resource, filePath);
161 setLocations(locations);
162 } catch (IOException e) {
163 e.printStackTrace();
164 }
165 }
166 super.approveSelection();
167 }
168
169 /**
170 * Set the resource to remember the path. Must be set before to call
171 * {@link #showDialog}.
172 * @param resource name of the resource
173 */
174 public void setResource(String resource) {
175 this.resource = resource;
176 }
177
178 /**
179 * Get the resource associated to this file chooser.
180 * @return name of the resource
181 */
182 public String getResource() {
183 return resource;
184 }
185
186 /** Overriden to test first if the file exists */
187 public void ensureFileIsVisible(File f) {
188 if(f != null && f.exists()) super.ensureFileIsVisible(f);
189 }
190
191 /** Overriden to test first if the file exists */
192 public void setSelectedFile(File file) {
193 if(file != null){
194 if(file.exists() ||
195 (file.getParentFile() != null && file.getParentFile().exists())){
196 super.setSelectedFile(file);
197 }
198 isFileSelected = true;
199 }
200 }
201
202 /** overriden to add a filter only if not already present */
203 public void addChoosableFileFilter(FileFilter filterToAdd) {
204 for (FileFilter filter : getChoosableFileFilters()) {
205 if (filter.getDescription().equals(filterToAdd.getDescription())) {
206 setFileFilter(filter);
207 return;
208 }
209 }
210 super.addChoosableFileFilter(filterToAdd);
211 }
212 }
|