JTree isn't showing handles when it first loads up

柔情痞子 提交于 2019-12-11 03:17:49

问题


So for a project I'm working on, I need the file tree from a file manager that displays all of the directories and files from a system. I found a full working file manager called FileManager.Java which can be seen on this page: https://codereview.stackexchange.com/questions/4446/file-browser-gui

However, as I said, I only need the tree part of this. I have already achieved this, and took the FileManager.java code and broke it down to what I believed necessary. That code is here:

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;
    }
}

When I call this into my actual program, everything works fine, except for the handles for the directories. I can't figure out how to get them to display as soon as the program starts. For some reason, you have to click on the directory first in order for it to show up. If anyone has any ideas, that'd be greatly appreciated.

If it helps, when I call this into my program, all I do is

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

回答1:


everything works fine, except for the handles for the directories. I can't figure out how to get them to display as soon as the program starts.

Two approaches suggest themselves:

  • Invoke scrollPathToVisible(); assuming DefaultMutableTreeNode, you can obtain a suitable TreePath as shown here using depthFirstEnumeration().

  • Invoke expandRow() for each node you want expanded:

    for (int i = 0; i < tree.getRowCount(); i++) {
        tree.expandRow(i);
    }
    


来源:https://stackoverflow.com/questions/28944195/jtree-isnt-showing-handles-when-it-first-loads-up

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!