Hi again. I have just noticed that the problems also happens even without the "only leaves" filter
Just by updating one of the TreeList elements - the structure is getting messy.
Here is a trivial program that demonstrate the problem:
----- code start -----
import java.util.Comparator;
import java.util.List;
import ca.odell.glazedlists.BasicEventList;
import ca.odell.glazedlists.EventList;
import ca.odell.glazedlists.TreeList;
import ca.odell.glazedlists.TreeList.Format;
public class TreeListBug {
private TreeList<Item> treeList;
public TreeListBug() {
// prepare the source list
final EventList<Item> eventList = new BasicEventList<Item>();
Item sect1 = new Item(null, "code1", "name1");
Item sect11 = new Item(sect1, "code11", "name11");
Item sect12 = new Item(sect1, "code12", "name12");
final Item sect2 = new Item(null, "code2", "name2");
Item sect21 = new Item(sect2, "code21", "name21");
Item sect22 = new Item(sect2, "code22", "name22");
eventList.add(sect11);
eventList.add(sect12);
eventList.add(sect21);
eventList.add(sect22);
// A trivial tree format - defined by item.parent
Format format = new Format<Item>() {
public boolean allowsChildren(Item element) { return true; }
public Comparator<? extends Item> getComparator(int depth) { return null; }
public void getPath(List<Item> path, Item item) {
Item parent = item.parent;
while (parent != null) {
path.add(0, parent);
parent = parent.parent;
}
path.add(item);
}
};
treeList = new TreeList<Item>(eventList, format, TreeList.NODES_START_EXPANDED);
System.err.println("eventList="+eventList);
System.err.println("treeList="+treeList);
System.err.println("refreshing item 3 in treeList...");
Item item = treeList.get(3);
treeList.set(3, item);
System.err.println("eventList="+eventList);
System.err.println("treeList="+treeList);
}
public static class Item {
public String code;
public String name;
public Item parent;
public Item(Item parent, String code, String name) {
this.parent = parent;
this.code = code;
this.name = name;
}
public String toString() { return code+"/"+name; }
}
public static void main(String[] args) {
new TreeListBug();
}
}
----- code ends -----
Thanks again for help
Avital
avitaln wrote:
Hi
I am trying to build a tree table from a flat list, just like encouraged by GL but with one small difference: the source list contains all nodes and not just the leaves.
For this purpose, I wrote a FilterList which filters out the non leaf elements.
When windows is shown I see this tree table:
code1/name1
code11/name11
code12/name12
code2/name2
code21/name21
code22/name22
Now the user is updating name2 cell. What happens is that EventTableModel.setValueAt is trying to refresh row 3
this means that treeList.set(3, treeList.get(3)); is called.
After this call the tree looks like this (one element was lost!!!)
code1/name1
code11/name11
code2/name2
code21/name21
code22/name22
I wrote a small program which demonstrate the problem:
------ code start -------
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import ca.odell.glazedlists.BasicEventList;
import ca.odell.glazedlists.EventList;
import ca.odell.glazedlists.FilterList;
import ca.odell.glazedlists.FunctionList;
import ca.odell.glazedlists.GlazedLists;
import ca.odell.glazedlists.TreeList;
import ca.odell.glazedlists.TreeList.Format;
import ca.odell.glazedlists.matchers.Matcher;
public class TreeListBug {
private TreeList<Item> treeList;
public TreeListBug() {
// prepare the source list
final EventList<Item> eventList = new BasicEventList<Item>();
Item sect1 = new Item(null, "code1", "name1");
Item sect11 = new Item(sect1, "code11", "name11");
Item sect12 = new Item(sect1, "code12", "name12");
final Item sect2 = new Item(null, "code2", "name2");
Item sect21 = new Item(sect2, "code21", "name21");
Item sect22 = new Item(sect2, "code22", "name22");
eventList.add(sect1);
eventList.add(sect2);
eventList.add(sect11);
eventList.add(sect12);
eventList.add(sect21);
eventList.add(sect22);
// A trivial tree format - defined by item.parent
Format format = new Format<Item>() {
public boolean allowsChildren(Item element) { return true; }
public Comparator<? extends Item> getComparator(int depth) { return null; }
public void getPath(List<Item> path, Item item) {
Item parent = item.parent;
while (parent != null) {
path.add(0, parent);
parent = parent.parent;
}
path.add(item);
}
};
// Build a decorated list which contains only the leaves
OnlyLeavesMatcher matcher = new OnlyLeavesMatcher(eventList);
EventList<Item> onlyLeaves = new FilterList<Item>(eventList, matcher);
// Build the treeList from the onlyLeaves list
treeList = new TreeList<Item>(onlyLeaves, format, TreeList.NODES_START_EXPANDED);
System.err.println("eventList="+eventList);
System.err.println("treeList="+treeList);
System.err.println("onlyLeaves="+onlyLeaves);
System.err.println("refreshing item 3 in treeList...");
Item item = treeList.get(3);
treeList.set(3, item);
System.err.println("eventList="+eventList);
System.err.println("treeList="+treeList);
System.err.println("onlyLeaves="+onlyLeaves);
}
// A matcher which will filter out nodes which are not leaves
private static class OnlyLeavesMatcher implements Matcher<Item> {
private Map<Integer, List<Item>> mapByParent;
public OnlyLeavesMatcher(EventList<Item> eventList) {
mapByParent = GlazedLists.syncEventListToMultiMap(eventList, new IdentityOfParentFunction());
}
public boolean matches(Item item) {
List<Item> children = mapByParent.get(new Integer(System.identityHashCode(item)));
if (children == null || children.isEmpty()) {
return true;
}
return false;
}
private static class IdentityOfParentFunction implements FunctionList.Function<Item,Integer> {
public Integer evaluate(Item item) {
Object parent = item.parent;
if (parent == null) {
return 0;
}
return System.identityHashCode(parent);
}
}
}
public static class Item {
public String code;
public String name;
public Item parent;
public Item(Item parent, String code, String name) {
this.parent = parent;
this.code = code;
this.name = name;
}
public String toString() { return code+"/"+name; }
}
public static void main(String[] args) {
new TreeListBug();
}
}
------ code ends --------
Any idea?
Thanks in advance
Avital