1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.xnap.commons.gui;
22
23 import java.awt.BorderLayout;
24 import java.awt.Component;
25 import java.awt.event.ActionEvent;
26 import java.io.File;
27 import java.util.LinkedList;
28 import javax.swing.Action;
29 import javax.swing.JDialog;
30 import javax.swing.JFrame;
31 import javax.swing.JScrollPane;
32 import javax.swing.JTree;
33 import javax.swing.event.TreeSelectionEvent;
34 import javax.swing.event.TreeSelectionListener;
35 import javax.swing.tree.TreePath;
36 import org.xnap.commons.gui.action.AbstractXNapAction;
37 import org.xnap.commons.gui.dnd.DefaultTreeFileTransferHandler;
38 import org.xnap.commons.gui.tree.FileCellRenderer;
39 import org.xnap.commons.gui.tree.FileNode;
40 import org.xnap.commons.gui.tree.FileTreeModel;
41 import org.xnap.commons.i18n.I18n;
42 import org.xnap.commons.i18n.I18nFactory;
43
44 /***
45 * Provides a dialog with a {@link JTree} that contains the local
46 * directory structure for directory selection and a button for quick selection
47 * of the user's home directory.
48 *
49 * <p>The usage of this class is similar to {@link javax.swing.JFileChooser}.
50 *
51 * TODO add auto completed input field for entering directory
52 */
53 public class DirectoryChooser extends DefaultDialog
54 implements TreeSelectionListener
55 {
56
57 private static final I18n i18n = I18nFactory.getI18n(DirectoryChooser.class);
58
59 public static final int APPROVE_OPTION = 1;
60 public static final int CANCEL_OPTION = 2;
61
62 private JTree directoryTree;
63 private FileTreeModel directoryTreeModel;
64 private HomeAction homeAction;
65 private int selectedOption;
66
67 /***
68 * Creates a directory chooser.
69 *
70 * @param owner the dialog's parent
71 */
72 public DirectoryChooser(JFrame owner)
73 {
74 super(owner, BUTTON_OKAY | BUTTON_CANCEL);
75
76 initialize();
77 }
78
79 /***
80 * Creates a directory chooser.
81 *
82 * @param owner the dialog's parent
83 */
84 public DirectoryChooser(JDialog owner)
85 {
86 super(owner, BUTTON_OKAY | BUTTON_CANCEL);
87
88 initialize();
89 }
90
91 /***
92 * Creates a directory chooser.
93 */
94 public DirectoryChooser()
95 {
96 super(BUTTON_OKAY | BUTTON_CANCEL);
97
98 initialize();
99 }
100
101 private void initialize()
102 {
103
104 directoryTreeModel = new FileTreeModel(i18n.tr("Folders"),
105 File.listRoots());
106 directoryTree = new JTree(directoryTreeModel);
107 directoryTree.setRootVisible(false);
108 directoryTree.setCellRenderer(new FileCellRenderer());
109 directoryTree.putClientProperty("JTree.lineStyle", "Angled");
110 directoryTree.addTreeSelectionListener(this);
111 directoryTree.setTransferHandler(new DefaultTreeFileTransferHandler());
112 directoryTree.setDragEnabled(true);
113
114 JScrollPane jspDirectories = new JScrollPane(directoryTree);
115
116
117 homeAction = new HomeAction();
118 getButtonPanel().add(Builder.createButton(homeAction), 0);
119
120
121 getMainPanel().setLayout(new BorderLayout());
122 getMainPanel().add(jspDirectories, BorderLayout.CENTER);
123
124 pack();
125 }
126
127 @Override
128 public boolean apply()
129 {
130 selectedOption = APPROVE_OPTION;
131 return true;
132 }
133
134 @Override
135 public void cancelled()
136 {
137 selectedOption = CANCEL_OPTION;
138 }
139
140 /***
141 * Returns the currently selected directory.
142 *
143 * @return the selected directory; null, if no directory is selected
144 */
145 public File getSelectedDirectory()
146 {
147 Object selectedItem = directoryTree.getLastSelectedPathComponent();
148 return (selectedItem instanceof File) ? (File)selectedItem : null;
149 }
150
151 /***
152 * Selects the specified directory in the tree. The tree is expanded
153 * as necessary and scrolled to ensure visibility of the directory.
154 *
155 * @param dir the directory to be selected
156 */
157 public void setSelectedDirectory(File dir)
158 {
159 LinkedList<FileNode> files = new LinkedList<FileNode>();
160 File parent = dir;
161 while (parent != null) {
162 files.addFirst(new FileNode(parent));
163 parent = parent.getParentFile();
164 }
165 Object[] path = new Object[files.size() + 1];
166 path[0] = directoryTreeModel.getRoot();
167 System.arraycopy(files.toArray(), 0, path, 1, path.length - 1);
168 TreePath tp = new TreePath(path);
169 directoryTree.setSelectionPath(tp);
170 directoryTree.scrollPathToVisible(tp);
171 }
172
173 public int showChooseDialog(Component c)
174 {
175 setTitle(i18n.tr("Choose a Folder"));
176 setModal(true);
177 pack();
178 show(c);
179
180 return selectedOption;
181 }
182
183 public void valueChanged(TreeSelectionEvent e)
184 {
185 getOkayAction().setEnabled(directoryTree.getLastSelectedPathComponent()
186 instanceof File);
187 }
188
189 public class HomeAction extends AbstractXNapAction {
190
191 public HomeAction()
192 {
193 putValue(Action.NAME, i18n.tr("Home"));
194 putValue(Action.SHORT_DESCRIPTION,
195 i18n.tr("Jump to home folder"));
196 putValue(ICON_FILENAME, "folder_home.png");
197 }
198
199 public void actionPerformed(ActionEvent event)
200 {
201 setSelectedDirectory(new File(System.getProperty("user.home")));
202 }
203
204 }
205
206 }