package org.korsakow.ide.ui.components.tree;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import javax.swing.tree.TreePath;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import com.sun.swingx.treetable.DefaultMutableTreeTableNode;
import com.sun.swingx.treetable.MutableTreeTableNode;
public class KNode extends DefaultMutableTreeTableNode implements Iterable<KNode>
{
public static void visitDepthFirstLeafFirst(KNode node, NodeVisitor visitor) {
// copy the list to allow modifications by the visitor
Collection<KNode> children = new ArrayList<KNode>(node.getChildren());
for (KNode child : children) {
visitDepthFirstLeafFirst(child, visitor);
}
visitor.visit(node);
}
private String name;
public KNode(String name)
{
setName(name);
}
public void setName(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
public void add(KNode child)
{
// resolve ambiguous call
super.add((MutableTreeTableNode)child);
}
public void remove(KNode child)
{
// resolve ambiguous call
super.remove((MutableTreeTableNode)child);
}
public List<String> getNamePath()
{
List<String> names = new ArrayList<String>();
KNode node = this;
while (node != null) {
names.add(0, node.getName());
node = node.getParent();
}
return names;
}
@Override
public KNode getParent()
{
return (KNode)super.getParent();
}
// public TreePath getTreePath()
// {
// return new TreePath(getPath());
// }
public void setChildIndex(int index, KNode child)
{
if (child.getParent() != this)
throw new IllegalArgumentException("not of parent of child");
int oldIndex = getIndex(child);
if (index > oldIndex) {
--index;
}
children.remove(oldIndex);
children.add(index, child);
}
public Collection<KNode> getChildren()
{
return new NodeChildListAdapter<KNode>(this);
}
@Override
public KNode getChildAt(int index)
{
return (KNode)super.getChildAt(index);
}
public KNode getChild(String name)
{
if (children == null)
return null;
for (Object child : children) {
KNode node = (KNode)child;
if (node.getName().equals(name))
return node;
}
return null;
}
public boolean isNodeDescendant(KNode node)
{
// compromise of sorts between breadth and depth first
for (Object child : children) {
if (child == node)
return true;
}
for (Object child : children) {
if (((KNode)child).isNodeDescendant(node))
return true;
}
return false;
}
public TreePath getTreePath()
{
List<KNode> elms = new ArrayList<KNode>();
KNode node = this;
while (node != null) {
elms.add(node);
node = node.getParent();
}
Collections.reverse(elms);
TreePath path = new TreePath(elms.toArray());
return path;
}
@Override
public int getColumnCount() {
return Integer.MAX_VALUE;
}
@Override
public Object getValueAt(int column)
{
return this;
}
@Override
public void setValueAt(Object value, int column)
{
setName(value!=null?value.toString():null);
}
public Iterator<KNode> iterator()
{
return new ChildIterator();
}
private class ChildIterator implements Iterator<KNode>
{
private int index = 0;
public boolean hasNext() {
return index < getChildCount();
}
public KNode next() {
return getChildAt(index++);
}
public void remove() {
throw new IllegalArgumentException();
}
}
public Element toDomElement(Document doc)
{
throw new IllegalArgumentException("KNode has no default XML representation");
}
}