Sunday

Implementation of lazy loading (swing)


Hello, this is a example of displaying tree folder with lazy loading.
List of child nodes is retrieved when click on a node by using TreeWillExpandListener.

1. Class TreeDirectory
package jbohn.swing;
import java.awt.EventQueue;
import java.io.File;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JTree;
import javax.swing.SwingWorker;
import javax.swing.event.TreeExpansionEvent;
import javax.swing.event.TreeWillExpandListener;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.ExpandVetoException;
import javax.swing.tree.MutableTreeNode;

public class TreeDirectory extends JFrame implements TreeWillExpandListener
{
    private JTree jTree;
    private DefaultTreeModel treeModel;
    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                // TODO Auto-generated method stub
                TreeDirectory tree = new TreeDirectory();
                tree.initial();
                tree.setVisible(true);
            }
        });
    }
    private void initial()
    {
        this.add(getJTreeDirectory());
    }

    @Override
    public void treeWillCollapse(TreeExpansionEvent arg0)
            throws ExpandVetoException {
    }

    @Override
    public void treeWillExpand(TreeExpansionEvent arg0)
            throws ExpandVetoException {
        final TreeNode lazyNode =
                (TreeNode) arg0.getPath().getLastPathComponent();
        if( lazyNode.isFullyLoaded() )
        {
            return;
        }
        new SwingWorker<List<MutableTreeNode>, Void>(){
            @Override
            protected List<MutableTreeNode> doInBackground() throws Exception {
                // TODO Auto-generated method stub
                return lazyNode.loadChildren();
            }

            protected void done() {
                try {
                    for (MutableTreeNode node : get()) {
                        treeModel.insertNodeInto(node, lazyNode,
                                lazyNode.getChildCount());
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }.execute();
    }
    public JTree getJTreeDirectory() {
        if (jTree == null)
        {
            TreeNode root = new TreeNode(new File("C:\\"));
            treeModel = new DefaultTreeModel(root, true);
            jTree = new JTree(treeModel);
            jTree.setRootVisible(true);
            jTree.addTreeWillExpandListener(this);
            jTree.collapseRow(0);
        }
        return jTree;
    }
}


2. Class TreeNode
package jbohn.swing;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.MutableTreeNode;

public class TreeNode extends DefaultMutableTreeNode
{
    public TreeNode(File file)
    {
        super(file);
        setAllowsChildren(file.isDirectory());
    }
    public List<MutableTreeNode> loadChildren() {
        List<MutableTreeNode> list = new ArrayList<>();
        File[] fileList = ((File) getUserObject()).listFiles();
        if (fileList == null) {
            fileList = new File[0];
        }
        for (File file : fileList) {
            list.add(new TreeNode(file));
        }
        return list;
    }
    public boolean isFullyLoaded()
    {
        return getChildCount() != 0 && getAllowsChildren();
    }
}

2 comments:

  1. Hello,I am doing lazy loading for my swing app. My problem happened when i clicked to node which has it's children and it didn't expand or do lazy loading. I have implemented lazy loading in Tree Will Expand Event, but it didn't work. Could you help me to fix my problem?

    ReplyDelete
  2. Could you please share the source or some snippet? I could have a look

    ReplyDelete