jTree Dinâmica

Então irmão,

consegui acertar a parada aqui, porém o código ficou meio sujo, queria ver se consigo melhorar para deixar mais dinâmico, e com mais possibilidades de níveis, segue a Classe CategoriasTreeModel com as alterações feitas, porém está meio tosco o negócio, to tentando bolar um jeito de melhorar, se tiver alguma dica agradeço, eu criei um método getPai para quando um filho possuir um pai passar o path completo para o fireLastPathComponentInserted (vide método adicionarAutor), to pensando em adicionar um campo path na classe das categorias e na classe itens, dessa forma teria em cada classe qual o seu path completo podendo assim fazer os tratamentos necessários.


package treeSample;

import java.util.ArrayList;
import java.util.List;

public class CategoriaTreeModel extends AbstractTreeModel {
	// Raiz da nossa árvore, vamos exibir uma lista de livros.
	private List<Categorias> categorias;
        private String fakeRoot = "Categorias";

	public CategoriaTreeModel(List<Categorias> categorias) {
		this.categorias = categorias;
	}

	/**
	 * Com esse método, o Java quem é o objeto que está num determinado índice
	 * do pai. Cada nó de uma árvore pode ser encarado como uma lista. Sendo o
	 * pai a lista e o índice um dos filhos.
	 *
	 * @param parent
	 *            É o pai, que tem os filhos. No caso do Livro, o próprio livro.
	 * @param index
	 *            Índice do filho. No caso do livro, o índice corresponde aos
	 *            autores.
	 */
        @Override
	public Object getChild(Object parent, int index) {
                
		if (parent == fakeRoot) // É o nó principal?
			return categorias.get(index); // Pegamos da lista de livro

		if (parent instanceof Categorias) // O pai é uma categoria?
		{
			//List<Categorias> cat = categorias;
			if (index < ((Categorias) parent).getNumSubCategorias()) {
				return ((Categorias) parent).getSubCategorias().get(index);
			}  
                        
                            return ((Categorias) parent).getItens().get(index - ((Categorias) parent).getNumSubCategorias()); // Se não lista os itens(filhos)
               }
            return null;
	}

	/**
	 * Retornamos quantos filhos um pai tem. No caso de um livro, é a contagem
	 * de autores. No caso da lista de livros, é a quantidade de livros.
	 */
        @Override
	public int getChildCount(Object parent) {
		// Mesma lógica.
		if (parent == fakeRoot)
			return categorias.size();

		if (parent instanceof Categorias) {
			Categorias cat = (Categorias) parent;
			return cat.getSubCategorias().size() + cat.getItens().size();
		}
            return 0;
	}

	/**
	 * Dado um pai, indicamos qual é o índice do filho correspondente.
	 */
	public int getIndexOfChild(Object parent, Object child) {
		if (parent == fakeRoot)
			return categorias.indexOf(child);
		if (parent instanceof Categorias) {
			if (child instanceof Categorias)
			     return ((Categorias) parent).getSubCategorias().indexOf(child);
			return ((Categorias) parent).getSubCategorias().size() + 
			     ((Categorias) parent).getItens().indexOf(child);
		}

		return 0;
	}

	/**
	 * Devemos retornar quem é o nó raiz da árvore. Afinal, a árvore tem que
	 * começar em algum lugar.
	 */
	public Object getRoot() {
		return fakeRoot;
	}

	/**
	 * Indicamos se um nó é ou não uma folha. Isso é, se ele não tem filhos. No
	 * nosso caso, os autores são as folhas da árvore.
	 */
	public boolean isLeaf(Object node) {

                return node instanceof Itens;
	}
        
        public void adicionarLivro(Categorias livro)
        {
            categorias.add(livro);
            fireLastPathComponentInserted(fakeRoot, livro);
        }

        public void adicionarSubLivro(Categorias livroPai, Categorias livro)
        {
            for (int i = 0; i < categorias.size(); i++)
            {
                if (categorias.get(i).getNome().equals(livroPai.getNome()))
                {
                    livro.setPai(livroPai.getNome());
                    categorias.get(i).addSubCategoria(livro);
                }
            }
            
            //livros.get(livroPai.get).addSubCategoria(livro);
            
            fireLastPathComponentInserted(fakeRoot, livroPai, livro);
        }        
        
        public void adicionarAutor(Categorias livro, Itens autor)
        {
            livro.addItem(autor);
            if(livro.getPai() != null)
            {
                fireLastPathComponentInserted(fakeRoot,getPai(livro),livro, autor); 
            }else
            fireLastPathComponentInserted(fakeRoot,livro, autor);
        }
public Categorias getPai(Categorias filho){
    for (int i = 0; i < categorias.size(); i++)
    {
        if (categorias.get(i).getNome() == filho.getPai())
            return categorias.get(i);
    }
    
    return null;
}
        public void removerLivro(Categorias livro)
        {
            if (categorias.remove(livro))
            {
                fireLastPathComponentRemoved(fakeRoot, livro);
            }
        }
}

Árvore é sempre o cão.[/quote]

Então irmão depois de umas noites sem dormir e uns dias a fio, consegui funcionar sem limite de níveis, afemaria… que trampo rsss pq que um abençoado não disponibiliza uma classe dessas para facilitar a vida… da uma olhada como ficou a minha CategoriaTreeModel :

package treeSample;

import java.util.ArrayList;
import java.util.List;
import javax.swing.tree.TreePath;

public class CategoriaTreeModel extends AbstractTreeModel {
	// Raiz da nossa árvore, vamos exibir uma lista de livros.
	private List&lt;Categorias&gt; categorias;
        private Categorias fakeRoot = new Categorias("Raiz Categorias");
        
        
	public CategoriaTreeModel(List&lt;Categorias&gt; categorias) {
	    this.categorias = categorias;
            
            //Se a categoria é vazia(adiciona a raiz nela)
            if (categorias.isEmpty())
            {
                categorias.add(fakeRoot);
            }
	}

	/**
	 * Com esse método, o Java quem é o objeto que está num determinado índice
	 * do pai. Cada nó de uma árvore pode ser encarado como uma lista. Sendo o
	 * pai a lista e o índice um dos filhos.
	 *
	 * @param parent
	 *            É o pai, que tem os filhos. No caso do Livro, o próprio livro.
	 * @param index
	 *            Índice do filho. No caso do livro, o índice corresponde aos
	 *            autores.
	 */
        @Override
	public Object getChild(Object parent, int index) {
                
//		if (parent == fakeRoot) // É o nó principal?
//			return categorias.get(index); // Pegamos da lista de livro

		if (parent instanceof Categorias) // O pai é uma categoria?
		{
			//List&lt;Categorias&gt; cat = categorias;
			if (index &lt; ((Categorias) parent).getSubCategorias().size()) {
				return ((Categorias) parent).getSubCategorias().get(index);
			}  
                        
                            return ((Categorias) parent).getItens().get(index - ((Categorias) parent).getSubCategorias().size()); // Se não lista os itens(filhos)
               }
            return null;
	}

	/**
	 * Retornamos quantos filhos um pai tem. No caso de um livro, é a contagem
	 * de autores. No caso da lista de livros, é a quantidade de livros.
	 */
        @Override
	public int getChildCount(Object parent) {
		// Mesma lógica.
//		if (parent == fakeRoot)
//			return categorias.size();

		if (parent instanceof Categorias) {
			Categorias cat = (Categorias) parent;
			return cat.getSubCategorias().size() + cat.getItens().size();
		}
            return 0;
	}

	/**
	 * Dado um pai, indicamos qual é o índice do filho correspondente.
	 */
        @Override
	public int getIndexOfChild(Object parent, Object child) {
		//if (parent == fakeRoot)
		//	return categorias.indexOf(child);
		if (parent instanceof Categorias) {
			if (child instanceof Categorias)
			     return ((Categorias) parent).getSubCategorias().indexOf(child);
                        
			return ((Categorias) parent).getSubCategorias().size() + ((Categorias) parent).getItens().indexOf(child);
		}

		return 0;
	}

	/**
	 * Devemos retornar quem é o nó raiz da árvore. Afinal, a árvore tem que
	 * começar em algum lugar.
	 */
        @Override
	public Object getRoot() {
		return fakeRoot;
	}

	/**
	 * Indicamos se um nó é ou não uma folha. Isso é, se ele não tem filhos. No
	 * nosso caso, os autores são as folhas da árvore.
	 */
        @Override
	public boolean isLeaf(Object node) {

                return node instanceof Itens;
	}
        
        public void adicionarLivro(Categorias livro)
        {
            categorias.add(livro);
            fireLastPathComponentInserted(fakeRoot, livro);
        }

        public void adicionarCategoria(Categorias _categSelecionada, Categorias _categoria)
        {
            
            Categorias categAdd = percorreCategorias(categorias, _categSelecionada);
            categAdd.addSubCategoria(_categoria);
            
            //monta o caminho para exibição do treeview
            fireLastPathComponentInserted(montaPath(_categoria, null));
        }        
        
        //Percorre recursivamente o ArrayList Categorias
        //retornando a classe selecionada
        public Categorias percorreCategorias(List&lt;Categorias&gt; arrCategorias, Categorias livroSelecionado)
        {
            Categorias retorno = null;
            //Percorre o arraylist para adicionar as novas categorias
            for (int i = 0; i &lt; arrCategorias.size(); i++)
            {
                if (arrCategorias.get(i) == livroSelecionado)
                {
                        retorno = arrCategorias.get(i);
                        if(retorno != null)
                        {
                            return retorno;
                        }                        
                }else{

                    if(arrCategorias.get(i).getSubCategorias().size() &gt; 0)
                    {
                        retorno = percorreSubCategorias(arrCategorias.get(i), livroSelecionado);
                        if(retorno != null)
                        {
                            return retorno;
                        }                        
                    }
                }
            } 
            return retorno;
        }
        
        //Metodo para percorrer recursivamente as subcategorias do ArrayList categorias 
        //para adicionar as novas categorias no Array
        public Categorias percorreSubCategorias(Categorias categI, Categorias livroSelecionado)
        {
            Categorias retorno;
            for (int i = 0; i &lt; categI.getSubCategorias().size(); i++)
            {
                if (categI.getSubCategorias().get(i) == livroSelecionado)
                {
                        retorno = categI.getSubCategorias().get(i);
                        if(retorno != null)
                        {
                            return retorno;
                        }
                }else{

                    if(categI.getSubCategorias().get(i).getSubCategorias().size() &gt; 0)
                    {
                        retorno = percorreSubCategorias(categI.getSubCategorias().get(i), livroSelecionado);
                        if(retorno != null)
                        {
                            return retorno;
                        }                        
                    }
                }
            }
            return null;
        }
        
        public void adicionarItem(Categorias _categorias, Itens _item)
        {
            _categorias.addItem(_item);
            fireLastPathComponentInserted((Object[])montaPath(null, _item));
        }
        
        public void remover( Object itemSelecionado)
        {
            if(itemSelecionado instanceof Categorias)
            {
                //Monta o Path para notificar a exclusão do nó
                Object[] objPath = montaPath((Categorias)itemSelecionado, null);
                TreePath path =  new TreePath(objPath);
                Object parent = path.getParentPath().getLastPathComponent();
                
                //Notifica a exclusão do nó
                fireLastPathComponentRemoved(objPath);
                
                //Retorna a classe do pai do objeto selecionado
                //para excluir o objeto selecionado
                Categorias teste = percorreCategorias(categorias, (Categorias)parent);
                //teste.getSubCategorias().remove((Categorias)itemSelecionado);
                teste.removeSubCategoria((Categorias)itemSelecionado);

            }
            
            if(itemSelecionado instanceof Itens)
            {
                //Monta o Path para notificar a exclusão do nó
                Object[] objPath = montaPath(null, (Itens)itemSelecionado);
                TreePath path =  new TreePath(objPath);
                Object parent = path.getParentPath().getLastPathComponent();
                
                //Notifica a exclusão do nó
                fireLastPathComponentRemoved(objPath);
                
                //Retorna a classe do pai do objeto selecionado
                //para excluir o objeto selecionado
                Categorias teste = percorreCategorias(categorias, (Categorias)parent);
                //teste.getSubCategorias().remove((Categorias)itemSelecionado);
                teste.removeItens((Itens)itemSelecionado);

            }            

        }

        
        //Método para percorrer o ArrayList categorias para montar o Path do menu selecionado
        //public Object[] montaPath(Object sel)
        public Object[] montaPath(Categorias _categoriaProcurada, Itens _item)
        {
            Object[] retorno = new Object[0];
            
            if(_categoriaProcurada != null)
            {
                for(Categorias categs : categorias)
                {
                    if(categs.getSubCategorias().size() &gt; 0)
                    {
                        List&lt;Categorias&gt; arrVarreSub = (List&lt;Categorias&gt;) varreSub(categs, _categoriaProcurada, null);
                        if (arrVarreSub != null)
                        {

                            for(Categorias retVarre : arrVarreSub)
                            {
                                int ictrl = retorno.length;
                                retorno = (Object[]) resizeArray(retorno, retorno.length + 1);
                                retorno[ictrl] = retVarre;                               
                            }

                            return retorno;
                        }
                    }
                }
            }
            
            if(_item != null){
                
                for(Categorias categs : categorias)
                {
                    //Percorre os itens na raiz
                    for(Itens item : categs.getItens())
                    {
                        //Se o item for igual 
                        if(item == _item)
                        {
                            retorno = (Object[]) resizeArray(retorno, retorno.length + 1);
                            retorno[retorno.length - 1] = categs;       
                            
                            retorno = (Object[]) resizeArray(retorno, retorno.length + 1);
                            retorno[retorno.length -1] = item;
                            return retorno;
                        }
                        
                    }
                    if(categs.getSubCategorias().size() &gt; 0)
                    {
                        List&lt;Object&gt; arrVarreSub = (List&lt;Object&gt;) varreSub(categs, null, _item);
                        if (arrVarreSub != null)
                        {
                            for(Object obj : arrVarreSub)
                            {
                                retorno = (Object[]) resizeArray(retorno, retorno.length + 1);
                                retorno[retorno.length -1] = obj;                       
                            }
                            return retorno;
                        }
                    }
                }
                
            }
        return null;
        }
        
        public Object retornaPath(Object teste)
        {
            return new TreePath(teste);
        }
        
        public Object varreItens(Categorias _categorias, Itens _itemSel)
        {
            for(Itens itens : _categorias.getItens())
            {
                if (itens == _itemSel)
                {
                    return itens;
                }
                
            }
            
            return null;
        }
        
        public Object varreSub(Categorias _categorias, Object _categSel, Itens _itemSel)
        {
            List&lt;Object&gt; retorno = new ArrayList();

                retorno.add(_categorias);


                for (Categorias categs : _categorias.getSubCategorias())
                {
                    retorno.add(categs);
                    
                    for(Itens _item : categs.getItens())
                    {
                        if(_item == _itemSel)
                        {
                            retorno.add(_item);
                            return retorno; 
                        }
                    }
                    retorno.remove(categs);
                    
                    if(categs == _categSel)
                    {
                        retorno.add(categs);
                        return retorno;
                    }

                    if(categs.getSubCategorias().size() &gt; 0)
                    {
                        for (Categorias _categs : categs.getSubCategorias())
                        {
                            retorno.add(categs);

                            for(Itens _item : _categs.getItens())
                            {
                                retorno.add(_categs);
                                if(_item == _itemSel)
                                {
                                    retorno.add(_item);
                                    return retorno; 
                                }
                                retorno.remove(_categs);
                            }                            

                            if(_categs == _categSel)
                            {
                                retorno.add(_categs);
                                return retorno;
                            }

                            if(_categs.getSubCategorias().size() &gt; 0)
                            {
                                List&lt;Object&gt; arrVarreSub = (List&lt;Object&gt;) varreSub(_categs, (Categorias) _categSel, _itemSel);
                                if (arrVarreSub != null)
                                {
                                    for(Object retVarre : arrVarreSub)
                                    {
                                       retorno.add(retVarre);
                                    }
                                    return retorno;
                                }
                            }

                            retorno.remove(categs);
                        }
                    }
                }
                return null;
            }

        //Percorre as subcategorias da tree recursivamente
        public Object varreSubCateg(Categorias categ, Categorias categSel)
        {
            List&lt;Object&gt; retorno = new ArrayList();
            
            for(Categorias categs : categ.getSubCategorias())
            {
                if(categs == categSel)
                {
                    retorno.add(categ);
                    retorno.add(categs);
                    return retorno;
                }
                
                if(categs.getSubCategorias().size() &gt; 0)
                {
                    List&lt;Categorias&gt; arrVarreSub = (List&lt;Categorias&gt;) varreSubCateg(categs, (Categorias) categSel);
                    if (arrVarreSub != null)
                    {
                        retorno.add(categ);
                        for(Categorias retVarre : arrVarreSub)
                        {
                           retorno.add(retVarre);
                        }
                        return retorno;
                    }
                }
            }           
            return null;
        }
        
        private static Object resizeArray (Object oldArray, int newSize) {
            int oldSize = java.lang.reflect.Array.getLength(oldArray);
            Class elementType = oldArray.getClass().getComponentType();
            Object newArray = java.lang.reflect.Array.newInstance(elementType, newSize);
            int preserveLength = Math.min(oldSize, newSize);
            if (preserveLength &gt; 0)
               System.arraycopy(oldArray, 0, newArray, 0, preserveLength);
            return newArray; 
        }
}