View Javadoc

1   /*
2    *  XNap Commons
3    *
4    *  Copyright (C) 2005  Felix Berger
5    *  Copyright (C) 2005  Steffen Pingel
6    *
7    *  This library is free software; you can redistribute it and/or
8    *  modify it under the terms of the GNU Lesser General Public
9    *  License as published by the Free Software Foundation; either
10   *  version 2.1 of the License, or (at your option) any later version.
11   *
12   *  This library is distributed in the hope that it will be useful,
13   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15   *  Lesser General Public License for more details.
16   *
17   *  You should have received a copy of the GNU Lesser General Public
18   *  License along with this library; if not, write to the Free Software
19   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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 		// center
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 		// bottom
117 		homeAction = new HomeAction();
118 		getButtonPanel().add(Builder.createButton(homeAction), 0);
119 
120 		// set me up
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 }