/*******************************************************************************
gocha.org-lib-java Библеотека общего назначения
(с) Камнев Георгий Павлович 2009 GPLv2
Данная программа является свободным программным обеспечением. Вы вправе
распространять ее и/или модифицировать в соответствии с условиями версии 2
либо по вашему выбору с условиями более поздней версии
Стандартной Общественной Лицензии GNU, опубликованной Free Software Foundation.
Мы распространяем данную программу в надежде на то, что она будет вам полезной,
однако НЕ ПРЕДОСТАВЛЯЕМ НА НЕЕ НИКАКИХ ГАРАНТИЙ,
в том числе ГАРАНТИИ ТОВАРНОГО СОСТОЯНИЯ ПРИ ПРОДАЖЕ
и ПРИГОДНОСТИ ДЛЯ ИСПОЛЬЗОВАНИЯ В КОНКРЕТНЫХ ЦЕЛЯХ.
Для получения более подробной информации ознакомьтесь
со Стандартной Общественной Лицензией GNU.
Вместе с данной программой вы должны были получить экземпляр
Стандартной Общественной Лицензии GNU.
Если вы его не получили, сообщите об этом в Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*******************************************************************************/
package org.gocha.gui;
import java.util.Collection;
import java.util.HashSet;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
import org.gocha.collection.Convertor;
import org.gocha.collection.Iterators;
import org.gocha.collection.NodesExtracter;
/**
* @author gocha
*/
public class TreeAdaptiveModel implements TreeModel
{
protected Object rootObject = null;
protected Convertor nodeWrapper = null;
protected Convertor reverseNodeWrapper = null;
protected NodesExtracter nodesExtracter = null;
public TreeAdaptiveModel(Object root, NodesExtracter nodesExtracter)
{
setRootObject(root);
setNodesExtracter(nodesExtracter);
}
public TreeAdaptiveModel(Object root, NodesExtracter nodesExtracter, Convertor wrapper, Convertor unwrapper)
{
setRootObject(root);
setNodesExtracter(nodesExtracter);
setNodeWrapper(wrapper);
setReverseNodeWrapper(unwrapper);
}
public NodesExtracter getNodesExtracter()
{
return nodesExtracter;
}
public void setNodesExtracter(NodesExtracter nodesExtracter)
{
this.nodesExtracter = nodesExtracter;
}
public Convertor getReverseNodeWrapper()
{
return reverseNodeWrapper;
}
public void setReverseNodeWrapper(Convertor reverseNodeWrapper)
{
this.reverseNodeWrapper = reverseNodeWrapper;
}
public Convertor getNodeWrapper()
{
return nodeWrapper;
}
public void setNodeWrapper(Convertor nodeWrapper)
{
this.nodeWrapper = nodeWrapper;
}
public Object getRootObject()
{
return rootObject;
}
public void setRootObject(Object rootObject)
{
this.rootObject = rootObject;
}
@Override
public Object getRoot()
{
Object obj = getRootObject();
Convertor nWrap = getNodeWrapper();
if( nWrap!=null )
return nWrap.convert(obj);
return obj;
}
protected Object getDefaultChild(){ return null; }
@Override
public Object getChild(Object parent, int index)
{
if( nodesExtracter==null )
return getDefaultChild();
Object unwrapped = parent;
if( reverseNodeWrapper!=null )
unwrapped = reverseNodeWrapper.convert(parent);
Iterable itr = nodesExtracter.extract(unwrapped);
int idx = -1;
Object result = getDefaultChild();
for( Object o : itr )
{
idx++;
if( idx==index )
{
result = o;
}
}
if( nodeWrapper!=null )
result = nodeWrapper.convert(result);
return result;
}
@Override
public int getChildCount(Object parent)
{
if( nodesExtracter==null )
return 0;
Iterable itr = nodesExtracter.extract(parent);
return (int)Iterators.count(itr);
}
@Override
public boolean isLeaf(Object node)
{
int co = getChildCount(node);
return co==0;
}
@Override
public void valueForPathChanged(TreePath path, Object newValue)
{
// throw new UnsupportedOperationException("Not supported yet.");
}
protected int getDefaultChildIndex(){ return -1; }
protected boolean equalsNodes(Object node1,Object node2)
{
return node1 == node2;
}
@Override
public int getIndexOfChild(Object parent, Object child)
{
if( nodesExtracter==null )
return getDefaultChildIndex();
Object unwrappedParent = parent;
if( reverseNodeWrapper!=null )
unwrappedParent = reverseNodeWrapper.convert(unwrappedParent);
Object unwrappedChild = child;
if( reverseNodeWrapper!=null )
unwrappedChild = reverseNodeWrapper.convert(unwrappedChild);
Iterable itr = nodesExtracter.extract(unwrappedParent);
int idx = -1;
for( Object o : itr )
{
idx++;
if( equalsNodes(o, unwrappedChild) )
{
return idx;
}
}
return getDefaultChildIndex();
}
private Collection<TreeModelListener> listeners = null;
public Collection<TreeModelListener> getListeners()
{
if( listeners==null )
listeners = new HashSet<TreeModelListener>();
return listeners;
}
@Override
public void addTreeModelListener(TreeModelListener l)
{
if( l!=null )
getListeners().add(l);
}
@Override
public void removeTreeModelListener(TreeModelListener l)
{
getListeners().remove(l);
}
public void fireStructureChanged()
{
Object root = getRoot();
TreeModelEvent event = new TreeModelEvent(root, new Object[]{root});
fireTreeModelEvent(event, true, false, false, false);
}
public void fireTreeModelEvent(
TreeModelEvent event,
boolean structureChanged,
boolean nodesChanged,
boolean nodesInserted,
boolean nodesRemoved)
{
for( TreeModelListener l : getListeners().toArray(new TreeModelListener[]{}) )
{
if( l==null )continue;
if( structureChanged )l.treeStructureChanged(event);
if( nodesChanged )l.treeNodesChanged(event);
if( nodesInserted )l.treeNodesInserted(event);
if( nodesRemoved )l.treeNodesRemoved(event);
}
}
}