📄 filesystemtree.java
字号:
/**
* Returns the display name for a given file.
*
* @param file The file for which to get the display name.
* @return The display name.
*/
protected String getName(File file) {
if (file==null)
return null;
String name = (String)rootNameCache.get(file);
if (name!=null)
return name;
name = fileSystemView.getSystemDisplayName(file);
if (name!=null && !EMPTY.equals(name))
return name;
return file.getAbsolutePath();
}
/*****************************************************************************/
/**
* This method is overridden to ensure that this tree is given a little
* bit of room if it is placed into a <code>JScrollPane</code> (which
* is likely). If you don't do this, the tree's preferred width will only
* be the maximum width of one of its visible nodes, so it will appear
* "squished" into whatever frame/dialog it's in.
*
* @return The preferred size of this tree.
*/
public Dimension getPreferredSize() {
Dimension size = super.getPreferredSize();
size.width = Math.max(size.width, 300);
return size;
}
/*****************************************************************************/
/**
* Returns the file currently selected by the user.
*
* @return The file currently selected, or <code>null</code>
* if no file is selected.
* @see #getSelectedFileName
*/
public File getSelectedFile() {
TreePath path = getSelectionPath();
if (path!=null) {
Object comp = path.getLastPathComponent();
if (comp!=null && comp instanceof FileSystemTreeNode) {
FileSystemTreeNode node = (FileSystemTreeNode)comp;
return (File)node.getUserObject();
}
}
return null;
}
/*****************************************************************************/
/**
* Returns the name of the file currently selected by the user.
*
* @return The name of the file currently selected, or <code>null</code>
* if no file is selected.
* @see #getSelectedFile
*/
public String getSelectedFileName() {
File file = getSelectedFile();
return file!=null ? file.getAbsolutePath() : null;
}
/*****************************************************************************/
/**
* Returns the string to use for the tooltip.
*
* @return The tooltip text.
*/
public String getToolTipText(MouseEvent e) {
String tip = null;
int x = e.getX();
int y = e.getY();
TreePath path = getPathForLocation(x, y);
if (path!=null) {
Object comp = path.getLastPathComponent();
if (comp!=null && comp instanceof FileSystemTreeNode) {
FileSystemTreeNode node = (FileSystemTreeNode)comp;
return getName((File)node.getUserObject());
}
}
return tip;
}
/*****************************************************************************/
/**
* Called when a mouse event occurs in this file system tree. This method
* is overridden so that we can display our popup menu if necessary.
*
* @param e The mouse event.
*/
protected void processMouseEvent(MouseEvent e) {
super.processMouseEvent(e);
if (e.isPopupTrigger()) {
displayPopupMenu(e.getPoint());
}
}
/*****************************************************************************/
/**
* Refreshes the children of the specified node (representing a directory)
* to accurately reflect the files inside of it.
*
* @param node The node.
*/
private void refreshChildren(FileSystemTreeNode node) {
node.removeAllChildren();
File file = node.getFile();
if (file.isDirectory()) {
File[] children = fileSystemView.getFiles(file, false);
File[] filteredChildren = filterAndSort(children);
int numChildren = filteredChildren.length;
for (int i=0; i<numChildren; i++)
node.add(createTreeNodeFor(filteredChildren[i]));
}
}
/*****************************************************************************/
/**
* Selects the given file in the tree. If the file does not exist,
* then no file is selected.
*
* @param file The file to select.
*/
public void selectFile(final File file) {
if (file==null || !file.exists())
return;
ArrayList parents = new ArrayList();
File f2 = file;
while (f2!=null) {
parents.add(f2);
f2 = f2.getParentFile();
}
int numParents = parents.size();
FileSystemTreeNode temp = root;
TreePath path = null;
for (int i=numParents-1; i>=0; i--) {
temp = getChildRepresentingFile(temp, parents.get(i));
if (temp==null) {
System.err.println("aargh");
return;
}
path = new TreePath(temp.getPath());
// Won't work on a leaf node, but who cares...
expandPath(path);
}
setSelectionPath(path);
}
/*****************************************************************************/
/**
* Overridden so that the renderer is also updated on a LnF change.
* If we don't do this, the renderer will still work, but will use the
* "background color" and other colors from the original LnF.
*/
public void updateUI() {
super.updateUI();
// Don't create a new one the first time through (done in ctor).
if (cellRenderer!=null) {
// NOTE: DefaultTreeCellRenderer caches icons, colors, etc.,
// so we cannot simply call cellRenderer.updateUI(),
// unfortunately; we must create a new one ourselves.
//SwingUtilities.updateComponentTreeUI(cellRenderer);
cellRenderer = new FileSystemTreeRenderer();
setCellRenderer(cellRenderer);
}
}
/*****************************************************************************/
/***************** PRIVATE INNER CLASSES *************************************/
/*****************************************************************************/
/**
* The tree node used by the file tree. This class ia mainly here
* for debugging purposes and serves no real purpose.
*/
public static class FileSystemTreeNode extends DefaultMutableTreeNode {
/**
*
*/
private static final long serialVersionUID = -1030689945943927405L;
public FileSystemTreeNode() {
super();
}
public FileSystemTreeNode(Object userObject) {
super(userObject);
}
public boolean containsFile(File file) {
return (file!=null && file.equals(userObject));
}
public boolean equals(Object o2) {
if (o2 instanceof FileSystemTreeNode) {
File f2 = ((FileSystemTreeNode)o2).getFile();
File file = getFile();
if ((file==null && f2==null) || (file.equals(f2)))
return true;
}
return false;
}
public File getFile() {
return (File)userObject;
}
public String toString() {
File file = getFile();
String fileName = file==null ? "<null>" : file.getAbsolutePath();
return "[FileSystemTreeNode: file=" + fileName + "]";
}
}
/*****************************************************************************/
/**
* Renderer for the file tree.
*/
class FileSystemTreeRenderer extends DefaultTreeCellRenderer {
/**
*
*/
private static final long serialVersionUID = 873373377685565005L;
public Component getTreeCellRendererComponent(JTree tree,
Object value, boolean sel,
boolean expanded, boolean leaf,
int row, boolean hasFocus)
{
super.getTreeCellRendererComponent(tree, value, sel, expanded,
leaf, row, hasFocus);
// Make the node have the proper icon and only display the
// file name.
// We must check "instanceof File" because it appears that Metal
// and Motif LnF's call this method during a JTree's setRoot()
// call (although Windows LnF doesn't... ???), which throws a
// ClassCastException, as this is evidently called before the
// root is replaced (and so the root node contains default sample
// data such as "Colors" or some junk). So if we check this, we
// don't cast to File before the stuff has changed to File.
Object userObj = ((DefaultMutableTreeNode)value).getUserObject();
if (userObj!=null && (userObj instanceof File) && row!=-1) {
File file = (File)userObj;
setText(FileSystemTree.this.getName(file));
setIcon(iconManager.getIcon(file));
}
return this;
}
}
/*****************************************************************************/
/**
* Action that "refreshes" the currently selected directory in the
* directory tree.
*/
private class RefreshAction extends AbstractAction {
/**
*
*/
private static final long serialVersionUID = 2105966082459252910L;
public RefreshAction(ResourceBundle bundle) {
super(bundle.getString("Refresh"));
putValue(Action.MNEMONIC_KEY,
new Integer((int)bundle.getString("RefreshMnemonic").
charAt(0)));
}
public void actionPerformed(ActionEvent e) {
TreePath path = getSelectionPath();
if (path!=null) { // Should always be true.
FileSystemTreeNode node = (FileSystemTreeNode)path.
getLastPathComponent();
File file = node.getFile();
// The file should be a directory. The only catch is
// that maybe the directory was deleted since the last
// time we cached. NOTE: We MUST check whether the file
// exists BEFORE we check whether it's a directory because
// isDirectory() can return true for a directory that has
// been removed after the File object was created, despite
// what the Javadoc says.
// If the directory no longer exists, refresh the structure
// from the parent directory down, in case other stuff has
// changed too.
if (!file.exists()) {
int count = path.getPathCount();
if (count>1) {
node = (FileSystemTreeNode)path.
getPathComponent(count-2);
refreshChildren(node);
treeModel.reload(node);
}
else { // It's the one and only file in the path...
removeSelectionPath(path);
treeModel.reload(node);
}
}
// If the directory still exists...
else if (file.isDirectory()) {
refreshChildren(node);
treeModel.reload(node); // Causes repaint properly.
}
// Otherwise, they've removed what was a directory when we
// cached data, and created a regular file in its place...
// Again, we'll refresh the parent directory's cached data.
else {
int count = path.getPathCount();
if (count>1) {
node = (FileSystemTreeNode)path.
getPathComponent(count-2);
refreshChildren(node);
treeModel.reload(node);
}
else { // It's the one and only file in the path...
removeSelectionPath(path);
treeModel.reload(node);
}
}
}
}
}
/*****************************************************************************/
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -