使用JButton更新JTree更改时出现问题

时间:2013-12-17 02:03:38

标签: java swing jbutton jtree

我正在和几个人一起开展一个项目,我的任务是编译一个工作的JTree来显示一个set目录的结构。实际上,JTree在类启动时显示正确的文件和文件夹结构。但是,我似乎无法让它能够在添加或减少文件时更新(而不是使用JTree)。在我快乐的无知(非常有远见的那个)中,我添加了一个JButton;

treeModel.reload();

......希望能做到这一点。它确实重新加载了JTree,但是没有改变文件结构,即使在加载类之后添加了几个文件。

因此,我信任这个社区,既指出了我的问题的根源,又指出了语义和逻辑方面的其他缺陷。我是一个愿意学习的人。

    public class FileTree extends JPanel {

    private JTree tree;
    private DefaultMutableTreeNode root;
    private DefaultTreeModel treeModel;

    public FileTree(JPanel jp) {
        jp.setLayout(new BorderLayout());

        final File directory = getDir();
        createTree(directory);

        tree = new JTree(treeModel);
        tree.setRootVisible(true);
        tree.setShowsRootHandles(true);
        tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
        tree.setCellRenderer(new FileTreeCellRenderer());
        tree.addMouseListener(new MouseAdapter() {
            public void mousePressed(MouseEvent e) {
                 TreePath selPath = tree.getPathForLocation(e.getX(), e.getY());
                 if(e.getClickCount() == 2) {
                    Object n        = selPath.getLastPathComponent();
                    String sel      = n.toString();
                    File nodeFile   = new File(sel);

                    if(nodeFile.isDirectory() && (!nodeFile.isHidden())) {
                        UserWindow.printToLog("doubble-click event on folder: " + nodeFile.getName());
                        //TODO:stuff happening here
                    }

                     if(nodeFile.isFile() && (!nodeFile.isHidden())) {
                         UserWindow.printToLog("doubble-click event on file: " + nodeFile.getName());
                         new FileTreeEventHandler(nodeFile);
                     }
                 } 
            }
        });
        JScrollPane sp = new JScrollPane(tree);
        jp.add(sp);
        JButton updateButton = new JButton("Update");
        updateButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                treeModel.reload();
            }
        });
        jp.add(updateButton, BorderLayout.SOUTH);
        setVisible(true);
    }

    private void createTree(File directory) {
        root = new DefaultMutableTreeNode();
        treeModel = new DefaultTreeModel(root);
        DefaultMutableTreeNode node = new DefaultMutableTreeNode(directory);

        root.add(node);
        populate(directory, node);
    }

    private void populate(File directory, DefaultMutableTreeNode node) {
        String[] files = directory.list();
        for(String file : files) {
            File currentFile = new File(directory, file);
            addLeaf(node, currentFile);
        }
    }

    private void addLeaf(DefaultMutableTreeNode node, File currentFile) {
        if(currentFile.isFile() && !currentFile.isHidden()) {
            DefaultMutableTreeNode leafFile = new DefaultMutableTreeNode(currentFile);
            node.add(leafFile);
        }
        if(currentFile.isDirectory() && !currentFile.isHidden()) {
            DefaultMutableTreeNode folder = new DefaultMutableTreeNode(currentFile);
            node.add(folder);
            populate(currentFile, folder);
        }
    }

    private File getDir() {
        String path = new File(System.getProperty("user.dir"), "downloaded content").getAbsolutePath();
        File dir = new File(path);
        if(!dir.exists()) {
            dir.mkdirs();
        }
        return dir;
    }       
}

2 个答案:

答案 0 :(得分:1)

DefaultTreeModel#reload基本上陈述......

  

如果您修改了TreeNodes,则调用此方法   模特取决于。该模型将通知其所有听众   模型在给定节点下面发生了变化。

这假设模型本身已经改变。

你至少有两个基本的行动方案......

你可以......

  • 创建新的DefaultTreeModel
  • 从现有DefaultTreeModel ...
  • 中删除所有节点

然后重新构建模型。

如果您创建新的TreeModel,请确保将其设置为JTree

这有点沉重,但即使您选择编写填充算法以便检查模型的现有内容,您仍然需要遍历文件结构。

更新模型可以让您保留JTree的某些状态(例如,扩展或未扩展的节点)

如果您足够幸运使用Java 7,您还可以利用File Watcher API,例如,您可以将每个目录节点设置为观察者服务,以监控它自己的内容和发生更改时更新自身(添加/删除节点)。

查看Watching a Directory for Changes

答案 1 :(得分:1)

treeModel.reload();

我猜你需要调用:

,而不只是调用上面的代码
createTree(directory);
tree.setModel(treeModel);

重新创建TreeModel以反映新的目录结构。