Selecionar nó na jTree correspondente ao nome pesquisado
11 respostas
M
marcosarantesj
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ó:
Não sei se é bem isso que você está procurando, porém lá vai:
// Armazena o path inteiro de sua treefinalTreePathlo_path=e.getNewLeadSelectionPath();if(lo_path!=null){// Armazena o grupo selecionado na tree.Objectlo_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 grupo1if(lo_selectioninstanceofGrupo1Node){for(inti=0;i<lo_no_path.legth();i++){System.out.println("Nó selecionado foi: "+lo_no_path[i]);}}}privateclassGrupo1Node{privateStringls_nome;publicGrupo1Node(Stringas_name){ls_nome=as_name;}publicStringtoString(){returnls_nome;}}
Tchauzin!
M
marcosarantesj
Vou testar.
L
lina
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!
M
marcosarantesj
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.
M
marcosarantesj
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 especificadofor(introw=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ó especificadojTree1.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.
M
marcosarantesj
[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.
privatevoidtxtDescricaoKeyReleased(java.awt.event.KeyEventevt){// Procura para frente o primeiro nó visível que começa com o prefixo// somente o nome que inicia com o prefixointstartRow=0;Stringprefix=txtDescricao.getText().trim();TreePathpath=jTree1.getNextMatch(prefix,startRow,Position.Bias.Forward);jTree1.expandPath(path);System.out.print(path);jTree1.setSelectionRow(jTree1.getRowForPath(path));}
M
marcosarantesj
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.
L
lina
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.
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.
M
marcosarantesj
Minha classe modelo do jTree. Usei o mesmo padrão do Vini Godoy. Nome da classe: GrupoTreeModel
packageClasses;importjava.util.ArrayList;importjava.util.List;importjavax.swing.event.TreeModelListener;importjavax.swing.tree.TreeModel;importjavax.swing.tree.TreePath;publicclassGrupoTreeModelimplementsTreeModel{//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.privateStringraiz="Grupos";// Escrevam depois AbstractTreeModel para lidar com os listeners.privateList<TreeModelListener>listeners=newArrayList<TreeModelListener>();// Raiz da nossa árvore, vamos exibir uma lista de grupos.privateList<Grupos>grupos;publicGrupoTreeModel(List<Grupos>grupos){this.grupos=grupos;}/** * 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. */publicObjectgetChild(Objectparent,intindex){if(parent==raiz)// � o n� principal?returngrupos.get(index);// Pegamos da lista de gruposif(parentinstanceofGrupos)// O pai � um grupo?{// Devolvemos um título do inforeturn((Grupos)parent).getTitulos().get(index);}// Se o pai n�o � nenhum desses. Melhor dar erro.thrownewIllegalArgumentException("Invalid parent class"+parent.getClass().getSimpleName());}/** * Retornamos quantos filhos um pai tem. No caso de um livro, � a contagem * de autores. No caso da lista de grupos, � a quantidade de grupos. */publicintgetChildCount(Objectparent){// Mesma l�gica.if(parent==raiz)returngrupos.size();if(parentinstanceofGrupos)// O pai � um livro?return((Grupos)parent).getTitulos().size();// Se o pai n�o � nenhum desses. Melhor dar erro.thrownewIllegalArgumentException("Invalid parent class"+parent.getClass().getSimpleName());}/** * Dado um pai, indicamos qual � o �ndice do filho correspondente. */publicintgetIndexOfChild(Objectparent,Objectchild){if(parent==raiz)returngrupos.indexOf(child);if(parentinstanceofGrupos)return((Grupos)parent).getTitulos().indexOf(child);return0;}/** * Devemos retornar quem � o n� raiz da �rvore. Afinal, a �rvore tem que * come�ar em algum lugar. */publicObjectgetRoot(){returnraiz;}/** * 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. */publicbooleanisLeaf(Objectnode){returnnodeinstanceofInfo;}publicvoidvalueForPathChanged(TreePathpath,ObjectnewValue){// Com esse m�todo, a tree avisa que um objeto mudou.// Editem se quiserem que um n� seja edit�vel}// Esses dois m�todos abaixo poderiam ir para classe abstratapublicvoidremoveTreeModelListener(TreeModelListenerl){listeners.remove(l);}publicvoidaddTreeModelListener(TreeModelListenerl){listeners.add(l);}}
Classe Grupos
/* * To change this template, choose Tools | Templates * and open the template in the editor. */packageClasses;importjava.util.ArrayList;importjava.util.Collections;importjava.util.List;/** * * @author MARK */publicclassGrupos{privateintcodigo;privateStringgrupo;privateList<Info>info=newArrayList<Info>();// Getters(pega um valor) e Setters(seta um valor)publicintgetCodigo(){returncodigo;}publicvoidsetCodigo(intcodigo){this.codigo=codigo;}publicStringgetGrupo(){returngrupo;}publicvoidsetGrupo(Stringgrupo){this.grupo=grupo;}//===================================================//construtor com os campospublicGrupos(intcodigo,Stringgrupo){this.codigo=codigo;this.grupo=grupo;}/*Construtor com o campo para o array*/publicGrupos(Stringgrupo){this.grupo=grupo;}//Construtor vaziopublicGrupos(){}@OverridepublicStringtoString(){returngetGrupo();}//Adiciona o titulo ao arraypublicvoidaddTitulo(Infotitulo){info.add(titulo);}publicList<Info>getTitulos(){returnCollections.unmodifiableList(info);}}
Classe Info
/* * To change this template, choose Tools | Templates * and open the template in the editor. */packageClasses;importjava.util.ArrayList;importjava.util.Collections;importjava.util.List;/** * * @author MARK */publicclassInfoextendsGrupos{privateintidInfo;privateStringtitulo;privateStringdescricao;privateStringgp;/*Construtor padrão da classe (código título, descrição)*/publicInfo(intidInfo,Stringtitulo,Stringdescricao){this.idInfo=idInfo;this.titulo=titulo;this.descricao=descricao;}/* Construtor com o campo para o jTree*/publicInfo(Stringtitulo){this.titulo=titulo;}//Construtor para a consulta (grupo e título)publicInfo(Stringgp,Stringtitulo,Stringdescricao){this.gp=gp;this.titulo=titulo;this.descricao=descricao;}//Construtor para a consulta (código,grupo,título e descrição da consultaInfo)publicInfo(intidInfo,Stringtitulo,Stringdescricao,Stringgp){this.idInfo=idInfo;this.titulo=titulo;this.descricao=descricao;this.gp=gp;}//construtor vaziopublicInfo(){}//=========================================================//Getters e SetterspublicintgetIdInfo(){returnidInfo;}publicvoidsetIdInfo(intidInfo){this.idInfo=idInfo;}publicStringgetTitulo(){returntitulo;}publicvoidsetTitulo(Stringtitulo){this.titulo=titulo;}publicStringgetDescricao(){returndescricao;}publicvoidsetDescricao(Stringdescricao){this.descricao=descricao;}publicStringgetGp(){returngp;}publicvoidsetGp(Stringgp){this.gp=gp;}//Sobescreve os métodos para o array@Override//Retorna o títulopublicStringtoString(){returngetTitulo();}}
M
marcosarantesj
Para mostrar a jTree carregada com os dados.
publicvoidMostrajTree(Stringfiltro){banco=newDB();banco.connect();Queryquery1=newQuery(banco.conn);Stringsql1=null;//Se tiver filtroif(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 noselseif(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);Stringcodgrupo=null,grup=null,titulo=null;List<Grupos>grupos=newArrayList<Grupos>();//Variáveis para verificar se é o registro atualStringstrGrupoAtual=null,strTituloAtual=null;//Inicia o loop através dos registroswhile(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 jTreeif(!codgrupo.equals(strGrupoAtual)){//Cria um novo nógrupo=newGrupos(grup);//Atualiza a variável com o código do grupo atualstrGrupoAtual=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 jTreeif(!titulo.equals(strTituloAtual)){//Adiciona o "nó" do titulo para o grupo atual.grupo.addTitulo(newInfo(titulo));//Atualiza a variável para indicar qual é o titulo atual.strTituloAtual=titulo;}//Adiciona os ítens ao arraygrupos.add(grupo);}// //Seta o modelojTree1.setModel(newGrupoTreeModel(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.