::RESOLVIDO::Inserir linha em jTable em tempo de execução

9 respostas
C

Boa tarde galera!

Estou desenvolvendo um sistema para controle interno de notas fiscais. No cadastro das notas estou enfrentando dificuldades na adição dos itens da nota. Essa adição é feita através de um jButton [Add Item] que pega os dados dos jTextField preenchidos e os insere no jTable. O problema é que só consigo inserir 1 (um) item por vez na jTable. O segundo item na verdade substitui o primeiro na tabela.

Estou utilizando duas técnicas.

private void PreencherTabela() {           
       
        if (jTable1.getValueAt(0, 0) == null) {  //certifica se primeira celula tem conteudo
            Connect Con1 = new Connect();
            Con1.Conecta();
            String sql = "SELECT * FROM produtos WHERE desc_produtos_prod LIKE '"+Descricao.getText()+"'";            
            Con1.ExecutaSQL(sql);            
            jTable1.getColumnModel().getColumn(0).setPreferredWidth(10);
            jTable1.getColumnModel().getColumn(1).setPreferredWidth(10);
            jTable1.getColumnModel().getColumn(2).setPreferredWidth(10);
            jTable1.getColumnModel().getColumn(3).setPreferredWidth(10);
            jTable1.getColumnModel().getColumn(4).setPreferredWidth(10);
            jTable1.getColumnModel().getColumn(5).setPreferredWidth(10);            
          
            DefaultTableModel modelotabela = (DefaultTableModel) jTable1.getModel();
            modelotabela.setNumRows(0);
            
            try {
                Con1.resultset.first();

                modelotabela.addRow(new Object[]{
                            Con1.resultset.getString("cod_prod"),
                            Descricao.getText(),
                            Unidade.getText(),
                            Qtde.getText(),
                            V_Unit.getText(),
                            Subtotal.getText()});

                Con1.Desconecta();

            } catch (SQLException erro) {
                JOptionPane.showMessageDialog(null, "Talvez este nome não esteja cadastrado no banco de dados. Tente outro nome. \n" + erro);      
            }
        
        } else {

            Connect Con1 = new Connect();
            Con1.Conecta();
            String sql = "SELECT * FROM produtos WHERE desc_produtos_prod LIKE '" + Descricao.getText() + "'";
            Con1.ExecutaSQL(sql);
            
            try {
                Con1.resultset.first();
            } catch (SQLException ex) {
                Logger.getLogger(Cad_Nota.class.getName()).log(Level.SEVERE, null, ex);
            }
            
            try {
       Collumnames = new String[] {"Codigo","Descricao","Unidade","Qtde","V.Unitario","Subtotal"};
       data = new Object[1][6];

                Object[][] temp = new Object[data.length + 1][6]; //Objeto do tipo array que defini linhas e colunas
                for (int i = 0; i < data.length; i++) { // laço para percorrer o array (linha)
                    for (int j = 0; j < 6; j++) {          // laço para percorrer o array (coluna)
                        temp[i][j] = data[i][j];            
                    }
                }
                       
                temp[data.length][0] = Con1.resultset.getString("cod_prod");
                temp[data.length][1] = Descricao.getText();
                temp[data.length][2] = Unidade.getText();
                temp[data.length][3] = Qtde.getText();
                temp[data.length][4] = V_Unit.getText();
                temp[data.length][5] = Subtotal.getText();
                data = temp;
                jTable1.setModel(new DefaultTableModel(data, Collumnames));

                } catch (SQLException e) {
                    e.printStackTrace();
            }
      }
}

Consigo adicionar o 1º item normal. O problema são as demais linhas. Ele até adiciona uma linha mas sem conteúdo.
Conto com vc’s amigos.

9 Respostas

Ravnus

Cara, Swing realmente não é o meu forte, mas creio que tentar ajudar é melhor do que ficar em silêncio. Então… na apostila FJ16 da Caelum, tem um exemplo ensinando a mexer com JTable e TableModel. Dá uma sacada no índice e vê se ajuda.

Espero que isso possa ser uma dica.

ViniGodoy

Basta inserir uma linha no TableModel.

Se você não sabe fazer um TableModel, ou está usando o horrível DefaultTableModel, siga o link do lado do texto em vermelho na minha assinatura.

C

Boa tarde meus amigos!

O problema foi resolvido, agradeço a proatividade do Ravnus.
Vini, apesar de já ter visto vários posts seus criticando o DefaultTableModel foi com ele que resolvi o problema. Acredito que existam inúmeras formas de se utilizar o recurso, inclusive mais recomendadas do ponto de vista das boas práticas de desenvolvimento e E.S, porém, dentro de minhas limitações técnicas (na verdade sou Adm. de Redes e não desenvolvedor), foi o que consegui fazer. De toda maneira, agradeço pela ajuda e sei que certamente sua solução seria muito mais profissional.
Eis o código corrigido:

int count2 = 0;

if (jTable1.getValueAt(0, 0) == null) {
            Connect Con1 = new Connect();
            Con1.Conecta();
            String sql = "SELECT * FROM produtos WHERE desc_produtos_prod LIKE '"+Descricao.getText()+"'";            
            Con1.ExecutaSQL(sql);            
            jTable1.getColumnModel().getColumn(0).setPreferredWidth(10);
            jTable1.getColumnModel().getColumn(1).setPreferredWidth(10);
            jTable1.getColumnModel().getColumn(2).setPreferredWidth(10);
            jTable1.getColumnModel().getColumn(3).setPreferredWidth(10);
            jTable1.getColumnModel().getColumn(4).setPreferredWidth(10);
            jTable1.getColumnModel().getColumn(5).setPreferredWidth(10);            
          
            DefaultTableModel modelotabela = (DefaultTableModel) jTable1.getModel();
            modelotabela.setNumRows(0);
                   
            try {
                Con1.resultset.first();

                modelotabela.addRow(new Object[]{
                            Con1.resultset.getString("cod_prod"),
                            Descricao.getText(),
                            Unidade.getText(),
                            Qtde.getText(),
                            V_Unit.getText(),
                            Subtotal.getText()});

                Con1.Desconecta();

            } catch (SQLException erro) {
                JOptionPane.showMessageDialog(null, "Talvez este nome não esteja cadastrado no banco de dados. Tente outro nome. \n" + erro);
                erro.printStackTrace();               
            }
        
        } else {
            
            
            Connect Con1 = new Connect();
            Con1.Conecta();
            String sql = "SELECT * FROM produtos WHERE desc_produtos_prod LIKE '" + Descricao.getText() + "'";
            Con1.ExecutaSQL(sql);
            jTable1.getColumnModel().getColumn(0).setPreferredWidth(10);
            jTable1.getColumnModel().getColumn(1).setPreferredWidth(10);
            jTable1.getColumnModel().getColumn(2).setPreferredWidth(10);
            jTable1.getColumnModel().getColumn(3).setPreferredWidth(10);
            jTable1.getColumnModel().getColumn(4).setPreferredWidth(10);
            jTable1.getColumnModel().getColumn(5).setPreferredWidth(10);

            DefaultTableModel modelotabela = (DefaultTableModel) jTable1.getModel();
            modelotabela.setRowCount(count2+1); //incrementa posição da linha
            
            try {
                
                Con1.resultset.first();
                modelotabela.insertRow(modelotabela.getRowCount(), new Object[]{ //pega a contagem atual da linha (getRowCount) e insere uma nova(insertRow)
                            Con1.resultset.getString("cod_prod"),
                            Descricao.getText(),
                            Unidade.getText(),
                            Qtde.getText(),
                            V_Unit.getText(),
                            Subtotal.getText()});

                count2++; //incrementa contador
                Con1.Desconecta();

            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
ViniGodoy

Você sequer tentou fazer sem o Default?
Não se engane. Usar o Default é ir pelo caminho mais difícil. Ele trará diversos problemas que nem sequer existirão se você fizer do jeito certo.

Ser admin. de redes não é desculpa para ser um desenvolvedor desleixado. Se é esse o caso, o que você está fazendo atuando com um sistema de notas fiscais? Essa desculpa pode até aliviar sua consciência, mas certamente não vai ajudar em nada quem for manter a porquice do Default depois.

C

Bom dia Sr. Vini Godoy, me assusta sua indignação com este recurso. Respondendo sua pergunta, eu tentei sim fazer sem o Default.
Em vez de retrucar suas ofensas (o que me deixa espantado, afinal, pelo que me consta vc é um moderador do fórum), prefiro agradecer dizendo que seus comentários foram muito construtivos e muito ajudaram a resolver o problema.
É de moderadores e comentários assim que os estudantes, profissionais e entusiastas do desenvolvimento java estão precisando. Continue assim.

Muito obrigado por tudo!
Abraço

ViniGodoy

Não é uma ofensa, é um cutucão. O DefaultTableModel foi criado pela Sun para servir de exemplo.
Ele realmente gera muitos transtornos, quebra modelos de software e torna o trabalho com JTable muito mais difícil, sujeito a erros e ineficiente do que deveria ser.

Fazendo um paralelo com redes: Você pode distribuir senhas de root para todos os seus usuários. Vai ser fácil e, aparentemente, num primeiro momento, resolve diversos problemas de conexão e acesso.

Agora, o que você me diria se, num fórum de redes, eu insistisse com você que estou dando a senha de root para todos os meus usuários, usando como desculpa o fato de ser um “programador e não um administrador de rede” e dizendo que esse “recurso” resolveu meu problema? Especialmente, depois de eu alegar que sabia que esse não era o jeito certo e já havia lido em diversos lugares que isso não deveria ser feito? Mesmo alegando inexperiência, não é desculpa para se fazer errado, é?

ViniGodoy

Aproveitando a deixa, pesquise também sobre PreparedStatement. O seu código está sujeito a SQL Injection, o que pode comprometer a segurança de todo o seu banco de dados.

Por exemplo, considere que algum usuário mal intecionado coloque a seguinte descrição de produto:

'); DROP TABLE Produtos; --

O PreparedStatement também resolve outros problemas, como evitar que seu programa dê erro caso o usuário use apóstrofe na descrição do produto, abstrair para você formatos de datas e permitir a inserção de dados do tipo BLOB. Ele também envia os dados de maneira mais otimizada pela rede, pois pode faze-lo de forma binária.

C

Ahhh, era esse o nível que eu esperava deste fórum. Muito obrigado. Espero que não tenha se chateado comigo. Agora com todas essas explicações TÉCNICAS me senti mais motivado a estudar o modo correto de fazer. Obrigado também pela dica do PreparedStatement, vou pesquisar.

Abraço!

ViniGodoy

crononsp:
Ahhh, era esse o nível que eu esperava deste fórum. Muito obrigado. Espero que não tenha se chateado comigo. Agora com todas essas explicações TÉCNICAS me senti mais motivado a estudar o modo correto de fazer. Obrigado também pela dica do PreparedStatement, vou pesquisar.

Nem um pouco chateado. :slight_smile:
Não havia dado explicações técnicas pois você havia argumentado que já as havia lido, mas ainda assim optou por ignora-las.
Nesse caso, apelei mesmo para o cutucão provocativo. :wink:

Espero que não fique chateado comigo também.

Criado 19 de novembro de 2012
Ultima resposta 21 de nov. de 2012
Respostas 9
Participantes 3