001: /*
002: * Copyright (c) 2000, Jacob Smullyan.
003: *
004: * This is part of SkunkDAV, a WebDAV client. See http://skunkdav.sourceforge.net/
005: * for the latest version.
006: *
007: * SkunkDAV is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License as published
009: * by the Free Software Foundation; either version 2, or (at your option)
010: * any later version.
011: *
012: * SkunkDAV 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 GNU
015: * General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with SkunkDAV; see the file COPYING. If not, write to the Free
019: * Software Foundation, 59 Temple Place - Suite 330, Boston, MA
020: * 02111-1307, USA.
021: */
022:
023: package org.skunk.swing.filechooser;
024:
025: import java.awt.Component;
026: import java.io.File;
027: import java.util.Arrays;
028: import java.util.Enumeration;
029: import java.util.Vector;
030: import javax.swing.DefaultListCellRenderer;
031: import javax.swing.JList;
032: import javax.swing.JOptionPane;
033: import javax.swing.tree.DefaultMutableTreeNode;
034: import javax.swing.tree.DefaultTreeModel;
035: import javax.swing.tree.TreeNode;
036: import org.skunk.swing.TreeNodeChooser;
037:
038: /**
039: * a file chooser similar to GTK+'s GtkFileSelection widget
040: */
041: public class LocalFileChooser extends TreeNodeChooser {
042: /**
043: * constructor with a specified file root.
044: * @param fileRoot the root of the desired portion of the file system
045: */
046: public LocalFileChooser(String fileRoot) {
047: super (new DefaultTreeModel(new FileNode(new File(fileRoot))));
048: setComboBoxCellRenderer(new FileComboRenderer());
049: }
050:
051: /**
052: * constructor with the system file roots.
053: */
054: public LocalFileChooser() {
055: super (new DefaultTreeModel(FileNode.getRootNode()));
056: if (FileNode.listRoots().length > 1)
057: setRootVisible(false);
058: setComboBoxCellRenderer(new FileComboRenderer());
059: }
060:
061: /**
062: * a test of the file chooser, for development purposes.
063: */
064: public static class Test {
065: TreeNodeChooser chooser;
066:
067: public Test(String fileRoot) {
068: initModel(fileRoot);
069: }
070:
071: private void initModel(String fileRoot) {
072: if (fileRoot != null)
073: chooser = new LocalFileChooser(fileRoot);
074: else
075: chooser = new LocalFileChooser();
076: }
077:
078: public void showDialog() {
079: int option = JOptionPane.showConfirmDialog(null, chooser,
080: "choose a file", JOptionPane.OK_CANCEL_OPTION,
081: JOptionPane.QUESTION_MESSAGE, null);
082: if (option == JOptionPane.OK_OPTION) {
083: System.out.println(chooser.getEntryFieldText());
084: } else
085: System.out.println("CANCELLED");
086: }
087:
088: public static void main(String[] args) {
089: //parse args
090: String initialPath = null;
091: SelectionMode mode = null;
092: if (args.length >= 1)
093: initialPath = args[0];
094:
095: if (args.length >= 2) {
096: if (args[1].equalsIgnoreCase("branch"))
097: mode = SelectionMode.BRANCH_ONLY;
098: else if (args[1].equalsIgnoreCase("leaf"))
099: mode = SelectionMode.LEAF_ONLY;
100: else if (args[1].equalsIgnoreCase("both"))
101: mode = SelectionMode.LEAF_AND_BRANCH;
102: }
103: Test test = new Test(initialPath);
104:
105: if (mode != null)
106: test.chooser.setSelectionMode(mode);
107:
108: test.showDialog();
109: System.exit(0);
110: }
111: }
112:
113: /**
114: * renderer for the combo box
115: */
116: protected class FileComboRenderer extends DefaultListCellRenderer {
117: protected FileComboRenderer() {
118: super ();
119: }
120:
121: public Component getListCellRendererComponent(JList list,
122: Object value, int index, boolean isSelected,
123: boolean cellHasFocus) {
124: Object path;
125: if (value instanceof FileNode) {
126: File f = ((FileNode) value).getFile();
127: if (f != null)
128: path = f.getAbsolutePath();
129: else
130: path = "what is this?";
131: } else
132: path = value;
133: return super .getListCellRendererComponent(list, path,
134: index, isSelected, cellHasFocus);
135: }
136: }
137:
138: public static class FileNode extends DefaultMutableTreeNode
139: implements Comparable {
140: private File file;
141: private Vector children;
142: private static FileNode rootNode;
143: private static File[] roots = File.listRoots();
144:
145: public static final boolean isRoot(File f) {
146: for (int i = 0; i < roots.length; i++) {
147: if (roots[i].equals(f))
148: return true;
149: }
150: return false;
151: }
152:
153: /**
154: * equivalent to calling File.listRoots(), but retrieves statically cached information.
155: * on Windows, calling File.listRoots() causes a dialog to appear if there is no disk in a
156: * removable drive! Aaargh.
157: */
158: public static File[] listRoots() {
159: return roots;
160: }
161:
162: public static FileNode getRootNode() {
163: if (rootNode == null) {
164: if (roots.length > 2)
165: rootNode = new FileNode(null);
166: else
167: rootNode = new FileNode(roots[0]);
168: }
169: return rootNode;
170: }
171:
172: public FileNode(File f) {
173: super ();
174: if (f == null)
175: setUserObject(null);
176: else {
177: if (isRoot(f)) {
178: String s = f.toString();
179: setUserObject(s);
180: } else {
181: setUserObject(f.getName());
182: }
183: }
184: this .file = f;
185: }
186:
187: private void initChildren() {
188: children = new Vector();
189: File[] files = (file != null) ? file.listFiles() : roots;
190: if (files != null) {
191: Arrays.sort(files);
192: for (int i = 0; i < files.length; i++) {
193: children.add(new FileNode(files[i]));
194: }
195: }
196: }
197:
198: public int getChildCount() {
199: if (children == null)
200: initChildren();
201: return children.size();
202: }
203:
204: public boolean isLeaf() {
205: return file != null && !file.isDirectory();
206: }
207:
208: public TreeNode getChildAt(int index) {
209: if (children == null)
210: initChildren();
211: if (index >= 0 && index < getChildCount())
212: return (TreeNode) children.elementAt(index);
213: return null;
214: }
215:
216: public int getIndex(TreeNode child) {
217: if (children == null)
218: initChildren();
219: if (child instanceof FileNode) {
220: return children.indexOf(child);
221: }
222: return -1;
223: }
224:
225: public Enumeration children() {
226: if (children == null)
227: initChildren();
228: return children.elements();
229: }
230:
231: public File getFile() {
232: return this .file;
233: }
234:
235: public int compareTo(Object other) {
236: if (other instanceof FileNode) {
237: if (this .file != null)
238: return this .file.compareTo(((FileNode) other)
239: .getFile());
240: else
241: return Integer.MIN_VALUE;
242: } else
243: throw new ClassCastException(
244: "FileNodes must be compared to other FileNodes");
245: }
246: }
247: }
248:
249: /* $Log */
|