ItEr16S09RFComportamentoGraficoPlanificadorItEr15S12: Creating mutable tree model.
This commit is contained in:
parent
0bc3242c09
commit
a1e26c8370
3 changed files with 271 additions and 0 deletions
|
|
@ -40,6 +40,11 @@
|
|||
<groupId>org.jgrapht</groupId>
|
||||
<artifactId>jgrapht-jdk1.5</artifactId>
|
||||
</dependency>
|
||||
<!-- Junit -->
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,147 @@
|
|||
package org.zkoss.ganttz.util;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import org.zkoss.zul.AbstractTreeModel;
|
||||
import org.zkoss.zul.event.TreeDataEvent;
|
||||
|
||||
/**
|
||||
* @author Óscar González Fernández <ogonzalez@igalia.com>
|
||||
*/
|
||||
public class MutableTreeModel<T> extends AbstractTreeModel {
|
||||
|
||||
private static class Node<T> {
|
||||
private T value;
|
||||
|
||||
private List<Node<T>> children = new LinkedList<Node<T>>();
|
||||
|
||||
private Node<T> parentNode;
|
||||
|
||||
private Node(T value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public void add(Node<T> node) {
|
||||
node.parentNode = this;
|
||||
children.add(node);
|
||||
}
|
||||
|
||||
private void until(LinkedList<Integer> result, Node<T> parent) {
|
||||
if (parent.equals(this)) {
|
||||
return;
|
||||
} else {
|
||||
result.add(0, this.parentNode.getIndexOf(this));
|
||||
this.parentNode.until(result, parent);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private int getIndexOf(Node<T> child) {
|
||||
return children.indexOf(child);
|
||||
}
|
||||
|
||||
public LinkedList<Integer> until(Node<T> parent) {
|
||||
LinkedList<Integer> result = new LinkedList<Integer>();
|
||||
until(result, parent);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private final Class<T> type;
|
||||
|
||||
private final Node<T> root;
|
||||
|
||||
private Map<T, Node<T>> nodesByDomainObject = new WeakHashMap<T, Node<T>>();
|
||||
|
||||
private static <T> Node<T> wrap(T object) {
|
||||
return new Node<T>(object);
|
||||
}
|
||||
|
||||
private Node<T> find(Object domainObject) {
|
||||
Node<T> result = nodesByDomainObject.get(domainObject);
|
||||
if (result == null)
|
||||
throw new RuntimeException("not found " + domainObject);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static <T> T unwrap(Node<T> node) {
|
||||
return node == null ? null : node.value;
|
||||
}
|
||||
|
||||
public static <T> MutableTreeModel<T> create(Class<T> type) {
|
||||
return new MutableTreeModel<T>(type, new Node<T>(null));
|
||||
}
|
||||
|
||||
public static <T> MutableTreeModel<T> create(Class<T> type, T root) {
|
||||
return new MutableTreeModel<T>(type, wrap(root));
|
||||
}
|
||||
|
||||
private MutableTreeModel(Class<T> type, Node<T> root) {
|
||||
super(root);
|
||||
if (type == null)
|
||||
throw new IllegalArgumentException("type cannot be null");
|
||||
nodesByDomainObject.put(unwrap(root), root);
|
||||
this.type = type;
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getPath(Object parent, Object last) {
|
||||
Node<T> parentNode = find(parent);
|
||||
Node<T> lastNode = find(last);
|
||||
List<Integer> path = lastNode.until(parentNode);
|
||||
return asIntArray(path);
|
||||
}
|
||||
|
||||
private int[] asIntArray(List<Integer> path) {
|
||||
int[] result = new int[path.size()];
|
||||
int i = 0;
|
||||
for (Integer integer : path) {
|
||||
result[i++] = integer;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getRoot() {
|
||||
return unwrap(root);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getChild(Object parent, int index) {
|
||||
Node<T> node = find(parent);
|
||||
return unwrap(node.children.get(index));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChildCount(Object parent) {
|
||||
Node<T> node = find(parent);
|
||||
return node.children.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLeaf(Object object) {
|
||||
Node<T> node = find(object);
|
||||
return node.children.isEmpty();
|
||||
}
|
||||
|
||||
public void addToRoot(T child) {
|
||||
add(root, wrap(child));
|
||||
}
|
||||
|
||||
private void add(Node<T> parent, Node<T> child) {
|
||||
parent.add(child);
|
||||
nodesByDomainObject.put(unwrap(child), child);
|
||||
final int position = parent.children.size() - 1;
|
||||
fireEvent(unwrap(parent), position, position,
|
||||
TreeDataEvent.INTERVAL_ADDED);
|
||||
}
|
||||
|
||||
public void add(T parent, T child) {
|
||||
add(find(parent), wrap(child));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
package org.zkoss.ganttz.util;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.zkoss.zul.TreeModel;
|
||||
import org.zkoss.zul.event.TreeDataEvent;
|
||||
import org.zkoss.zul.event.TreeDataListener;
|
||||
|
||||
/**
|
||||
* @author Óscar González Fernández <ogonzalez@igalia.com>
|
||||
*/
|
||||
public class MutableTreeModelTest {
|
||||
|
||||
public static class Prueba {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void aMutableTreeModelIsAZkTreeModel() {
|
||||
assertTrue(TreeModel.class.isAssignableFrom(MutableTreeModel.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void aMutableTreeModelCanBeCreatedPassingType() {
|
||||
MutableTreeModel<Prueba> model = MutableTreeModel.create(Prueba.class);
|
||||
assertNotNull(model);
|
||||
assertNull(model.getRoot());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void aMutableTreeModelCanBeCreatedPassingTypeAndRootObject() {
|
||||
Prueba root = new Prueba();
|
||||
MutableTreeModel<Prueba> model = MutableTreeModel.create(Prueba.class,
|
||||
root);
|
||||
assertNotNull(model);
|
||||
assertThat(model.getRoot(), equalTo(root));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void childrenCanBeAdded() {
|
||||
Prueba prueba = new Prueba();
|
||||
MutableTreeModel<Prueba> model = MutableTreeModel.create(Prueba.class,
|
||||
prueba);
|
||||
Prueba other = new Prueba();
|
||||
model.add(model.getRoot(), other);
|
||||
Prueba otherChild = new Prueba();
|
||||
model.addToRoot(otherChild);
|
||||
assertThat(model.getChildCount(model.getRoot()), equalTo(2));
|
||||
assertThat(model.getChild(model.getRoot(), 0), equalTo(other));
|
||||
assertThat(model.getChild(model.getRoot(), 1), equalTo(otherChild));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLeaf() {
|
||||
Prueba root = new Prueba();
|
||||
MutableTreeModel<Prueba> model = MutableTreeModel.create(Prueba.class,
|
||||
root);
|
||||
Prueba other = new Prueba();
|
||||
model.add(model.getRoot(), other);
|
||||
assertTrue(model.isLeaf(other));
|
||||
assertFalse(model.isLeaf(root));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void childAddedCanBeFoundUsingGetPath() {
|
||||
Prueba root = new Prueba();
|
||||
MutableTreeModel<Prueba> model = MutableTreeModel.create(Prueba.class,
|
||||
root);
|
||||
Prueba child = new Prueba();
|
||||
model.add(root, child);
|
||||
int[] path = model.getPath(model.getRoot(), child);
|
||||
assertThat(path.length, equalTo(1));
|
||||
assertThat(path[0], equalTo(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addingTriggersEvent() {
|
||||
MutableTreeModel<Prueba> model = MutableTreeModel.create(Prueba.class);
|
||||
final ArrayList<TreeDataEvent> eventsFired = new ArrayList<TreeDataEvent>();
|
||||
model.addTreeDataListener(new TreeDataListener() {
|
||||
|
||||
@Override
|
||||
public void onChange(TreeDataEvent event) {
|
||||
eventsFired.add(event);
|
||||
}
|
||||
});
|
||||
Prueba child1 = new Prueba();
|
||||
Prueba child2 = new Prueba();
|
||||
Prueba granChildren1 = new Prueba();
|
||||
model.add(model.getRoot(), child1);
|
||||
checkIsValid(getLast(eventsFired), model.getRoot(), 0);
|
||||
model.add(model.getRoot(), child2);
|
||||
checkIsValid(getLast(eventsFired), model.getRoot(), 1);
|
||||
model.add(child1, granChildren1);
|
||||
checkIsValid(getLast(eventsFired), child1, 0);
|
||||
assertThat(eventsFired.size(), equalTo(3));
|
||||
}
|
||||
|
||||
private void checkIsValid(TreeDataEvent event, Prueba expectedParent,
|
||||
int expectedPosition) {
|
||||
assertEquals(expectedParent, event.getParent());
|
||||
assertThat(event.getIndexFrom(), equalTo(expectedPosition));
|
||||
assertThat(event.getIndexTo(), equalTo(expectedPosition));
|
||||
assertThat(event.getType(), equalTo(TreeDataEvent.INTERVAL_ADDED));
|
||||
}
|
||||
|
||||
private TreeDataEvent getLast(List<TreeDataEvent> list) {
|
||||
return list.get(list.size() - 1);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue