[Resolvido] jComboBox com código e nome

9 respostas
G
Tenho uma lista de objetos de uma classe Usuario que possui os atributos Código, Nome e Perfil.
List<Usuario> = new ArrayList<Usuario>();
Preciso que essa lista seja usada para preencher um jComboBox, mas de modo que a combo fique com o código do usuário no índice e o nome do usuário no valor. No C# dá para fazer isso inserindo um novo item a combo, nomeCombo.add(indice, valor). Como posso fazer isso usando Java?

Pelo que já pesquisei, é possível colocar o objeto Usuario diretamente na combo: jComboBoxUsuario.addItem(new Usuario(1, "Usuario 1")), mas não é interessante fazer isso ao utilizar o MVC, pois assim estaria tratando uma classe Modelo diretamente na Visão.

Vi também que outra solução seria utilizar um Map, mas não consigo manter o Integer escondido e mostrar somente a String:
// Instanciar
        Map<Integer,String> mapa = new HashMap<Integer, String>();

        // Inserir
        mapa.put(1, "Teste 1");
        mapa.put(2, "Teste 2");
        mapa.put(3, "Teste 3");

        Iterator it = mapa.entrySet().iterator();
        while (it.hasNext())
        {
            Map.Entry pairs = (Map.Entry)it.next();
            jComboBoxUsuario.addItem(pairs); // Assim mostra na Combo: "1=Teste 1", "2=Teste 2", "3=Teste 3"
        }

Um Abraço,

Gabriel

9 Respostas

L

Olá Gabriel,

se você não quer manipular suas entidades de negócio na visão, poderia criar uma classe auxiliar qualquer, que tivesse somente os dois atributos que você precisa para preencher o combo. Eu particularmente não vejo grande problema nisso, mas vai de cada um.
Outra coisa que você pode fazer é criar um ComboBoxModel (http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/ComboBoxModel.html) e nele manipular as entidades de negócio que irão preencher o combo. Isto seria mais correto e elegante, e você estaria manipulando classes de modelo no modelo. =)

[]'s

M

Você deve inserir os dados no modelo. No seu caso, acredito que um DefaultComboBoxModel resolva. Alguma coisa como:

DefaultComboBoxModel model = new DefaultComboBoxModel();
model.insertElementAt(new Usuario("blablabla"), index); 
comboBox.setModel(model);

Com o insertElementAt você escolhe o índice no qual vai inserir o usuário.

Caso você precise de algo mais elaborado (como por exemplo manter a ordem dos contatos na lista) você precisará implementar seu próprio ComboBoxModel.

G

Pessoal, não existe nenhuma solução onde não precise implementar nada novo?

Por exemplo, no C#:
ListItem prim_item = new ListItem("Geladeira", 1)
ListItem seg_item = new ListItem("Televisão", 2)
ListItem ter_item = new ListItem("Computador", 3)

comboBoxProdutos.add(prim_item);
comboBoxProdutos.add(seg_item);
comboBoxProdutos.add(ter_item);

Tentei procurar por algo semelhante ao ListItem do C# e só encontrei o Map, mas tem aquele problema citado anteriormente ao inseri-lo no combobox.
Será que utilizando uma implementação própria de ComboBoxModel eu consigo manter o código oculto e mostrar somente o nome na interface, mas quando obter o item selecionado este retornar o nome?

M

Para que servirá o índice que você passará afinal?

G
A tela é um cadastro de projetos, onde deve-se escolher um responsável pelo projeto que está sendo cadastrado. Esse responsável é um Usuário cadastrado no sistema. Desse modo, a tabela Projeto tem um campo inteiro que é chave estrangeira do código da tabela Usuário.
Tabela de Usuários:
Cod.    Nome
1       "Usuario 01"
2       "Usuario 02"

Tabela de Projetos:
Cod.    Nome       Usuario
1       "Proj 1"   1
2       "Proj 2"   1
3       "Proj 3"   2
Quando o usuário do sistema selecionar na combo a opção "Usuario 01", o sistema saberá que tem que inserir o código 1 no campo da tabela de projetos.

Entendeu?

M

Java é orientado a objetos, não a Strings.

O que você está adicionando no seu JComboBox é um objeto do tipo Usuario que já contem um codigo. Ao resgatar o objeto selecionado você terá o mesmo objeto Usuario com o mesmo código independentemente do índice dele no ComboBox.

O que o usuário vê é só uma representação do objeto Usuario (que, nesse caso, será o nome dele). Mas isso não significa que o JComboBox carregue somente a String: ele carrega o objeto Usuario todo.

M

Isso acima significa que basta fazer:

// supondo que usuarios é um List preenchido de objetos do tipo Usuario:
for (Usuario u : usuarios) {
    jComboBoxUsuario.addItem(u);
}

E na hora de resgatar:

Usuario selecionado = (Usuario) jComboBoxUsuario.getSelectedItem();
// usando o getter você consegue saber qual o código 
int codigo = selecionado.getCodigo();
G

marco,

Concordo com o que você disse sobre orientado a objetos. Alias, neste momento o sistema está funcionando exatamente como no seu exemplo. Tanto que na comparação entre as tabelas que eu coloquei a intenção é que o código a ser inserido na jComboBox seja o código que vem do banco, e todos os registros que vem do banco são transformados em objetos da classe Usuario.

O problema dessa implementação é que dessa maneira eu estou utilizando objetos da classe Usuario (Model) diretamente na classe TelaProjeto (View), e isso teoricamente está em desencontro com o propósito do MVC. O ideal seria utilizar a classe ControleProjeto (Controler) e essa sim preencher o ComboBox com qualquer tipo de objeto:

  • um ListItem do C#
  • um Map<Integer,String>
  • uma nova entidade semelhante a Usuario mas que contenha só Codigo e Nome como foi sugerido pelo Luiz_Gustavo.

Acho que o meu problema está sendo arrumar um objeto já existente no java para preencher o jComboBox…

G

Pessoal,

Para não utilizar objetos do modelo na camada de Visão, criei uma classe auxiliar que contém 2 atributos: value e text. Essa classe sobrescreve o equals() e o toString() e pode ser usada em qualquer ComboBox.

Obrigado!

Criado 16 de março de 2010
Ultima resposta 21 de mar. de 2010
Respostas 9
Participantes 3