package jas.util.gui; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Cursor; import java.awt.FlowLayout; import java.awt.Frame; import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.util.Vector; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextField; import javax.swing.JTree; import javax.swing.SwingUtilities; import javax.swing.event.EventListenerList; import javax.swing.event.TreeModelEvent; import javax.swing.event.TreeModelListener; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.filechooser.FileFilter; import javax.swing.filechooser.FileSystemView; import javax.swing.filechooser.FileView; import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.tree.TreeModel; import javax.swing.tree.TreePath; import javax.swing.tree.TreeSelectionModel; /** * A class which allows a user to select directories or files, similar to JFileChooser, * except that it display files as a tree, and is better suited to selecting directories * than the current file chooser (see java bug id 4239219). * * TODO: Understand issue with moving mouse between double clicks * (seems like MOUSE_PRESSED and MOUSE_RELEASED events are generated, but not MOUSE_CLICKED) * See Bug ID 4218549 * * @author Tony Johnson (tony_johnson@slac.stanford.edu) */ public class JDirectoryChooser extends JComponent { /** * Create a JDirectoryChooser with the default FileSystemView */ public JDirectoryChooser() { this(FileSystemView.getFileSystemView()); } /** * Create a JDirectoryChooser with the default FileSystemView * @param currentDirectory The directory to which the tree is initially set */ public JDirectoryChooser(File currentDirectory) { this(); setCurrentDirectory(currentDirectory); } /** * Create a JDirectoryChooser with the default FileSystemView * @param currentDirectory The directory to which the tree is initially set */ public JDirectoryChooser(String currentDirectory) { this(); if (currentDirectory != null) setCurrentDirectory(new File(currentDirectory)); } /** * Create a JDirectoryChooser * @param currentDirectory The directory to which the tree is initially set * @param view The FileSystemView to use */ public JDirectoryChooser(File currentDirectory, FileSystemView view) { this(view); setCurrentDirectory(currentDirectory); } /** * Create a JDirectoryChooser * @param currentDirectory The directory to which the tree is initially set * @param view The FileSystemView to use */ public JDirectoryChooser(String currentDirectory, FileSystemView view) { this(view); setCurrentDirectory(new File(currentDirectory)); } /** * Create a JDirectoryChooser * @param view The FileSystemView to use */ public JDirectoryChooser(FileSystemView view) { setup(view); ButtonListener al = new ButtonListener(); tree = new JTree(); tree.setRootVisible(false); tree.setShowsRootHandles(true); tree.setCellRenderer(new FileRenderer()); tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); tree.addTreeSelectionListener(al); approve.addActionListener(al); cancel.addActionListener(al); approve.setEnabled(false); setLayout(new BorderLayout()); add(new JScrollPane(tree)); JPanel p = new JPanel(new FlowLayout()); p.add(approve); p.add(cancel); add(p,BorderLayout.SOUTH); } public void addNotify() { tree.setModel(model); makeCurrentDirectoryVisible(); super.addNotify(); } private void makeCurrentDirectoryVisible() { if (currentDirectory != null) { File dir = currentDirectory; FileSystemView view = foo.getFileSystemView(); Vector v = new Vector(); while (true) { if (dir == null) return; // Something wrong, ignore dir v.addElement(dir); if (view.isRoot(dir)) break; dir = view.getParentDirectory(dir); } Object[] files = new File[v.size()+1]; Object node = model.getRoot(); files[0] = node; for (int i=1; i