JTree正在显示应该可以作为叶节点扩展的节点

时间:2017-03-06 09:45:13

标签: java jtree treemodel treepath

我有这个项目,我的程序从操作系统磁盘映像中获取文件并将其详细信息存储在数据库中,另一个功能从数据库中获取文件并将它们存储在List(我自己的对象类型)中,并且应该是在获取路径(也存储在数据库中)并基于斜杠拆分路径字符串后创建JTree,以便各种文件夹中的文件是叶节点,文件夹是父节点。获取文件非常有效,但我认为创建JTree有些问题,因为有些文件夹在JTree中显示为叶子节点。这是一个截图:

you can see the /home and /usr folders are terminal nodes

让我告诉你我的代码是什么样的:

public class ActiveCase {   
private void populateList(){
    //a function that fetches a list of files from a database and stores it in a list
 List<AbstractFile> l = *a query function that stores the files in the list*;
listFiles(l);
}

public void listFiles(List<AbstractFile> fl){    
    ArrayList<TreePath> te = new ArrayList<TreePath>();
    try {           
        for(AbstractFile file : fl){
        //don't worry about the isDir() and getName() functions they work                               
        if(!file.isDir() && !file.getName().startsWith(".")){                                        
        te.add(new TreePath(("File list"+formatPath(file.getUniquePath())).split("/")));
        }
    }
    } catch (TskCoreException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }   

        TreeModel tmClean = new TreePathsTreeModel("File list", te);
        cleanPanel.add(new JTree(tmClean));
}

private static String formatPath(String uniquePath){
    String[] pathSegments = uniquePath.split("/");
    int index = 3;
    StringBuilder strbuf = new StringBuilder();
    for (; index < pathSegments.length; ++index) {
        if (!pathSegments[index].isEmpty()) {
            strbuf.append("/").append(pathSegments[index]);
        }
    }   
    return strbuf.toString();
}        

}

我有一个实现TreeModel的TreePathsTreeModel类:

    public class TreePathsTreeModel implements TreeModel {
      private final ArrayList<TreePath> paths;
      private final String root;

      public TreePathsTreeModel(String root, ArrayList<TreePath> te) {
        this.root = root;
        this.paths = te;
        //a little test print statement to see if the TreePath list is in the right format
        for(TreePath t : paths){
            System.out.println(t.toString());
        }
      }
      @Override
      public Object getRoot() {
        return this.root;
      }

      @Override
      public Object getChild(Object parent, int index) {
        try {
          return getChildren(parent).get(index);
        } catch (IndexOutOfBoundsException ex) {
          return null;
        }
      }

      @Override
      public int getChildCount(Object parent) {
        return getChildren(parent).size();
      }

      @Override
      public boolean isLeaf(Object node) {
        for (int i = 0; i < paths.size(); i++) {
          TreePath treePath = paths.get(i);
          if (treePath.getLastPathComponent().equals(node))
            return true;
        }
        return false;
      }

      // This method is only required for editable trees, so it is not
      // implemented here.
      @Override
      public void valueForPathChanged(TreePath path, Object newValue) {
        //throw new UnsupportedOperationException("Not supported yet.");
      }

      @Override
      public int getIndexOfChild(Object parent, Object child) {
        return getChildren(parent).indexOf(child);
      }

      // This TreeModel never fires any events (since it is not editable)
      // so event listener registration methods are left unimplemented
      @Override
      public void addTreeModelListener(TreeModelListener l) {
        //throw new UnsupportedOperationException("Not supported yet.");
      }

      @Override
      public void removeTreeModelListener(TreeModelListener l) {
        //throw new UnsupportedOperationException("Not supported yet.");
      }
              //search all paths in list for given object 
              //return every item one level further than it
      private ArrayList<String> getChildren(Object parent) {
        ArrayList<String> children = new ArrayList<String>();
        for (int i = 0; i < this.paths.size(); i++) {
          ArrayList<Object> pathObjects = new ArrayList<Object>( Arrays.asList(this.paths.get(i).getPath()) );
          for (Iterator<Object> it = pathObjects.iterator(); it.hasNext();) {
            Object parentCandidate = it.next();
            if (parentCandidate.equals(parent)) {
              Iterator<Object> checker = it;
              try {
                String child = new DefaultMutableTreeNode( checker.next() ).toString();
                if ( !children.contains(child) )
                  children.add (child);
              } catch (NoSuchElementException ex) {

              } 
            }
          }
        }
        return children;
      }

    }

据我所知,TreePathsTreeModel构造函数中的print语句的列表格式正确。我将粘贴以下输出的样本:

...
[File list, dev, tty0]
[File list, dev, tty1]
[File list, dev, tty2]
[File list, dev, tty3]
[File list, dev, tty4]
[File list, dev, tty5]
[File list, dev, tty6]
[File list, dev, tty7]
[File list, dev, tty8]
[File list, dev, tty9]
[File list, dev, urandom]
[File list, dev, zero]
[File list, home, mainvm, examples.desktop]
[File list, home, mainvm, .cache, wallpaper, 0_5_1920_950_792beab7550410d531e55f95b449f135]
[File list, home, mainvm, .cache, upstart, unity7.log.2.gz]
[File list, home, mainvm, .cache, upstart, ssh-agent.log.2.gz]
[File list, home, mainvm, .cache, upstart, gnome-keyring-ssh.log.1.gz]
[File list, home, mainvm, .cache, upstart, dbus.log]
[File list, home, mainvm, .cache, upstart, unity7.log]
[File list, home, mainvm, .cache, upstart, hud.log]
[File list, home, mainvm, .cache, upstart, upstart-event-bridge.log.2.gz]
[File list, home, mainvm, .cache, upstart, unity7.log.1.gz]
[File list, home, mainvm, .cache, upstart, unity-settings-daemon.log.2.gz]
[File list, home, mainvm, .cache, upstart, unity-panel-service.log.2.gz]
[File list, home, mainvm, .cache, upstart, hud.log.1.gz]
[File list, home, mainvm, .cache, upstart, window-stack-bridge.log.2.gz]
[File list, home, mainvm, .cache, upstart, gpg-agent.log.2.gz]
[File list, home, mainvm, .cache, upstart, ssh-agent.log.1.gz]
[File list, home, mainvm, .cache, upstart, window-stack-bridge.log.1.gz]
[File list, home, mainvm, .cache, upstart, unity-panel-service.log]
[File list, home, mainvm, .cache, upstart, unity-settings-daemon.log.1.gz]
[File list, home, mainvm, .cache, upstart, unity-panel-service.log.1.gz]
[File list, home, mainvm, .cache, upstart, dbus.log.2.gz]
[File list, home, mainvm, .cache, upstart, dbus.log.1.gz]
[File list, home, mainvm, .cache, upstart, gnome-keyring-ssh.log.2.gz]
[File list, home, mainvm, .cache, upstart, gpg-agent.log.1.gz]
[File list, home, mainvm, .cache, upstart, indicator-sound.log.2.gz]
[File list, home, mainvm, .cache, upstart, indicator-sound.log.1.gz]
[File list, home, mainvm, .cache, upstart, upstart-event-bridge.log.1.gz]
[File list, home, mainvm, .cache, ibus, bus, registry.F0VAPY]
...
[File list, home, mainvm, .local, share, recently-used.xbel.49E0TY]
[File list, home, mainvm, .local, share, recently-used.xbel]
[File list, home, mainvm, .gnupg, gnupg_spawn_agent_sentinel.lock]
[File list, home, mainvm, .gnupg, S.gpg-agent]
[File list, lib, apparmor, functions]
[File list, lib, apparmor, profile-load]
[File list, lib, brltty, brltty.sh]
[File list, lib, brltty, libbrlttybal.so]
[File list, lib, brltty, libbrlttybat.so]
[File list, lib, brltty, libbrlttybba.so]
[File list, lib, brltty, libbrlttybbc.so]
[File list, lib, brltty, libbrlttybbd.so]
[File list, lib, brltty, libbrlttybbg.so]
[File list, lib, brltty, libbrlttybbl.so]
[File list, lib, brltty, libbrlttybbm.so]
[File list, lib, brltty, libbrlttybbn.so]
[File list, lib, brltty, libbrlttybcb.so]
[File list, lib, brltty, libbrlttybce.so]
[File list, lib, brltty, libbrlttybec.so]
[File list, lib, brltty, libbrlttybeu.so]
...

也许我的鼻子下面有一些我不知道的东西。这可能是一个愚蠢的错误。有任何想法吗?这是我大学的最后一年项目,请帮忙!

1 个答案:

答案 0 :(得分:2)

该错误最有可能出现在isLeaf(Object node)的{​​{1}}方法中 查看TreeModel.isLeaf(Object node)的javadoc:

  

如果TreeModel是一个叶子,则返回true。此方法可能会返回node   即使false没有孩子。例如,文件系统中的目录   可能不包含任何文件;表示目录的节点不是叶子,   但它也没有孩子。

因此,如果是目录(即使是目录),您需要返回node而不是false