JTree首次加载时不会显示句柄

时间:2015-03-09 14:16:20

标签: java swing jtree

因此,对于我正在进行的项目,我需要来自文件管理器的文件树,该文件管理器显示系统中的所有目录和文件。我找到了一个名为FileManager.Java的完整工作文件管理器,可在此页面上看到:https://codereview.stackexchange.com/questions/4446/file-browser-gui

然而,正如我所说,我只需要树的一部分。我已经实现了这一点,并采用了FileManager.java代码并将其分解为我认为必要的内容。那段代码在这里:

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Component;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.tree.*;
import javax.swing.filechooser.FileSystemView;

import java.util.List;
import java.io.*;


class FileManager {

    /** Provides nice icons and names for files. */
    private FileSystemView fileSystemView;

    /** File-system tree. Built Lazily */
    private JTree tree;
    private DefaultTreeModel treeModel;

    /** Directory listing */
    private JProgressBar progressBar;

    public Container getGui() {
        fileSystemView = FileSystemView.getFileSystemView();

        // the File tree
        DefaultMutableTreeNode root = new DefaultMutableTreeNode();
        treeModel = new DefaultTreeModel(root);

        TreeSelectionListener treeSelectionListener = new TreeSelectionListener() {
            public void valueChanged(TreeSelectionEvent tse){
                DefaultMutableTreeNode node =
                    (DefaultMutableTreeNode)tse.getPath().getLastPathComponent();
                showChildren(node);
            }
        };

        // show the file system roots.
        File[] roots = fileSystemView.getRoots();
        for (File fileSystemRoot : roots) {
            DefaultMutableTreeNode node = new DefaultMutableTreeNode(fileSystemRoot);
            root.add( node );
            //showChildren(node);
            File[] files = fileSystemView.getFiles(fileSystemRoot, true);
            for (File file : files) {
                if (file.isDirectory()) {
                    node.add(new DefaultMutableTreeNode(file));
                }
            }
        }

        tree = new JTree(treeModel);
        tree.setRootVisible(false);
        tree.addTreeSelectionListener(treeSelectionListener);
        tree.setCellRenderer(new FileTreeCellRenderer());
        tree.expandRow(0);
        tree.setVisibleRowCount(15);

        JPanel simpleOutput = new JPanel(new BorderLayout(3,3));
        progressBar = new JProgressBar();
        simpleOutput.add(progressBar, BorderLayout.EAST);
        progressBar.setVisible(false);

        return tree;
    }

    public void showRootFile() {
        // ensure the main files are displayed
        tree.setSelectionInterval(0,0);
    }




    /** Add the files that are contained within the directory of this node.
    Thanks to Hovercraft Full Of Eels. */
    private void showChildren(final DefaultMutableTreeNode node) {
        tree.setEnabled(false);
        progressBar.setVisible(true);
        progressBar.setIndeterminate(true);

        SwingWorker<Void, File> worker = new SwingWorker<Void, File>() {
            @Override
            public Void doInBackground() {
                File file = (File) node.getUserObject();
                if (file.isDirectory()) {
                    File[] files = fileSystemView.getFiles(file, true); //!!
                    if (node.isLeaf()) {
                        for (File child : files) {
//                            if (child.isDirectory()) {
                                publish(child);
//                           }
                        }
                    }
                }
                return null;
            }

            @Override
            protected void process(List<File> chunks) {
                for (File child : chunks) {
                    node.add(new DefaultMutableTreeNode(child));
                }
            }

            @Override
            protected void done() {
                progressBar.setIndeterminate(false);
                progressBar.setVisible(false);
                tree.setEnabled(true);
            }
        };
        worker.execute();
    }
}


/** A TreeCellRenderer for a File. */
class FileTreeCellRenderer extends DefaultTreeCellRenderer {

    private FileSystemView fileSystemView;

    private JLabel label;

    FileTreeCellRenderer() {
        label = new JLabel();
        //label.setOpaque(true);
        fileSystemView = FileSystemView.getFileSystemView();
    }

    @Override
    public Component getTreeCellRendererComponent(
        JTree tree,
        Object value,
        boolean selected,
        boolean expanded,
        boolean leaf,
        int row,
        boolean hasFocus) {
        DefaultMutableTreeNode node = (DefaultMutableTreeNode)value;
        File file = (File)node.getUserObject();
        label.setIcon(fileSystemView.getSystemIcon(file));
        label.setText(fileSystemView.getSystemDisplayName(file));
        label.setToolTipText(file.getPath());

        if (selected) {
            label.setBackground(backgroundSelectionColor);
            label.setForeground(textSelectionColor);
        } else {
            label.setBackground(backgroundNonSelectionColor);
            label.setForeground(textNonSelectionColor);
        }

        return label;
    }
}

当我将其调用到我的实际程序中时,一切正常,除了目录的句柄。我无法弄清楚如何在程序启动后立即显示它们。出于某种原因,您必须先单击该目录才能显示该目录。如果有人有任何想法,那将非常感激。

如果有帮助,当我将其称为我的程序时,我所做的只是

FileManager fm = new FileManager();
JScrollPane fmsp = new JScrollPane(fm.getGUI);

1 个答案:

答案 0 :(得分:1)

  

一切正常,除了目录的句柄。一旦程序启动,我无法弄清楚如何让它们显示出来。

两种方法表明自己:

  • 调用scrollPathToVisible();假设为DefaultMutableTreeNode,您可以使用TreePath获得depthFirstEnumeration()所示的合适for (int i = 0; i < tree.getRowCount(); i++) { tree.expandRow(i); }

  • 为要扩展的每个节点调用here

    {{1}}