JComboBox com Banco de dados

16 respostas
muniquewassem

Olá de novo!

Bem, estou com um problema com um combo box. Eu tenho um JFrame de cadastro de Medicamento, que busca o Tipo do medicamento e a Marca do medicamento.
Eu consigo listar os dados (como texto) e seleciona-los e até salva-los (como int), mas através de uma enorme gambiarra e que arrumar isso.

No frame eu faço a seguinte lambança:
public CadastroMedicamento() throws SQLException{
        initComponents();

        comboTipo.removeAllItems(); //remove os itens atuais do comboBox.  
        //comboTipo.insertItemAt("", 0); //insere linha em branco - solução 1 para começar a contagem em 1
        ArrayList tipos = new MedicamentoDAO().findMedTipos(); //'medicamentoDAO' é meu objeto que retorna os produtos do banco.
        Iterator i = tipos.iterator();
        while (i.hasNext()) {
            comboTipo.addItem(String.valueOf(i.next())); //adiciona itens na box
        }
        
        comboMarca.removeAllItems(); //remove os itens atuais do comboBox.  
        //comboMarca.insertItemAt("", 0);
        ArrayList marcas = new MedicamentoDAO().findMedMarcas(); //'produtoDAO' é meu objeto que retorna os produtos do banco.  
        Iterator i2 = marcas.iterator();
        while (i2.hasNext()) {
            comboMarca.addItem(String.valueOf(i2.next()));
        }
    }

    private void onClickSalvar() throws ParseException, SQLException{
        MedicamentoController mc = new MedicamentoController();
        int tipo = comboTipo.getSelectedIndex();
        int marca = comboMarca.getSelectedIndex();
        try {
            //inicio da gambirra 
            if (comboTipo.getSelectedIndex() >= 0){ //se estiver selecionado
                tipo = tipo + 1; //pela o indice + 1, pois getSelectedItenm começa a contar de 0
            } if (comboMarca.getSelectedIndex() >= 0){
                marca = marca + 1;
            } if (txtFaixaEtariaInicio.getText().isEmpty()){
                txtFaixaEtariaInicio.setText("0");
            }  if (txtFaixaEtariaFim.getText().isEmpty()){
                txtFaixaEtariaFim.setText("0");
            }
            mc.salvar(/**Integer.parseInt(jTextFieldCodigoTipo.getText()),*/ txtNomeMedicamento.getText(), tipo, 
                    marca, sexo, faixaEtaria,
                    Integer.parseInt(txtFaixaEtariaInicio.getText()), Integer.parseInt(txtFaixaEtariaFim.getText()), periodoValido,
                    formPeriodoValidoInicio.getText(), formPeriodoValidoFim.getText());
            JOptionPane.showMessageDialog(this, "Medicamento salvo com sucesso!");
            dispose();
            //clearFields();
        } catch (SQLException e) {
            JOptionPane.showMessageDialog(this, "Nao foi possivel salvar contato!\n" + e.getLocalizedMessage());
        }
    }
Ai no Dao, para achar as marcas e tipos, eu faço isso:
public ArrayList findMedTipos() throws SQLException {
        String select = "SELECT codigotipo, nometipo FROM tipomedicamento ORDER BY codigotipo"; //sql
        PreparedStatement stmt = getConnection().prepareStatement(select);
        ResultSet rs = stmt.executeQuery();
        ArrayList list = new ArrayList();
        while (rs.next()) {
            //list.add(rs.getString(1));
            list.add(rs.getString(2)); //mando a box exibir o nome e não o código
        }
        return list;
    }

    public ArrayList findMedMarcas() throws SQLException {
        String select = "SELECT codigomarca, nomemarca FROM marca ORDER BY codigomarca"; //sql
        PreparedStatement stmt = getConnection().prepareStatement(select);
        ResultSet rs = stmt.executeQuery();
        ArrayList list = new ArrayList();
        while (rs.next()) {
            //list.add(rs.getString(1));
            list.add(rs.getString(2)); //exibe nomemarca
        }
        return list;
    }

Tá, até ai tudo bem... salva tudo bonitinho e tal, mas o problema é: Se o usuário, por exemplo, excluir o tipo que tem como código 2 no banco, o combo vai exibir o tipo 3 como se fosse o 2 e vai salvar errado, gerando um enorme erro.
Eu quero achar uma solução que me faça salvar o código que fica no banco mesmo e não o indice, ou seja, que não use o getSelectedIndex.

Alguém tem uma idéia do que pode ser feito pra arrumar isso?

16 Respostas

ViniGodoy

Ao invés de colocar Strings na sua combobox, coloque objetos.

Basta sobrescrever o método toString() das suas classes, para retornar a descrição do medicamento, marca ou tipo. Aí vc poderá fazer coisas do tipo:

if (comboTipo.getSelectedIndex() >= 0){ Tipo tipo = (Tipo)comboTipo.getSelectedItem(); int idTipo = tipo.getId(); }

Sem nenhuma gambi. :slight_smile:

ViniGodoy

Só comentando, após sobrescrever o toString() das classes a carga vai ficar assim:

ArrayList<Tipo> tipos = new MedicamentoDAO().findMedTipos(); Iterator<Tipo> i = tipos.iterator(); while (i.hasNext()) { comboTipo.addItem(i.next()); //adiciona Tipos na box, não Strings }

muniquewassem

Para sobrescrever toString() seria algo como:

public class Tipo {

    private String nome;

    public Tipo(String nome) {
        this.nome = nome;
    }

    public String toString() {
        return nome;
    }
}

Não to entendendo o erro, está me retornando uma ClassCastException, falando que a String pode ser lançada.

ViniGodoy

É só isso mesmo.

Em que linha está dando a classcastexception?

muniquewassem

if (comboTipo.getSelectedIndex() >= 0) { Tipo tipo = (Tipo) comboTipo.getSelectedItem(); //erro aqui idTipo = tipo.getCodigo(); }

No exemplo você colocou getSelectedValue() , mas como o método não existe para combo, imagino que você tenho colocado pra ser o getSelectedItem().

ViniGodoy

Isso, era isso mesmo. Você mudou a carga da sua combobox como eu indiquei?
Note que você deve colocar objetos da classe Tipo dentro da combo, não Strings.

Outra coisa, sua combo é editável?

muniquewassem

Mudei a carga sim… Ficou assim:

comboTipo.removeAllItems(); //remove os itens atuais do comboBox. comboTipo.setEditable(false); ArrayList<Tipo> tipos = new MedicamentoDAO().findMedTipos(); //'medicamentoDAO' é meu objeto que retorna os produtos do banco. Iterator<Tipo> i = tipos.iterator(); while (i.hasNext()) { comboTipo.addItem(i.next()); //adiciona itens na box }

Eu coloquei ele não editável. Tem que ser?

ViniGodoy

Nao. E isso mesmo. Pode postar o texto completo da exception?

muniquewassem

Quando é assim, devo estar fazendo algo estupidamento estupido.

run: Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: java.lang.String cannot be cast to tipo.model.Tipo at medicamento.view.CadastroMedicamento.onClickSalvar(CadastroMedicamento.java:98) at medicamento.view.CadastroMedicamento.btnSalvarActionPerformed(CadastroMedicamento.java:411) at medicamento.view.CadastroMedicamento.access$400(CadastroMedicamento.java:30) at medicamento.view.CadastroMedicamento$5.actionPerformed(CadastroMedicamento.java:228) at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995) at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318) at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387) at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242) at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236) at java.awt.Component.processMouseEvent(Component.java:6288) at javax.swing.JComponent.processMouseEvent(JComponent.java:3267) at java.awt.Component.processEvent(Component.java:6053) at java.awt.Container.processEvent(Container.java:2041) at java.awt.Component.dispatchEventImpl(Component.java:4651) at java.awt.Container.dispatchEventImpl(Container.java:2099) at java.awt.Component.dispatchEvent(Component.java:4481) at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4577) at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4238) at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4168) at java.awt.Container.dispatchEventImpl(Container.java:2085) at java.awt.Window.dispatchEventImpl(Window.java:2478) at java.awt.Component.dispatchEvent(Component.java:4481) at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:643) at java.awt.EventQueue.access$000(EventQueue.java:84) at java.awt.EventQueue$1.run(EventQueue.java:602) at java.awt.EventQueue$1.run(EventQueue.java:600) at java.security.AccessController.doPrivileged(Native Method) at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87) at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:98) at java.awt.EventQueue$2.run(EventQueue.java:616) at java.awt.EventQueue$2.run(EventQueue.java:614) at java.security.AccessController.doPrivileged(Native Method) at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87) at java.awt.EventQueue.dispatchEvent(EventQueue.java:613) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161) at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

O que tem na linha 98:

if (comboTipo.getSelectedIndex() >= 0) { Tipo tipo = (Tipo) comboTipo.getSelectedItem(); //linha 98 idTipo = tipo.getCodigo(); }

Linha 411: actionPerformed do botão

Linha 30: chamada da classe

ViniGodoy

Estranho, seu erro diz que você ainda tem uma String na combo e não um Tipo. Você não está preenchendo a combo com nenhuma String em lugar nenhum?

muniquewassem

Não, eu mudei pra getObject no DAO.
Olha ai:

public ArrayList findMedTipos() throws SQLException { String select = "SELECT codigotipo, nometipo FROM tipomedicamento ORDER BY codigotipo"; PreparedStatement stmt = getConnection().prepareStatement(select); ResultSet rs = stmt.executeQuery(); ArrayList list = new ArrayList(); while (rs.next()) { list.add(rs.getObject(2)); } return list; }

Antes estava como getString… Tem que continuar getString?

ViniGodoy

Nao, seu Dao deve retornar Tipos. Voce feve montar uma lista de Tipos camando o new Tipo e colocando os dados da tabela dentro. Retorne tipos com nome e código e nao só a coluna 2.

ViniGodoy

public ArrayList<Tipo> findMedTipos() throws SQLException { String select = "SELECT codigotipo, nometipo FROM tipomedicamento ORDER BY codigotipo"; PreparedStatement stmt = getConnection().prepareStatement(select); ResultSet rs = stmt.executeQuery(); ArrayList<Tipo> list = new ArrayList<Tipo>(); while (rs.next()) { list.add(new Tipo(rs.getInt("codigotipo"), rs.getString("nometipo")); } return list; }

muniquewassem

Ahh sim! Entendi!
Mas ainda tá bixado. O idTipo ainda não está recebendo o valor do código do tipo, fiquei sem entender de vez o que tá acontecendo…

int idTipo = 0; //inicializa a variavel int idMarca = 0; try { if (comboTipo.getSelectedIndex() >= 0) { Tipo tipo = (Tipo) comboTipo.getSelectedItem(); //pega o item selecionado idTipo = tipo.getCodigo(); //pega o codigo do tipo JOptionPane.showMessageDialog(this, idTipo); //mostra o que o idTipo recebeu } if (comboMarca.getSelectedIndex() >= 0) { Marca marca = (Marca) comboMarca.getSelectedItem(); idMarca = marca.getCodigo(); JOptionPane.showMessageDialog(this, idMarca); } mc.salvar(/**Integer.parseInt(jTextFieldCodigoTipo.getText()),*/ txtNomeMedicamento.getText(), idMarca, idTipo, sexo, faixaEtaria, Integer.parseInt(txtFaixaEtariaInicio.getText()), Integer.parseInt(txtFaixaEtariaFim.getText()), periodoValido, formPeriodoValidoInicio.getText(), formPeriodoValidoFim.getText());
Até coloquei um JOptionPane pra ver se tava recebendo alguma coisa…

ViniGodoy

Aí só com o depurador para ver. Provavelmente é algum problema na hora da carga do tipo do banco.

muniquewassem

Acho que achei o erro, mas não sei se é isso e se for, não sei como corrigir. Quando ele vai salvar o Tipo e a Marca, ele vai na classe Medicamento e busca diretamente setTipo(int tipo) e setMarca(int marca).

O então passa direto por idTipo e idMarca… É isso?

Criado 25 de junho de 2011
Ultima resposta 26 de jun. de 2011
Respostas 16
Participantes 2