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.
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.
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();
}
}
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.
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.
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, é?
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.
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.
[quote=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.
[/quote]
Nem um pouco chateado.
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.