Selecionar nó na jTree correspondente ao nome pesquisado

Não consegui selecionar o nó por meio do nome digitado. Seria uma consulta em que ele procuraria por título(nós filhos) ou grupo(nó pai) e selecionaria o nó que contém o nome digitado, caso houvesse.
Exemplo de nó:

Grupo1
Título1
Título2
Grupo2
Título1
Título2

Oi,

Não sei se é bem isso que você está procurando, porém lá vai:

[code]// Armazena o path inteiro de sua tree
final TreePath lo_path = e.getNewLeadSelectionPath();

if (lo_path != null) {

 // Armazena o grupo selecionado na tree.
 Object lo_selection = ((DefaultMutableTreeNode)lo_path.getPathComponent(lo_path.getPathCount()-1)).getUserObject();

 // Armazena os nós deste grupo.
 Object[] lo_no_path = ((DefaultMutableTreeNode)lo_path.getPathComponent(lo_path.getPathCount()-1)).getPath();

 // Se foi selecionado o grupo1
 if	(lo_selection instanceof Grupo1Node) {

      for (int i = 0; i < lo_no_path.legth(); i++) {
           System.out.println("Nó selecionado foi: "+lo_no_path[i]);
      }

 }

}

private class Grupo1Node
{
private String ls_nome;

public Grupo1Node(String as_name	) {
     ls_nome = as_name;
}
	
    public String toString() {
     return ls_nome;
}

}[/code]

Tchauzin!

Vou testar.

Oi,

Esqueci de dizer de onde peguei esse “e.getNewLeadSelectionPath()…” da linha 2.

Foi pq adicionei a minha tree um evento de seleção:

minha_tree.addTreeSelectionListener ( new TreeSelectionListener() { public void valueChanged(TreeSelectionEvent e) { // Colocar o código do meu primeiro post aqui! } } );

Tchauzin!

Certo. Eu percebi esse erro e ia postar. Outra coisa, eu não quero selecionar o nó pelo clique do mouse. Eu quero digitar no jTextField o título ou grupo cadastrado e depois que clicar no botão para procurar, ele procura pelo nome digitado. Se eu digitar só a inicial, ele vai para a primeira ocorrência que corresponde à inicial. Parece que isso é com o .contains(txtDescricao.getText()). Ou pode ser pelo nome todo mesmo. Ao digitar para procurar e depois clicar no botão para procurar, ele seleciona o nó refeente ao nome que digitei.

Não está funcionando. Eu queria consultar pelo nó digitado. Ele ia procurar o nó pai e filhos que tem esse nome e se achar ele seleciona. Eu estava tentando criar um código sem pesquisar na internet mesmo. Eu consegui por parte apenas. Vou postar abaixo.


//            Verifica se existe o nó com o nome especificado
        for (int row = 1; row <= jTree1.getRowCount(); row++) {
            if (jTree1.getPathForRow(row).toString().substring(9).replace("]", "").equals(txtDescricao.getText().trim())) {

//             Seleciona o nó com base no índice caso encontre o nó especificado
                jTree1.setSelectionRow(row);
                lblMensagem.setText("Encontrado: " + jTree1.getPathForRow(row).toString().substring(9).replace("]", ""));

            } else {
                lblMensagem.setText("Não encontrado");
            }
          
        }

Só esse loop que deve estar com problema, porque percebi que tem índices que não tem número deles no especificado. O problema também e que jTree1.getRowCount() não deve estar dando certo porque, no meu exemplo, ele retorna 5 no total, mas tem índices com 7 e 9. Ele teria que percorrer pelos índices corretos. Esse código esta dando erro.

[resolvido]
Achei a solução. Segue o código abaixo. É muito simples e funciona bem. Testei várias vezes, só mais algumas correções. Coloquei também o código para expandir os nós quando achar algum que corresponda com prefixo indicado.

   private void txtDescricaoKeyReleased(java.awt.event.KeyEvent evt) {   
                                      
// Procura para frente o primeiro nó visível que começa com o prefixo
        // somente o nome que inicia com o prefixo
        int startRow = 0; String prefix = txtDescricao.getText().trim();
        TreePath path = jTree1.getNextMatch(prefix, startRow, Position.Bias.Forward);
        jTree1.expandPath(path);
        System.out.print(path);
        jTree1.setSelectionRow(jTree1.getRowForPath(path));

}      

Estou com problemas ainda com isso. O código que postei é para procurar pela primeira ocorrência do nome na jTree, mas o cliente(usuário) quer char exatamente o nome, sem precisar ficar procurando pela primeira ocorrência. Exemplo do problema encontrado: Tenho os 2 nós pai: Grupo e Grupo2. Se clicar na jTable na linha do Grupo2, vai para a primeira ocorrência, que é Grupo, mas deveria ser Grupo2, exatamente. Os títulos está acontecendo a mesma coisa. Tem que buscar exatamente. Não vi ninguém ainda que conseguiu fazer a busca na Jtree pelo nome extado digitado.

Oi,

Nunca usei esse componente para buscar um node digitado pelo usuário… Porém a idéia é percorrer a arvore, encontrar o nó e expandi-la até o nó encontrado.

De uma olhada:

http://www.guj.com.br/posts/list/213736.java

Tchauzin!

Já tentei esse código aí mas não deu certo. Ei, eu tenho uma idéia de como fazer. estou tentando resolver. Usando o mesmo código acima. eu sei que digitando ele procura sim exatamente, mas o usuário vai cansar de digitar a palavra toda só para achar. Tenho que usar um loop para verificar se o nó que ele selecionar com o Position.Bias, usando jTree1.getLastSelectedPathComponent().equals(txtConsulta.getText().trim()) . Se for igual, ele então encerra o loop. estava fazendo com o while e dá loop infinito. Vou fazer outros testes aqui.

Minha classe modelo do jTree. Usei o mesmo padrão do Vini Godoy. Nome da classe: GrupoTreeModel

package Classes;

import java.util.ArrayList;
import java.util.List;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;

public class GrupoTreeModel implements TreeModel {
        //Criamos um objeto para nossa raiz. O List não pode ser usado diretamente pois
        //seu hash irá mudar sempre que um novo livro for adicionado.
        //Fora que fica mais bonitinho escrever "Grupos" no topo.
        private String raiz = "Grupos";

	// Escrevam depois AbstractTreeModel para lidar com os listeners.
	private List<TreeModelListener> listeners = new ArrayList<TreeModelListener>();

	// Raiz da nossa árvore, vamos exibir uma lista de grupos.
	private List<Grupos> grupos;

	public GrupoTreeModel(List<Grupos> grupos) {
		this.grupos = grupos;
	}

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

		if (parent instanceof Grupos) // O pai &#65533; um grupo?
		{
			// Devolvemos um título do info
			return ((Grupos) parent).getTitulos().get(index);
		}

		// Se o pai n&#65533;o &#65533; nenhum desses. Melhor dar erro.
		throw new IllegalArgumentException("Invalid parent class"
				+ parent.getClass().getSimpleName());
	}

	/**
	 * Retornamos quantos filhos um pai tem. No caso de um livro, &#65533; a contagem
	 * de autores. No caso da lista de grupos, &#65533; a quantidade de grupos.
	 */
	public int getChildCount(Object parent) {
		// Mesma l&#65533;gica.
		if (parent == raiz)
			return grupos.size();

		if (parent instanceof Grupos) // O pai &#65533; um livro?
			return ((Grupos) parent).getTitulos().size();

		// Se o pai n&#65533;o &#65533; nenhum desses. Melhor dar erro.
		throw new IllegalArgumentException("Invalid parent class"
				+ parent.getClass().getSimpleName());
	}

	/**
	 * Dado um pai, indicamos qual &#65533; o &#65533;ndice do filho correspondente.
	 */
	public int getIndexOfChild(Object parent, Object child) {
		if (parent == raiz)
			return grupos.indexOf(child);
		if (parent instanceof Grupos)
			return ((Grupos) parent).getTitulos().indexOf(child);

		return 0;
	}

	/**
	 * Devemos retornar quem &#65533; o n&#65533; raiz da &#65533;rvore. Afinal, a &#65533;rvore tem que
	 * come&#65533;ar em algum lugar.
	 */
	public Object getRoot() {
		return raiz;
	}

	/**
	 * Indicamos se um n&#65533; &#65533; ou n&#65533;o uma folha. Isso &#65533;, se ele n&#65533;o tem filhos. No
	 * nosso caso, os autores s&#65533;o as folhas da &#65533;rvore.
	 */
	public boolean isLeaf(Object node) {
		return node instanceof Info;
	}

	public void valueForPathChanged(TreePath path, Object newValue) {
		// Com esse m&#65533;todo, a tree avisa que um objeto mudou.
		// Editem se quiserem que um n&#65533; seja edit&#65533;vel
	}

	// Esses dois m&#65533;todos abaixo poderiam ir para classe abstrata
	public void removeTreeModelListener(TreeModelListener l) {
		listeners.remove(l);
	}

	public void addTreeModelListener(TreeModelListener l) {
		listeners.add(l);
	}
}

Classe Grupos

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package Classes;

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

/**
 *
 * @author MARK
 */
public class Grupos {
private int codigo;
private String grupo;
private List<Info> info = new ArrayList<Info>();
// Getters(pega um valor) e Setters(seta um valor)
    public int getCodigo() {
        return codigo;
    }

    public void setCodigo(int codigo) {
        this.codigo = codigo;
    }

    public String getGrupo() {
        return grupo;
    }

    public void setGrupo(String grupo) {
        this.grupo = grupo;
    }

      //===================================================
//construtor com os campos
    public Grupos(int codigo, String grupo) {
        this.codigo = codigo;
        this.grupo = grupo;
    }
/*Construtor com o campo para o array*/
    public Grupos(String grupo) {
        this.grupo = grupo;
    }

//Construtor vazio
    public Grupos() {
    }


    @Override
    public String toString() {
        return getGrupo();
    }

    //Adiciona o titulo ao array
    public void addTitulo(Info titulo) {
        info.add(titulo);
    }

    public List<Info> getTitulos() {
        return Collections.unmodifiableList(info);
    }

}

Classe Info

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Classes;

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

/**
 *
 * @author MARK
 */
public class Info extends Grupos {

    private int idInfo;
    private String titulo;
    private String descricao;
    private String gp;

    /*Construtor padrão da classe (código título, descrição)*/
    public Info(int idInfo, String titulo, String descricao) {
        this.idInfo = idInfo;
        this.titulo = titulo;
        this.descricao = descricao;
    }
    /* Construtor com o campo para o jTree*/

    public Info(String titulo) {
        this.titulo = titulo;
    }
    //Construtor para a consulta (grupo e título)

    public Info(String gp, String titulo, String descricao) {
        this.gp = gp;
        this.titulo = titulo;
        this.descricao = descricao;
    }

    //Construtor para a consulta (código,grupo,título e descrição da consultaInfo)
    public Info(int idInfo, String titulo, String descricao, String gp) {
        this.idInfo = idInfo;
        this.titulo = titulo;
        this.descricao = descricao;
        this.gp = gp;
    }

//construtor vazio
    public Info() {
    }

    //=========================================================
    //Getters e Setters
    public int getIdInfo() {
        return idInfo;
    }

    public void setIdInfo(int idInfo) {
        this.idInfo = idInfo;
    }

    public String getTitulo() {
        return titulo;
    }

    public void setTitulo(String titulo) {
        this.titulo = titulo;
    }

    public String getDescricao() {
        return descricao;
    }

    public void setDescricao(String descricao) {
        this.descricao = descricao;
    }

    public String getGp() {
        return gp;
    }

    public void setGp(String gp) {
        this.gp = gp;
    }

    //Sobescreve os métodos para o array
    @Override
    //Retorna o título
    public String toString() {
        return getTitulo();
    }
}

Para mostrar a jTree carregada com os dados.

 public void MostrajTree(String filtro) {
        banco = new DB();
        banco.connect();
        Query query1 = new Query(banco.conn);
        String sql1 = null;
        //Se tiver filtro
        if (filtro != null) {
            sql1 = "SELECT grupos.codigo,grupos.grupo,info.titulo "
                    + "FROM grupos,info "
                    + "WHERE grupos.codigo=info.grupos_codigo "
                    + "AND info.titulo='" + filtro + "'"
                    + "ORDER BY grupos.grupo,info.titulo";
        } //Mostra todos os nos
        else if (filtro == null) {
            sql1 = "SELECT grupos.codigo,grupos.grupo,info.titulo "
                    + "FROM grupos,info "
                    + "WHERE grupos.codigo=info.grupos_codigo "
                    + "ORDER BY grupos.grupo,info.titulo";
        }


        query1.open(sql1);

        String codgrupo = null, grup = null, titulo = null;

        List<Grupos> grupos = new ArrayList<Grupos>();
        //Variáveis para verificar se é o registro atual
        String strGrupoAtual = null, strTituloAtual = null;
        //Inicia o loop através dos registros
        while (query1.next()) {
            grup = query1.fieldbyname("grupo");
            codgrupo = query1.fieldbyname("codigo");
            titulo = query1.fieldbyname("titulo");
            //Verifica se o registro corresponde ao grupo atual para
            //evitar a duplicação de registros nos "nós" do jTree
            if (!codgrupo.equals(strGrupoAtual)) {
                //Cria um novo nó
                grupo = new Grupos(grup);
                //Atualiza a variável com o código do grupo atual
                strGrupoAtual = codgrupo;
            }
            //======================Títulos do grupo======================
            //Aqui inicia a criação dos "nós" que exibirão os titulos de
            //cada grupo. Tem que verificar qual é o titulo atual para
            //que não ocorra duplicidade de registros nos "nós" do jTree
            if (!titulo.equals(strTituloAtual)) {
                //Adiciona o "nó" do titulo para o grupo atual.
                grupo.addTitulo(new Info(titulo));
                //Atualiza a variável para indicar qual é o titulo atual.
                strTituloAtual = titulo;
            }
            //Adiciona os ítens ao array
            grupos.add(grupo);

        }

        //        //Seta o modelo
        jTree1.setModel(new GrupoTreeModel(grupos));
        banco.disconnect();
    }

uso no evento FrameActivated, porque tem um menu e ele e carregado logo dentro do menu na tela inicial, porque infelizmente JAVA não é igual Visual Basic que teudo é mais fácil e tem mais controles.