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:
[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;
}
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!
}
}
);
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.
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.
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�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.
*/
public Object getChild(Object parent, int index) {
if (parent == raiz) // � o n� principal?
return grupos.get(index); // Pegamos da lista de grupos
if (parent instanceof Grupos) // O pai � um grupo?
{
// Devolvemos um título do info
return ((Grupos) parent).getTitulos().get(index);
}
// Se o pai n�o � 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, � a contagem
* de autores. No caso da lista de grupos, � a quantidade de grupos.
*/
public int getChildCount(Object parent) {
// Mesma l�gica.
if (parent == raiz)
return grupos.size();
if (parent instanceof Grupos) // O pai � um livro?
return ((Grupos) parent).getTitulos().size();
// Se o pai n�o � nenhum desses. Melhor dar erro.
throw new IllegalArgumentException("Invalid parent class"
+ parent.getClass().getSimpleName());
}
/**
* Dado um pai, indicamos qual � o �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 � o n� raiz da �rvore. Afinal, a �rvore tem que
* come�ar em algum lugar.
*/
public Object getRoot() {
return raiz;
}
/**
* 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 Info;
}
public void valueForPathChanged(TreePath path, Object newValue) {
// 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 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();
}
}
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.