📄 filesystemmodel2.java
字号:
*/ public String toString() { return file.getName(); } /** * Returns the java.io.File the receiver represents. */ public File getFile() { return file; } /** * Returns size of the receiver and all its children. */ public long totalSize() { return totalSize; } /** * Returns the parent of the receiver. */ public FileNode getParent() { return parent; } /** * Returns true if the receiver represents a leaf, that is it is * isn't a directory. */ public boolean isLeaf() { return file.isFile(); } /** * Returns true if the total size is valid. */ public boolean isTotalSizeValid() { return totalSizeValid; } /** * Clears the date. */ protected void resetLastModified() { lastModified = null; } /** * Sets the size of the receiver to be 0. */ protected void resetSize() { alterTotalSize(-totalSize); } /** * Loads the children, caching the results in the children * instance variable. */ protected FileNode[] getChildren() { return children; } /** * Recursively loads all the children of the receiver. */ protected void loadChildren(MergeSort sorter) { totalSize = file.length(); children = createChildren(null); for (int counter = children.length - 1; counter >= 0; counter--) { Thread.yield(); // Give the GUI CPU time to draw itself. if (!children[counter].isLeaf() && (descendLinks || !children[counter].isLink())) { children[counter].loadChildren(sorter); } totalSize += children[counter].totalSize(); if (!isValid) { counter = 0; } } if (isValid) { if (sorter != null) { sorter.sort(children); } totalSizeValid = true; } } /** * Loads the children of of the receiver. */ protected FileNode[] createChildren(MergeSort sorter) { FileNode[] retArray = null; try { String[] files = file.list(); if(files != null) { if (sorter != null) { sorter.sort(files); } retArray = new FileNode[files.length]; String path = file.getPath(); for(int i = 0; i < files.length; i++) { File childFile = new File(path, files[i]); retArray[i] = new FileNode(this, childFile); } } } catch (SecurityException se) {} if (retArray == null) { retArray = EMPTY_CHILDREN; } return retArray; } /** * Returns true if the children have been loaded. */ protected boolean loadedChildren() { return (file.isFile() || (children != null)); } /** * Gets the path from the root to the receiver. */ public FileNode[] getPath() { return getPathToRoot(this, 0); } /** * Returns the canonical path for the receiver. */ public String getCanonicalPath() { return canonicalPath; } /** * Returns true if the receiver's path does not begin with the * parent's canonical path. */ public boolean isLink() { return isLink; } protected FileNode[] getPathToRoot(FileNode aNode, int depth) { FileNode[] retNodes; if(aNode == null) { if(depth == 0) return null; else retNodes = new FileNode[depth]; } else { depth++; retNodes = getPathToRoot(aNode.getParent(), depth); retNodes[retNodes.length - depth] = aNode; } return retNodes; } /** * Sets the children of the receiver, updates the total size, * and if generateEvent is true a tree structure changed event * is created. */ protected void setChildren(FileNode[] newChildren, boolean generateEvent) { long oldSize = totalSize; totalSize = file.length(); children = newChildren; for (int counter = children.length - 1; counter >= 0; counter--) { totalSize += children[counter].totalSize(); } if (generateEvent) { FileNode[] path = getPath(); fireTreeStructureChanged(FileSystemModel2.this, path, null, null); FileNode parent = getParent(); if (parent != null) { parent.alterTotalSize(totalSize - oldSize); } } } protected synchronized void alterTotalSize(long sizeDelta) { if (sizeDelta != 0 && (parent = getParent()) != null) { totalSize += sizeDelta; nodeChanged(); parent.alterTotalSize(sizeDelta); } else { // Need a way to specify the root. totalSize += sizeDelta; } } /** * This should only be invoked on the event dispatching thread. */ protected synchronized void setTotalSizeValid(boolean newValue) { if (totalSizeValid != newValue) { nodeChanged(); totalSizeValid = newValue; FileNode parent = getParent(); if (parent != null) { parent.childTotalSizeChanged(this); } } } /** * Marks the receivers total size as valid, but does not invoke * node changed, nor message the parent. */ protected synchronized void forceTotalSizeValid() { totalSizeValid = true; } /** * Invoked when a childs total size has changed. */ protected synchronized void childTotalSizeChanged(FileNode child) { if (totalSizeValid != child.isTotalSizeValid()) { if (totalSizeValid) { setTotalSizeValid(false); } else { FileNode[] children = getChildren(); for (int counter = children.length - 1; counter >= 0; counter--) { if (!children[counter].isTotalSizeValid()) { return; } } setTotalSizeValid(true); } } } /** * Can be invoked when a node has changed, will create the * appropriate event. */ protected void nodeChanged() { FileNode parent = getParent(); if (parent != null) { FileNode[] path = parent.getPath(); int[] index = { getIndexOfChild(parent, this) }; Object[] children = { this }; fireTreeNodesChanged(FileSystemModel2.this, path, index, children); } } } /** * FileNodeLoader can be used to reload all the children of a * particular node. It first resets the children of the FileNode * it is created with, and in its run method will reload all of * that nodes children. FileNodeLoader may not be running in the event * dispatching thread. As swing is not thread safe it is important * that we don't generate events in this thread. SwingUtilities.invokeLater * is used so that events are generated in the event dispatching thread. */ class FileNodeLoader implements Runnable { /** Node creating children for. */ FileNode node; /** Sorter. */ MergeSort sizeMS; FileNodeLoader(FileNode node) { this.node = node; node.resetLastModified(); node.setChildren(node.createChildren(fileMS), true); node.setTotalSizeValid(false); } public void run() { FileNode[] children = node.getChildren(); sizeMS = getSizeSorter(); for (int counter = children.length - 1; counter >= 0; counter--) { if (!children[counter].isLeaf()) { reloadNode = children[counter]; loadChildren(children[counter]); reloadNode = null; } if (!isValid) { counter = 0; } } recycleSorter(sizeMS); if (isValid) { SwingUtilities.invokeLater(new Runnable() { public void run() { MergeSort sorter = getSizeSorter(); sorter.sort(node.getChildren()); recycleSorter(sorter); node.setChildren(node.getChildren(), true); synchronized(FileSystemModel2.this) { reloadCount--; FileSystemModel2.this.notifyAll(); } } }); } else { synchronized(FileSystemModel2.this) { reloadCount--; FileSystemModel2.this.notifyAll(); } } } protected void loadChildren(FileNode node) { if (!node.isLeaf() && (descendLinks || !node.isLink())) { final FileNode[] children = node.createChildren(null); for (int counter = children.length - 1; counter >= 0; counter--) { if (!children[counter].isLeaf()) { if (descendLinks || !children[counter].isLink()) { children[counter].loadChildren(sizeMS); } else { children[counter].forceTotalSizeValid(); } } if (!isValid) { counter = 0; } } if (isValid) { final FileNode fn = node; // Reset the children SwingUtilities.invokeLater(new Runnable() { public void run() { MergeSort sorter = getSizeSorter(); sorter.sort(children); recycleSorter(sorter); fn.setChildren(children, true); fn.setTotalSizeValid(true); fn.nodeChanged(); } }); } } else { node.forceTotalSizeValid(); } } } /** * Sorts the contents, which must be instances of FileNode based on * totalSize. */ static class SizeSorter extends MergeSort { public int compareElementsAt(int beginLoc, int endLoc) { long firstSize = ((FileNode)toSort[beginLoc]).totalSize(); long secondSize = ((FileNode)toSort[endLoc]).totalSize(); if (firstSize != secondSize) { return (int)(secondSize - firstSize); } return ((FileNode)toSort[beginLoc]).toString().compareTo (((FileNode)toSort[endLoc]).toString()); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -