001 /*
002 * Copyright (c) 2005 Einar Pehrson <einar@pehrson.nu>.
003 *
004 * This file is part of
005 * CleanSheets - a spreadsheet application for the Java platform.
006 *
007 * CleanSheets is free software; you can redistribute it and/or modify
008 * it under the terms of the GNU General Public License as published by
009 * the Free Software Foundation; either version 2 of the License, or
010 * (at your option) any later version.
011 *
012 * CleanSheets is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015 * GNU General Public License for more details.
016 *
017 * You should have received a copy of the GNU General Public License
018 * along with CleanSheets; if not, write to the Free Software
019 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020 */
021 package csheets.ui;
022
023 import java.awt.Component;
024 import java.io.File;
025 import java.io.FilenameFilter;
026 import java.util.ArrayList;
027 import java.util.List;
028 import java.util.Properties;
029
030 import javax.swing.JFileChooser;
031 import javax.swing.filechooser.FileFilter;
032
033 import csheets.SpreadsheetAppEvent;
034 import csheets.SpreadsheetAppListener;
035 import csheets.io.FilenameExtensionFilter;
036
037 /**
038 * A file chooser that loads choosable file types from properties.
039 * @author Einar Pehrson
040 */
041 @SuppressWarnings("serial")
042 public class FileChooser extends JFileChooser implements SpreadsheetAppListener {
043
044 /** The parent component of dialogs created by the chooser */
045 private Component parent;
046
047 /** The file filters used by the chooser */
048 private List<Filter> filters = new ArrayList<Filter>();
049
050 /**
051 * Creates a new file chooser. Choosable file types are loaded from the
052 * given properties.
053 * Dialogs are shown with the given component as parent.
054 * @param parent the parent component of dialogs
055 * @param props the user properties
056 */
057 public FileChooser(Component parent, Properties props) {
058 // Stores members
059 this.parent = parent;
060
061 // Configures chooser
062 setAcceptAllFileFilterUsed(false);
063
064 if (props != null) {
065 // Loads file types
066 String extension, description;
067 for (int i = 0;
068 (extension = props.getProperty("filetype" + i + ".extension")) != null
069 && (description = props.getProperty("filetype" + i + ".description")) != null;
070 i++) {
071 addChoosableFileFilter(new Filter(
072 new FilenameExtensionFilter(extension), description));
073 }
074 if (filters.size() > 0)
075 setFileFilter(filters.get(0));
076
077 // Loads current directory
078 String currentDir = props.getProperty("recentfile0");
079 if (currentDir != null)
080 setCurrentDirectory(new File(currentDir));
081 }
082 }
083
084 /**
085 * Shows a file chooser and returns the file the user selected, if any.
086 */
087 public File getFileToOpen() {
088 if (showOpenDialog(parent) == JFileChooser.APPROVE_OPTION)
089 return getChosenFile();
090 else
091 return null;
092 }
093
094 /**
095 * Shows a file chooser and returns the file the user selected, if any.
096 */
097 public File getFileToSave() {
098 if (showSaveDialog(parent) == JFileChooser.APPROVE_OPTION)
099 return getChosenFile();
100 else
101 return null;
102 }
103
104 /**
105 * Shows a file chooser and returns the file the user selected, if any.
106 */
107 private File getChosenFile() {
108 File file = getSelectedFile();
109 String filename = file.getName();
110 if (filename.lastIndexOf('.') != -1) {
111 // Checks if the file is acceptable by any of the filters.
112 boolean filterAcceptable = filters.isEmpty();
113 for (Filter filter : filters)
114 if (filter.getFilter().accept(file, filename)) {
115 filterAcceptable = true;
116 break;
117 }
118 return file.isDirectory() || filterAcceptable ? file : null;
119 } else {
120 // Appends default extension from the chosen filter
121 FileFilter filter = getFileFilter();
122 if (filter instanceof Filter) {
123 FilenameFilter filenameFilter = ((Filter)filter).getFilter();
124 if (filenameFilter instanceof FilenameExtensionFilter) {
125 String[] extensions = ((FilenameExtensionFilter)
126 filenameFilter).getExtensions();
127 return new File(file.getAbsolutePath() + "." + extensions[0]);
128 }
129 }
130 return null;
131 }
132 }
133
134 public void addChoosableFileFilter(FileFilter filter) {
135 super.addChoosableFileFilter(filter);
136 if (filter instanceof Filter) filters.add((Filter)filter);
137 }
138
139 public void workbookCreated(SpreadsheetAppEvent event) {}
140
141 public void workbookLoaded(SpreadsheetAppEvent event) {
142 setCurrentDirectory(event.getFile());
143 }
144
145 public void workbookUnloaded(SpreadsheetAppEvent event) {}
146
147 public void workbookSaved(SpreadsheetAppEvent event) {
148 setCurrentDirectory(event.getFile());
149 }
150
151 /**
152 * A file filter for use in file choosers.
153 * @author Einar Pehrson
154 */
155 public static class Filter extends FileFilter {
156
157 /** The filename filter used to determine which files to accept. */
158 private FilenameFilter filter;
159
160 /** The description of the filter. */
161 private String description;
162
163 /**
164 * Creates a new filter, using the given filename filter to determine which
165 * files to accept.
166 * @param filter the filename filter used to determine which files to accept
167 * @param description the description of the filter
168 */
169 public Filter(FilenameFilter filter, String description) {
170 this.filter = filter;
171 this.description = description;
172 }
173
174 public boolean accept(File f) {
175 return f != null && (f.isDirectory() || filter.accept(f, f.getName()));
176 }
177
178 /**
179 * Returns the filename filter used to determine which files to accept.
180 * @return the filename filter
181 */
182 public FilenameFilter getFilter() {
183 return filter;
184 }
185
186 /**
187 * Returns the description of the filter
188 * @return the description of the filter
189 */
190 public String getDescription() {
191 return description;
192 }
193 }
194 }