Nothing fancy, but I know many new programmers are often confused about recursion. Recursion simply is when a method calls itself.
What MyTree does is it adds nodes to the root node, then that root node can be used to create a JTree.
The populate() method reads in a list of Files into an array. If the file is a folder(directory), then populate() is called again. Only this time, the root node is a sub-folder of the root node that was originally passed in at the MyTree object's creation. Now why do we that? If the file in the File array is a folder, it may have sub folders. Instead of adding all those sub folders to the root node of the tree, they're added to its parent folder.

For example, lets say the initial root node represents "My Computer" on your computer. The path for the new File is "c:/". "C:/" becomes the root for any of the sub folders it contains. And the root for "c:/" is "My Computer". Let's assume you only have 2 folders visible directly under C:/, "Program Files" and "Windows". During the first pass through the populate method, "c:" is added to "My Computer", and then the rootAdded flag is set to true. "C:" is now the root from this point on. The first folder that is seen is "Program Files". That is now added to "C:", and populate() is called again to check for sub-folders. This time when it is called, "program files" becomes the root. So any folders added at that point will be seen under the "program files" node, or folder. This process continues until no more sub folders are found. The method then begins to end at each level that it was called. Eventually, the method ends until its back at the first time it was called. "C:" becomes the root again, and searches for more folders. It see "Windows" and adds it to "C:", and starts the whole procedure over again. This may sound confusing, but if you open up Windows File Explorer and follow along with a visual reference, it should make more sense. Hope this helps somebody.

// The code you would have in Main()

DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root");
MyTree myLibraryList = new MyTree(new File("c:/mp3"), root);
tree = new JTree(root);

// The MyTree class.

import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
public class MyTree
	private JTree tree;
	private MP3 mf = null;
	private MyDir md = null;
	private File nf = null;
	private DefaultMutableTreeNode n = null;
	private FileFilter filter = new FilterMP3();
	public MyTree(File f, DefaultMutableTreeNode toPopulate)
		this.populate(f, toPopulate, false);
	private void populate(File f, DefaultMutableTreeNode toPopulate, boolean rootAdded)
		/* Add the root folder first, and only once
		if (!rootAdded)
			DefaultMutableTreeNode root = new DefaultMutableTreeNode(new MyDir(f.getPath(), f.getName()));
			toPopulate = root;
			rootAdded = true;
		File[] dirEntries = f.listFiles(filter);
		for (int i=0; i<dirEntries.length; i++)
			if (dirEntries[i].isFile())
				//mf = new MP3(dirEntries[i]);
				//n = new DefaultMutableTreeNode(mf);
			else if(dirEntries[i].isDirectory())
				md = new MyDir(dirEntries[i].getPath(),dirEntries[i].getName());
				n = new DefaultMutableTreeNode(md);
				nf = new File(dirEntries[i].getAbsolutePath());
				this.populate(nf, n, true); //recursive call, woohoo!
		 }//FOR statement
	}//end populate	 
}//class MyTree
public class MyDir
	public String m_path;
	public String m_name;
	public MyDir(String path, String name)
		m_path = path;
		m_name = name;
	public String getName()
		return m_name;
	public String getPath()
		return m_path;
	public String toString()
		return this.getName();