source: release-kits/lirk3/bin/ant-installer/src/org/tp23/gui/widget/DefaultingDirectoryChooser.java@ 14982

Last change on this file since 14982 was 14982, checked in by oranfry, 16 years ago

initial import of LiRK3

File size: 7.3 KB
Line 
1/*
2 * Copyright 2005 Paul Hinds
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.tp23.gui.widget;
17
18import java.beans.PropertyChangeEvent;
19import java.beans.PropertyChangeListener;
20import java.io.File;
21
22import javax.swing.JFileChooser;
23import javax.swing.filechooser.FileFilter;
24import javax.swing.filechooser.FileSystemView;
25/**
26 * A file chooser that makes a beter default if the default directory is not available.
27* Basically the default looks for the suggested directory and if it does not find it moves back
28* up the directories. If still nothing is found (for example it may get to My Computer
29* which you can not add file to) the home directory is selected, as in the default file chooser.
30*
31* To use this class call new DefaultingDirectoryChooser(boolean) and immediately call
32* setDefaultDirectory(File) to determine the default. If you don't it behaves like the default JFileChooser
33* Also if you call setCurrentDirectory(File) it will behave like JFileChooser
34*
35* This chooser has two modes CREATE_MODE and EXISTING_MODE. <br/><br/>
36*
37* In existing mode it is assumed the chooser is being used to identify an existing directory
38* the default directory should exist if not the directory shown will be the next existing parent.<br/><br/>
39*
40* In create mode it is
41* assumed that the last directory in the default directory is to be created and may not
42* exist yet. Therefor the default directory displayed is the parent (with suitable defaulting)
43* and the text box will contain the name of the last directory.
44* e.g. if default is C:\Program Files\MyApp C:\Program Files will be displayed and
45* MyApp will be shown in the text box (even if it does not exist yet) If C:\Program Files does not exist
46* C:\ will be shown as with existing mode.
47* Choosing select can lead to the creation of the file. It will not be automatically
48* created that is the responsibility of the client code.<br/>
49*
50* This class uses FileSystemView and will only display folders that return true to fsv.isFileSystem()
51*
52* This class also uses a bit of a hack by in CREATE_MODE it sets the selectables to files and directories
53* although only shows the directories this way a non-existing Directory can be chosen. This is the only way I can
54* get it to work on my Java version but I would not be supprised if it did not work on
55* other versions of the Java API. It also means that setFileSelectionMode() should
56* never be called by clients as it will break this hack.
57 * @author Paul Hinds
58 * @version 1.0
59 */
60public class DefaultingDirectoryChooser extends JFileChooser{
61
62 public static final boolean CREATE_MODE = true;
63 public static final boolean EXISTING_MODE = false;
64
65 /**
66 * Determines that the default includes a directory name that is requried
67 * e.g. C:\Program Files\MyApp where even if Program Files does not exist
68 * MyApp should be part of the default even if it does not exist.
69 */
70 private boolean createMode = false;
71 private File selectedFile = null;
72 private String desiredName = null;
73
74 public DefaultingDirectoryChooser(boolean createMode) {
75 this.createMode=createMode;
76 if(createMode){
77 setFileSelectionMode(FILES_AND_DIRECTORIES);
78 removeChoosableFileFilter(getAcceptAllFileFilter());
79 addChoosableFileFilter(new FileFilter(){
80 public boolean accept(File f) {
81 if(f.exists() && f.isDirectory())return true;
82 if(!f.exists() && getFileSystemView().getParentDirectory(f).isDirectory())return true;
83 return false;
84 }
85 public String getDescription() {
86 return "Directories";
87 }
88 });
89
90 addPropertyChangeListener(JFileChooser.DIRECTORY_CHANGED_PROPERTY, new PropertyChangeListener(){
91 public void propertyChange(PropertyChangeEvent evt) {
92 File directory = (File)evt.getNewValue();
93 DefaultingDirectoryChooser.this.setCurrentDirectory(new File(directory, "newfolder"));
94 setSelectedFile(new File(directory, desiredName));
95 }
96 });
97 }
98 else {
99 setFileSelectionMode(DIRECTORIES_ONLY);
100 }
101 }
102
103
104 /**
105 * Sets the default directory.
106 * @param dir the current directory to point to
107 * @todo Implement this javax.swing.JFileChooser method
108 */
109 public void setDefaultDirectory(File dir) {
110 if(dir==null)return;// called by the default consructor
111 if(createMode){
112 if(desiredName == null)desiredName = dir.getName();
113 File selected = determineCreateDir(dir);
114 super.setCurrentDirectory(selected.getParentFile());
115 setSelectedFile(selected);
116 }else{
117 super.setCurrentDirectory(determineExistingDir(dir));
118 }
119 }
120
121
122
123 private File determineExistingDir(File defaultDir){
124 if(defaultDir.exists())return defaultDir;
125 FileSystemView fsv = this.getFileSystemView();
126 File validParent = getFSVParent(fsv,defaultDir);
127 if(validParent!=null) {
128 return validParent;
129 }
130 else {
131 return fsv.getHomeDirectory();
132 }
133 }
134 /**
135 * Select a base path for the default even if it does not exist. The order of preference is as follows
136 * if the directory exists use it
137 * if the parent does not exist try finding the next parent
138 * if the next parent is a root directory e.g. / or C:\ use the users home directory
139 * @param defaultDir File
140 * @return File
141 */
142 private File determineCreateDir(File defaultDir){
143 if(defaultDir.exists())return defaultDir;
144 FileSystemView fsv = this.getFileSystemView();
145 String dirName = defaultDir.getName();
146 File validParent = getFSVParent(fsv,defaultDir);
147 if(validParent!=null){
148 return new File(validParent, dirName);
149 }
150 else {
151 return new File(fsv.getHomeDirectory(), dirName);
152 }
153 }
154 /**
155 * Step back up trying to find a parent if none if found return null.
156 * null can be found if the path starts e:\ and e: does not exist
157 * @param fsv FileSystemView
158 * @param dir File
159 * @return File
160 */
161 private File getFSVParent(FileSystemView fsv,File dir){
162 File parent = dir.getParentFile();
163 if(fsv.isRoot(parent) && !parent.exists()){
164 return null;
165 }
166 if(!parent.exists() || !fsv.isFileSystem(parent)){
167 parent = getFSVParent(fsv,parent);
168 }
169 return parent;
170 }
171
172 public static void main(String[] args) {
173 DefaultingDirectoryChooser chooser = new DefaultingDirectoryChooser(CREATE_MODE);
174 chooser.setDefaultDirectory(new File("/usr/local/dibble/MyApp"));
175
176 chooser.showDialog(null,"Select");
177 System.out.println("Selected:"+chooser.getSelectedFile().getAbsolutePath());
178 System.exit(0);
179 }
180}
Note: See TracBrowser for help on using the repository browser.