Search code examples
javaperformanceswingjtree

Make an Tree for FileExplorerApplication but it's too slow for loading :< (JAVA , NETBEAN, JTREE, FILE Explorer)


So I want to make Tree for File Explorer , But my code is very slow :< I want to increase Perform of this application (sr My English is not very good):

This is What i Want but it's load too slow 1-2min

This is design view

So this is my code : (I remove initcomponent b/c it's not needed)

public class TreePanel extends javax.swing.JPanel {

    DefaultMutableTreeNode root;
    File[] drives;
    File copyfile,movefile;
    public TreePanel() {
        initComponents();
        drives = GetDrive();
        CreateJtree(drives);
        //ChangeIconNode();

    }
private javax.swing.JTree MyTree;
private javax.swing.JScrollPane jScrollPane1;

private void CreateJtree(File[] drives1) {
    root = new DefaultMutableTreeNode("This PC");

    DefaultTreeModel tree = new DefaultTreeModel(root);
    MyTree.setModel(tree);
    if (drives1 != null) {
        for (File file : drives1) {
            DefaultMutableTreeNode tmp = new DefaultMutableTreeNode(file.getAbsolutePath());
            root.add(tmp);
            AddNodeByRecursive(tmp, file.listFiles());
        }

    }
}

//Image

private Icon ImageResize(ImageIcon imageIcon) {
    int size = 15;
    Image t = imageIcon.getImage().getScaledInstance(size, size, Image.SCALE_SMOOTH);
    return new ImageIcon(t);
}

private void ChangeIconNode() {
    // Change the default JTree icons
    DefaultTreeCellRenderer renderer = (DefaultTreeCellRenderer) MyTree.getCellRenderer();

    Icon closedIcon = ImageResize(new ImageIcon("src/ImagePackages/closed.png"));
    Icon openIcon = ImageResize(new ImageIcon("src/ImagePackages/open.png"));
    Icon leafIcon = ImageResize(new ImageIcon("src/ImagePackages/leaf.png"));
    renderer.setClosedIcon(closedIcon);
    renderer.setOpenIcon(openIcon);
    renderer.setLeafIcon(leafIcon);
    //end of change
}

private File[] GetDrive() {
    return File.listRoots();
}

private void AddNodeByRecursive(DefaultMutableTreeNode root, File[] drives1) {
    if (drives1 == null) {
        return;
    } else {
        for (File file : drives1) {
            DefaultMutableTreeNode tempnode = new DefaultMutableTreeNode(file.getName());
            System.out.println(file.getName());
            root.add(tempnode);
            File[] tempfilearr = file.listFiles();
            AddNodeByRecursive(tempnode, tempfilearr);
        }

    }
}

private void RefreshTree() {
    
    DefaultTreeModel tree = new DefaultTreeModel(root);
    MyTree.setModel(tree);
}

Solution

  • but it's load too slow 1-2min

    Sounds like you are trying to build the tree for the entire drive up front. Don't.

    Instead, you can dynamically build the tree as the user clicks to expand a node by adding a TreeWillExpand listener to the tree.

    Simple example:

    import java.awt.*;
    import java.awt.event.*;
    import java.io.*;
    import javax.swing.*;
    import javax.swing.tree.*;
    import javax.swing.event.*;
    import java.nio.file.*;
    
    public class TreeFileSystem extends JPanel
        implements ActionListener, TreeWillExpandListener
    {
        private int fileIndex;
    
        private JTree tree;
        private DefaultTreeModel model;
    
        private JTextField textField;
    
        public TreeFileSystem()
        {
            super(new BorderLayout());
    
            textField = new JTextField("c:\\");
            textField.addActionListener( this );
            add(textField, BorderLayout.NORTH);
    
            tree = new JTree( new DefaultMutableTreeNode() );
            JScrollPane scrollPane = new JScrollPane( tree );
            add(scrollPane);
    
            tree.addTreeWillExpandListener( this );
    
            textField.postActionEvent();
        }
    
        public void actionPerformed(ActionEvent e)
        {
            File file = new File( textField.getText() );
    
            if (file.exists())
            {
                DefaultMutableTreeNode root = new DefaultMutableTreeNode( file );
                model = new DefaultTreeModel( root );
                addNodes(root, true);
                tree.setModel( model );
            }
        }
    
        private void addNodes(DefaultMutableTreeNode root, boolean addChildNodes)
        {
            File file = (File)root.getUserObject();
            System.out.println(file);
    
            if (!file.isDirectory()) return;
    
            File[] files = file.listFiles(f -> !f.isHidden());
    
            if (files == null) return;
    
            int directoryInsert = 0;
    
            for (int i = 0; i < files.length; i++)
            {
                file = files[i];
    
                DefaultMutableTreeNode node = new MyDefaultMutableTreeNode( file );
    
                if (file.isDirectory())
                    root.insert(node, directoryInsert++);
                else
                    root.insert(node, i);
    
                if (addChildNodes)
                    addNodes(node, false);
            }
        }
    
        public void treeWillExpand(TreeExpansionEvent e) throws ExpandVetoException
        {
            System.out.println("will expand");
            if (tree.hasBeenExpanded(e.getPath())) return;
    
            TreePath path = e.getPath();
            System.out.println(path);
    
            if (path.getPathCount() == 2) return;
            System.out.println(path.getPathCount());
    
            DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getPathComponent( path.getPathCount() - 1);
            addNodes(node, false);
        }
    
        public void treeWillCollapse(TreeExpansionEvent e) {}
    
        class MyDefaultMutableTreeNode extends DefaultMutableTreeNode
        {
            public MyDefaultMutableTreeNode(Object node)
            {
                super(node);
            }
    
            public boolean isLeaf()
            {
                File file = (File)getUserObject();
    
                return file.isFile();
            }
        }
    
        public static void main(String[] args)
        {
            JFrame frame = new JFrame();
            frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
            frame.getContentPane().add( new TreeFileSystem() );
            frame.setSize(300, 400);
            frame.setLocationRelativeTo( null );
            frame.setVisible(true);
        }
    }