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

Saturday

Overriding hashcode() method in Java and why always override hashcode() if overriding equals()?


Any class in java extend Object class by default. Object class has some non final methods: hashCode(), equals(), toString(), clone() and finalize(). Today we will discuss about hashCode() and equals() method.
  • You you want to use your object in a HashMap, Hashtable,… you need to override hashCode(). “hashCode()” method is supposed to return an int  that should uniquely identify different objects. The default hashCode() return machine address. When we use your object as a key in HashMap/Hashtable, then hashCode of this key will decide where corresponding value is stored in Hash. So if we override hashCode method, then performance of get value from Hash will be increased.

  • If you implemented equals() method, then you have to implement hashCode() method because of simple reason that there’s a consistent with equality: if x.equals(y), then x.hasCode() must == y.hashCode(). 

Sunday

Example of "ConcurrentModificationException" in multithreading and How to avoid?


When this exception happen?
This exception when a collection is modifying when it's being traversed.

Example:


OUTPUT
Key: 1
Exception in thread "Thread-0" java.util.ConcurrentModificationException
 at java.util.HashMap$HashIterator.nextEntry(Unknown Source)
 at java.util.HashMap$KeyIterator.next(Unknown Source)
 at jbohn.thread.JConcurentException$1.run(JConcurentException.java:26)
 at java.lang.Thread.run(Unknown Source)
Avoid this problem:
1. Clone a temporary list when loop a collection. This option work well for small list, but performance is affected.
//Copy key set to new list
ArrayList<Integer> keyList = new ArrayList<>(maps.keySet());
for (Iterator iterator = keyList.iterator(); iterator.hasNext();) {
   Integer integer = (Integer) iterator.next();
   System.out.println("Key: " + integer);
}





2. Using ConcurrentHashMap and CopyOnWriteArrayList for JDK 1.5 and above
private static final Map<Integer, String> maps = new ConcurrentHashMap<Integer, String>();


jbohn.blogspot.com