[Bug #793] Fix bug

CONTENTS_CHANGED event doesn't work well when the node has children as
the new content.

When TreeViewStateSnapshot.openIfRequired(Treeitem) tries to open the
previously opened element, the associated Treeitem has the _loaded
property set to true. As you can see in [1] this avoids the children
to be rendered.

Instead a INTERVAL_REMOVED and INTERVAL_ADDED are fired so the the
Treeitems for the elements moved are removed and recreated completely
avoiding that problem.

This introduces a new issue: the node loses its selection status but
can be fixed using a similar approach to TreeViewStateSnapshot.

[1] org.zkoss.zul.Tree.renderItem0(Renderer, Treeitem, Object)
This commit is contained in:
Óscar González Fernández 2011-01-06 20:56:43 +01:00
parent 094e7b7080
commit f4f40cd9b7
2 changed files with 21 additions and 7 deletions

View file

@ -389,8 +389,7 @@ public class MutableTreeModel<T> extends AbstractTreeModel {
Node<T> parentNode = find(parent);
int[] changed = parentNode.down(find(node));
if (changed.length != 0) {
fireEvent(parent, changed[0], changed[1],
TreeDataEvent.CONTENTS_CHANGED);
fireRecreationOfInterval(parentNode, changed[0], changed[1]);
}
}
@ -399,11 +398,18 @@ public class MutableTreeModel<T> extends AbstractTreeModel {
Node<T> parentNode = find(parent);
int[] changed = parentNode.up(find(node));
if (changed.length != 0) {
fireEvent(parent, changed[0], changed[1],
TreeDataEvent.CONTENTS_CHANGED);
fireRecreationOfInterval(parentNode, changed[0], changed[1]);
}
}
private void fireRecreationOfInterval(Node<T> parentNode, int start,
int endInclusive) {
fireEvent(parentNode.value, start, endInclusive,
TreeDataEvent.INTERVAL_REMOVED);
fireEvent(parentNode.value, start, endInclusive,
TreeDataEvent.INTERVAL_ADDED);
}
public boolean isEmpty() {
return getChildCount(getRoot()) == 0;
}

View file

@ -492,7 +492,7 @@ public class MutableTreeModelTest {
}
@Test
public void movingUpAndDownSendsEvents() {
public void movingUpAndDownSendsRemovalAndAddingEventsSoZKReloadsCorrectlyTheData() {
final MutableTreeModel<Prueba> model = MutableTreeModel
.create(Prueba.class);
Prueba prueba1 = new Prueba();
@ -510,10 +510,14 @@ public class MutableTreeModelTest {
}
});
model.up(prueba2);
checkIsValid(getLast(eventsFired), TreeDataEvent.CONTENTS_CHANGED,
checkIsValid(getPreviousToLast(eventsFired),
TreeDataEvent.INTERVAL_REMOVED, model.getRoot(), 0, 1);
checkIsValid(getLast(eventsFired), TreeDataEvent.INTERVAL_ADDED,
model.getRoot(), 0, 1);
model.down(prueba1);
checkIsValid(getLast(eventsFired), TreeDataEvent.CONTENTS_CHANGED,
checkIsValid(getPreviousToLast(eventsFired),
TreeDataEvent.INTERVAL_REMOVED, model.getRoot(), 1, 2);
checkIsValid(getLast(eventsFired), TreeDataEvent.INTERVAL_ADDED,
model.getRoot(), 1, 2);
}
@ -579,6 +583,10 @@ public class MutableTreeModelTest {
assertThat(event.getType(), equalTo(type));
}
private TreeDataEvent getPreviousToLast(List<TreeDataEvent> list) {
return list.get(list.size() - 2);
}
private TreeDataEvent getLast(List<TreeDataEvent> list) {
if (list.isEmpty()) {
throw new RuntimeException("no events");