目录浏览器获得 NPE
Directory explorer gets NPE
以下代码是 FileTreeModel
的改编版本,仅显示目录。然而。当它尝试访问需要管理员权限的文件夹时,我收到空指针异常。一个例子可能看起来像
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at DirectoryExplorer$FileTreeModel.listDirectories(DirectoryExplorer.java:112)
at DirectoryExplorer$FileTreeModel.getChildCount(DirectoryExplorer.java:79)
at javax.swing.tree.VariableHeightLayoutCache$TreeStateNode.expand(Unknown Source)
at javax.swing.tree.VariableHeightLayoutCache$TreeStateNode.expand(Unknown Source)
at javax.swing.tree.VariableHeightLayoutCache.ensurePathIsExpanded(Unknown Source)
at javax.swing.tree.VariableHeightLayoutCache.setExpandedState(Unknown Source)
at javax.swing.plaf.basic.BasicTreeUI.updateExpandedDescendants(Unknown Source)
at javax.swing.plaf.basic.BasicTreeUI$Handler.treeExpanded(Unknown Source)
at javax.swing.JTree.fireTreeExpanded(Unknown Source)
at javax.swing.JTree.setExpandedState(Unknown Source)
at javax.swing.JTree.expandPath(Unknown Source)
at javax.swing.plaf.basic.BasicTreeUI.toggleExpandState(Unknown Source)
at javax.swing.plaf.basic.BasicTreeUI.handleExpandControlClick(Unknown Source)
at javax.swing.plaf.basic.BasicTreeUI.checkForClickInExpandControl(Unknown Source)
at javax.swing.plaf.basic.BasicTreeUI$Handler.handleSelection(Unknown Source)
at javax.swing.plaf.basic.BasicTreeUI$Handler.mousePressed(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access0(Unknown Source)
at java.awt.EventQueue.run(Unknown Source)
at java.awt.EventQueue.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.run(Unknown Source)
at java.awt.EventQueue.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
为了尝试限制这种情况,我添加了一个仅将可见文件夹添加到 JTree
的参数,但是,这并不能捕获所有文件夹。有没有办法排除所有需要管理员权限才能浏览的文件夹?
MCVE / SSCCE
import java.awt.GridLayout;
import java.io.File;
import java.util.Arrays;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.TreeModel;
@SuppressWarnings("serial")
public class DirectoryExplorer extends JFrame {
private DirectoryExplorer() {
super("Directory Explorer");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new GridLayout(1, 1));
createPanel();
pack();
setVisible(true);
}
private void createPanel() {
JPanel panel = new JPanel(new GridLayout(1, 1));
TreeModel model = new FileTreeModel(new File("C:/"));
JTree tree = new JTree(model);
tree.setShowsRootHandles(true);
tree.collapseRow(0);
panel.add(new JScrollPane(tree));
getContentPane().add(panel);
}
public static void main(String[] args) {
new DirectoryExplorer();
}
private static class FileTreeModel implements TreeModel {
private File root;
public FileTreeModel(File root) {
this.root = root;
}
@Override
public void addTreeModelListener(javax.swing.event.TreeModelListener l) {
//do nothing
}
@Override
public Object getChild(Object parent, int index) {
File f = (File) parent;
return listDirectories(f)[index];
}
@Override
public int getChildCount(Object parent) {
File f = (File) parent;
if (!f.isDirectory()) {
return 0;
} else {
return listDirectories(f).length;
}
}
@Override
public int getIndexOfChild(Object parent, Object child) {
File par = (File) parent;
File ch = (File) child;
return Arrays.asList(listDirectories(par)).indexOf(ch);
}
@Override
public Object getRoot() {
return root;
}
@Override
public boolean isLeaf(Object node) {
return false;
}
@Override
public void removeTreeModelListener(javax.swing.event.TreeModelListener l) {
//do nothing
}
@Override
public void valueForPathChanged(javax.swing.tree.TreePath path, Object newValue) {
//do nothing
}
private File[] listDirectories(File path) {
ArrayList<File> arrayList = new ArrayList<File>();
for(File temp : path.listFiles()) {
if(temp.isDirectory() && !temp.isHidden())
arrayList.add(temp);
}
return arrayList.toArray(new File[0]);
}
}
}
如果给定文件不是目录或不可读,File.listFiles()
可以 return null
。参见 JavaDoc。
if(temp.isDirectory() && !temp.isHidden() && temp.listFiles()!=null)
以下代码是 FileTreeModel
的改编版本,仅显示目录。然而。当它尝试访问需要管理员权限的文件夹时,我收到空指针异常。一个例子可能看起来像
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at DirectoryExplorer$FileTreeModel.listDirectories(DirectoryExplorer.java:112)
at DirectoryExplorer$FileTreeModel.getChildCount(DirectoryExplorer.java:79)
at javax.swing.tree.VariableHeightLayoutCache$TreeStateNode.expand(Unknown Source)
at javax.swing.tree.VariableHeightLayoutCache$TreeStateNode.expand(Unknown Source)
at javax.swing.tree.VariableHeightLayoutCache.ensurePathIsExpanded(Unknown Source)
at javax.swing.tree.VariableHeightLayoutCache.setExpandedState(Unknown Source)
at javax.swing.plaf.basic.BasicTreeUI.updateExpandedDescendants(Unknown Source)
at javax.swing.plaf.basic.BasicTreeUI$Handler.treeExpanded(Unknown Source)
at javax.swing.JTree.fireTreeExpanded(Unknown Source)
at javax.swing.JTree.setExpandedState(Unknown Source)
at javax.swing.JTree.expandPath(Unknown Source)
at javax.swing.plaf.basic.BasicTreeUI.toggleExpandState(Unknown Source)
at javax.swing.plaf.basic.BasicTreeUI.handleExpandControlClick(Unknown Source)
at javax.swing.plaf.basic.BasicTreeUI.checkForClickInExpandControl(Unknown Source)
at javax.swing.plaf.basic.BasicTreeUI$Handler.handleSelection(Unknown Source)
at javax.swing.plaf.basic.BasicTreeUI$Handler.mousePressed(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access0(Unknown Source)
at java.awt.EventQueue.run(Unknown Source)
at java.awt.EventQueue.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.run(Unknown Source)
at java.awt.EventQueue.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
为了尝试限制这种情况,我添加了一个仅将可见文件夹添加到 JTree
的参数,但是,这并不能捕获所有文件夹。有没有办法排除所有需要管理员权限才能浏览的文件夹?
MCVE / SSCCE
import java.awt.GridLayout;
import java.io.File;
import java.util.Arrays;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.TreeModel;
@SuppressWarnings("serial")
public class DirectoryExplorer extends JFrame {
private DirectoryExplorer() {
super("Directory Explorer");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new GridLayout(1, 1));
createPanel();
pack();
setVisible(true);
}
private void createPanel() {
JPanel panel = new JPanel(new GridLayout(1, 1));
TreeModel model = new FileTreeModel(new File("C:/"));
JTree tree = new JTree(model);
tree.setShowsRootHandles(true);
tree.collapseRow(0);
panel.add(new JScrollPane(tree));
getContentPane().add(panel);
}
public static void main(String[] args) {
new DirectoryExplorer();
}
private static class FileTreeModel implements TreeModel {
private File root;
public FileTreeModel(File root) {
this.root = root;
}
@Override
public void addTreeModelListener(javax.swing.event.TreeModelListener l) {
//do nothing
}
@Override
public Object getChild(Object parent, int index) {
File f = (File) parent;
return listDirectories(f)[index];
}
@Override
public int getChildCount(Object parent) {
File f = (File) parent;
if (!f.isDirectory()) {
return 0;
} else {
return listDirectories(f).length;
}
}
@Override
public int getIndexOfChild(Object parent, Object child) {
File par = (File) parent;
File ch = (File) child;
return Arrays.asList(listDirectories(par)).indexOf(ch);
}
@Override
public Object getRoot() {
return root;
}
@Override
public boolean isLeaf(Object node) {
return false;
}
@Override
public void removeTreeModelListener(javax.swing.event.TreeModelListener l) {
//do nothing
}
@Override
public void valueForPathChanged(javax.swing.tree.TreePath path, Object newValue) {
//do nothing
}
private File[] listDirectories(File path) {
ArrayList<File> arrayList = new ArrayList<File>();
for(File temp : path.listFiles()) {
if(temp.isDirectory() && !temp.isHidden())
arrayList.add(temp);
}
return arrayList.toArray(new File[0]);
}
}
}
File.listFiles()
可以 return null
。参见 JavaDoc。
if(temp.isDirectory() && !temp.isHidden() && temp.listFiles()!=null)