building DefaultTreeModel
To: comp.lang.java.gui
Hi,
I hope someone can explain to me how to build
my DefaultTreeModel from a List of delimited Strings.
I get from my news server a list
(some tens of thousands) of newsgroups in the form:
comp.lang.java.gui
comp.lang.java.help
comp.lang.java.programmer
news.software.nntp
news.software.readers
rec.models.railroad
rec.models.scale
Now, my latest attempt to build GroupTreeModel
produces:
MyNewsServer
|
comp
|
lang
|
java
|
gui
|
comp
|
lang
|
java
|
help
Instead of the desired:
MyNewsServer
|
comp
|
lang
|
java
|
gui
|
help
|
programmer
Also, with tens of thousands of groups
I haven't been able to wait long enough
for this method to complete. I've waited
some tens of minutes, I don't think there's
an infinite loop, I think it is just taking
a very long time - not sure.
Anyway, the GroupTreeDemo.fillModel()
method is my latest attempt, I hope someone
will help me accomplish my goal.
Thanks,
Jeff Higgins
package newsgroup;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreeNode;
@SuppressWarnings("serial")
public class GroupTreeDemo extends JFrame
{
public GroupTreeDemo()
{
super("GroupTreeModel Demo");
setSize(300, 400);
setDefaultCloseOperation(EXIT_ON_CLOSE);
Group f = new Group("MyNewsServer");
DefaultMutableTreeNode root =
new DefaultMutableTreeNode(f);
GroupTreeModel model =
new GroupTreeModel(root, new StringComparator());
fillModel(model);
JTree tree = new JTree(model);
getContentPane().add(new JScrollPane(tree));
}
private void fillModel(GroupTreeModel model)
{
String[] myGroups =
{ "comp.lang.java.gui",
"comp.lang.java.help",
"comp.lang.java.programmer",
"news.software.nntp",
"news.software.readers",
"rec.models.railroad",
"rec.models.scale"
};
ArrayList<List<Group>> groups =
new ArrayList<List<Group>>(myGroups.length);
List<Group> list;
for (String str : myGroups)
{
list = new ArrayList<Group>();
String[] strArray = str.split("\\.");
for (String s : strArray)
{
list.add(new Group(s));
}
groups.add(list);
}
// here is where I attempt to build my model
for (List<Group> lst : groups)
{
DefaultMutableTreeNode current =
(DefaultMutableTreeNode) model.getRoot();
for (Group g : lst)
{
boolean contains = false;
Enumeration enumeration = current.children();
while (enumeration.hasMoreElements())
{
if (enumeration.nextElement() == g)
{
contains = true;
}
}
if (!contains)
{
DefaultMutableTreeNode tmp =
new DefaultMutableTreeNode(g);
current.add(tmp);
current = tmp;
}
}
}
}
public class Group
{
String label;
public Group(String s)
{ label = s; }
public String getLabel()
{ return label; }
public String toString()
{ return label; }
}
public class StringComparator
implements Comparator<TreeNode>
{
public int compare(TreeNode o1, TreeNode o2)
{
if (!(o1 instanceof DefaultMutableTreeNode
&& o2 instanceof DefaultMutableTreeNode))
{
throw new IllegalArgumentException(
"Can only compare DefaultMutableTreeNode objects");
}
String s1 = ((DefaultMutableTreeNode) o1)
.getUserObject().toString();
String s2 = ((DefaultMutableTreeNode) o2)
.getUserObject().toString();
return s1.compareToIgnoreCase(s2);
}
}
@SuppressWarnings("serial")
class GroupTreeModel extends DefaultTreeModel
{
private Comparator<TreeNode> comparator;
public GroupTreeModel(
TreeNode node, Comparator<TreeNode> c)
{
super(node);
comparator = c;
}
public GroupTreeModel(
TreeNode node, boolean asksAllowsChildren,
Comparator<TreeNode> c)
{
super(node, asksAllowsChildren);
comparator = c;
}
public void insertNodeInto(
MutableTreeNode child, MutableTreeNode parent)
{
int index = findIndexFor(child, parent);
super.insertNodeInto(child, parent, index);
}
public void insertNodeInto(
MutableTreeNode child, MutableTreeNode par, int i)
{
// The index is useless in this model,
// so just ignore it.
insertNodeInto(child, par);
}
// Perform a recursive binary search
// on the children to find the right
// insertion point for the next node.
private int findIndexFor(
MutableTreeNode child, MutableTreeNode parent)
{
int cc = parent.getChildCount();
if (cc == 0)
{
return 0;
}
if (cc == 1)
{
return comparator.compare(
child, parent.getChildAt(0)) <= 0 ? 0 : 1;
}
// First & last index
return findIndexFor(child, parent, 0, cc - 1);
}
private int findIndexFor(
MutableTreeNode child, MutableTreeNode parent,
int i1, int i2)
{
if (i1 == i2)
{
return comparator.compare(
child, parent.getChildAt(i1)) <= 0 ? i1 : i1 + 1;
}
int half = (i1 + i2) / 2;
if (comparator.compare(
child, parent.getChildAt(half)) <= 0)
{
return findIndexFor(child, parent, i1, half);
}
return findIndexFor(child, parent, half + 1, i2);
}
}
public static void main(String args[])
{
GroupTreeDemo demo = new GroupTreeDemo();
demo.setVisible(true);
}
}
---
* Synchronet * The Whitehouse BBS --- whitehouse.hulds.com --- check it out free usenet!
--- Synchronet 3.15a-Win32 NewsLink 1.92
Time Warp of the Future BBS - telnet://time.synchro.net:24