Como selecionar objeto em uma ComboBox? setSelectedItem não funciona

7 respostas
G

Olá,
Estou precisando de uma grande ajuda.

Estou desenvolvendo um programa, de cadastro de Pessoas e Estados. Cadastro de Estados OK. Cadastro de Pessoas, QUASE OK. Vejam minha de cadastro:

A imagem da tela de cadastro de Pessoas:

Meu pesadelo está porque coloquei uma ComboBox para selecionar o Estado.

Usando hibernate e listas, consigo puxar todos os OBJETOS Estado dentro do ComboBox e dentro da jTable.

O problema está sendo pegar a Referência ao OBJETO Estado, do meu campo 3 da jTable, e passar ele para o ComboBox.

Pegar a referência da tabela está fácil, fiz dessa forma:

Estado zz = (Estado) jTable2.getValueAt(jTable2.getSelectedRow(),3);

Ele realmente está pegando a referência ao objeto, testei da seguinte forma:

System.out.prinlnt(zz.getNomeEstado);

E deu certo! Pegou o nome do estado selecionado na jTable.

Acontece que eu quero que ele pegue esse objeto e automaticamente selecione o Estado na minha comboBox. O código usado não poderia ser mais simples:

comboEstado.setSelectedItem(zz);

Só que ele não seleciona! Não faz absolutamente nada!

Como resolvo isso? Tentei algo usando DefaultTableModel, sem sucesso, mas eu estou encafifado: o setSelectedItem não deveria fazer justamente isso?
Alguma luz?

Obrigado pela atenção e desculpem o tamanho. Apenas quis detalhar o máximo!

Abraços!

7 Respostas

S

GabrielVinicios:
Olá,

Como resolvo isso? Tentei algo usando DefaultTableModel, sem sucesso, mas eu estou encafifado: o setSelectedItem não deveria fazer justamente isso?

Deveria se tanto o objeto da tabela quanto do combo fossem a mesma instância ou duas referências apontando para o mesmo objeto.

Faça o seguinte teste:

for (int i = 0; i < combo.getItemCount(); ++i) {
   Estado item = (Estado) combo.getItemAt(i);
   if (zz.getNomeEstado().equals(item.getNomeEstado())) {
      if (zz == item) {
         System.out.println("Combo e tabela apontam para o mesmo objeto");
      } else {
         System.out.println("Possuem apenas o mesmo estado, mas apontam para objetos diferentes");
      }
      break;
   }
}
G

Hummm, entendi o que você quis dizer. O fato de dois objetos terem exatamente os mesmos atributos não os torna iguais.

De que forma eu faço o que eu quero, então?

Varrendo a combox até achar um objeto cujo equals seja verdadeiro em relação ao jTable, e selecionar esse? Ou existe forma mais fácil?

Abraços!

S

GabrielVinicios:
Hummm, entendi o que você quis dizer. O fato de dois objetos terem exatamente os mesmos atributos não os torna iguais.

De que forma eu faço o que eu quero, então?

Varrendo a combox até achar um objeto cujo equals seja verdadeiro em relação ao jTable, e selecionar esse? Ou existe forma mais fácil?

Abraços!

Se você observar essa linha no exemplo que coloquei:

...
if (zz.getNomeEstado().equals(item.getNomeEstado())) {
...

Dentro desse if você consegue setar o combo pelo indice também:

...
combo.setSelectedIndex(i);
...

Ou seja, quando ele encontrar um item que o texto bate com a coluna da tabela, sete-o pelo indice.

G

Entendi!

Muito obrigado pela solução! Vou implementá-la. É tão bom ir entendendo o porquê das coisas!

Agora, à titulo de curiosidade, esta é a melhor foram de se fazer isso?

No Visual Basic, eu podia usar uma combobox com várias colunas. Ai eu normalmente colocava o Id na primeira coluna e o Nome na segunda. Eu setava a largura da primeira coluna para zero, e então o usuário via apenas o nome, mas eu podia perfeitamente pegar o iD e isso me resolvia o problema.

No Java não dá pra fazer algo assim? Pelo que li, parece que só com outros tipos de ComboBox (não do Swing).

Mas muito obrigado, caro soldierx13!

S

GabrielVinicios:
Entendi!
Agora, à titulo de curiosidade, esta é a melhor foram de se fazer isso?

Não, essa não é a melhor forma, mas funciona.

Outra dica mais elegante, é colocar esse teste na própria classe Estado, sobreescrevendo o equals:

@Override
public boolean equals(Object o) {
   Estado estado = (Estado) o;
   return this.getNomeEstado().equals(estado.getNomeEstado());
}

Dessa forma você nem precisa mudar nada lá no combobox e tabela e muito menos ficar percorrendo laço pra isso.

Essa é outra forma de se fazer que creio eu não irá atrapalhar o seu projeto, já que para se comparar estados podemos “igualá-los” apenas pelo nome correto?

G

Sim, caro Soldier, mas estou pensando mais longe!

Não quero comparar apenas pelo nome, pois em situações futuras (cadastro de nomes de pessoas, por exemplo), só pelo nome eu não posso identificar uma pessoa. Então pensei que teria de ser algo mais robusto - ou pelo id, ou pelo objeto inteiro.

S

GabrielVinicios:
Sim, caro Soldier, mas estou pensando mais longe!

Não quero comparar apenas pelo nome, pois em situações futuras (cadastro de nomes de pessoas, por exemplo), só pelo nome eu não posso identificar uma pessoa. Então pensei que teria de ser algo mais robusto - ou pelo id, ou pelo objeto inteiro.

Pesquei, mas a sobreescrita do equals, você pode colocar o critério que desejar entendeu?

Por exemplo, no caso do Estado, ao carregar esse objeto no combo, o id dele pode ser o que veio da base e depois os demais que estarão na tabela, poderão ser objetos diferentes, mas com o mesmo atributo id (obviamente tratam-se de objetos distintos, mas a comparação seria feita entre atributos).

Eu apenas exemplifiquei o uso do equals().

Criado 17 de outubro de 2013
Ultima resposta 18 de out. de 2013
Respostas 7
Participantes 2