Estou desenvolvendo uma aplicaçãozinha usando swing e um banco mysql.
Em determinado momento, tenho uma JTable, inserida em um JScrollPane, q mostra os dados vindos do banco.
Para isso, utilizei uma TableModel (DefaultTableModel) e linkei ela com a table. Até aí, tudo OK.
Agora vem minha dúvida: kero permtir q o usuário altere os dados na JTable e que isso se reflita no banco (e claro na TableModel, né?? ).
Tentei usar o InputMethodTextChanged, mas num consegui. Na verdade naum entendi direito esse evento. Tentei colocá-lo tbém em JTextField, mas parece q ele nunca é disparado… :!: :?:
Vc quer atualizar o banco em tempo real ( assi mque termina de editar na JTable vá para o banco )?? Ou deixar um botão estilo “Salvar” para salvar no banco as alterações ?
A
ArturSampaio
Tenho diversos casos onde vou precisar usar esse recurso. em alguns casos, kero que vá direto para o banco (mas para isto utilizo os métodos setXXXX pra cada atributo que tenho. o objeto é responsável por fazer o mapeamento para o banco). Em outros, terei o botãozinho estilo “salvar”.
O que realmente procuro saber é qual evento utilizar para isto.
Qualquer dos dois exemplos que vc puder me ajudar são válidos.
[]'s
B
brlima
Qdo for online, acho que um listener no TableModel pra escutar as alterações ocorridas, resolve. Pois toda vez que alguem digitar um valor na JTable e confirmar o valor ( stopCellEditing ) esse listener vai disparar, pois é qdo a JTable atualiza o TableModel, e é onde vc deve pegar o valor atualizado e atualizar no banco ( mas não acho muito legal, pq toda hora vc vai fazer update no banco = muito trafego de rede ).
Qdo for disparado o update por um botão, simples: pra cada alteração na JTable, vc pode marcar a linha alterada ( ou marcando direto na linha, ou adicionando num array ) e depois, qdo clicado no botão para salvar, leia esse array, salvando as linhas da TableModel que estão neste array.
A
ArturSampaio
ok… a parte teórica entendi blz…
mas sinceramente gostaria de ver algum exmeplo msm… tem algum link, algum lugar onde posso achar uns exemplos?
por exemplo: tá me parecendo q a table num tá alterando a tableModel.
alguma manha especial pra fazer isso?? só alterei a propriedade da table, permitindo q as células sejam alteradas… consigo alterar o conteúdo… aparece na table, td ok… porém num vejo a alteração na tableModel… nem consigo usar o evento InputMethodTextChanged (tá errado isso?)
só como teste: qdo for alterada alguma célula na Table, escrever o novo valor da célula em uma jTextField.
pra segunda solução: como marcar as linhas da talbe q foram alteradas? aliás, seria até melhor marcar a(s) célula(s) alteradas, assim só altero no banco o(s) campo(s) com modificações.
vlw pela ajuda.
[]'s
B
brlima
Seguinte, dá uma olhada nesse codigo aqui e adiciona esse codigo abaixo, logo depois da criação das colunas ( md.addColumn ):
md.addTableModelListener(newTableModelListener(){publicvoidtableChanged(TableModelEvente){intcol=e.getColumn();introw=e.getLastRow();DefaultTableModelmd=(DefaultTableModel)e.getSource();if(col<0){// Opps, estou inserindo a linha toda!}else{System.out.println("Valor atualizado: "+md.getValueAt(row,col));}if(e.getType()==e.INSERT)System.out.println("Inserindo...");if(e.getType()==e.DELETE)System.out.println("Apagando...");if(e.getType()==e.UPDATE)System.out.println("Atualizando...");}});
É um exemplo de listener no tablemodel.
A
ArturSampaio
blz… vou fazer alguns testes. Depois posto os resultados.
Muito obrigado.
vlw msm.
S
srsinistro
Huahuahua esse exemplo serviu para mim também kra valews XD.
Abraços,
Sinistrão.
T
tmagostinho
brlima:
Seguinte, dá uma olhada nesse codigo aqui e adiciona esse codigo abaixo, logo depois da criação das colunas ( md.addColumn ):
md.addTableModelListener(newTableModelListener(){publicvoidtableChanged(TableModelEvente){intcol=e.getColumn();introw=e.getLastRow();DefaultTableModelmd=(DefaultTableModel)e.getSource();if(col<0){// Opps, estou inserindo a linha toda!}else{System.out.println("Valor atualizado: "+md.getValueAt(row,col));}if(e.getType()==e.INSERT)System.out.println("Inserindo...");if(e.getType()==e.DELETE)System.out.println("Apagando...");if(e.getType()==e.UPDATE)System.out.println("Atualizando...");}});
É um exemplo de listener no tablemodel.
Tentei usar este metodo no meu tablemodel mas não funcionou
Simplesmente não dispara listener nenhum! :? É preciso fazer algo mais do que isso?
V
ViniGodoy
Infelizmente, não está tudo ok. Ele cometeu um erro fatal, usou o DefaultTableModel. Isso deu um grau de controle perto do zero no JTable. Também tem a desvantagem de ser mais difícil de usar, duplicar dados e ser desnecessáriamente sincronizado, prejudicando a performance em tabelas maiores.
Pare um tempo e estude como um TableModel personalizado funciona. Cada minuto “perdido” será mais do que compensado.
T
tmagostinho
Realmente nao gosto do defaultaTableModel pois tenho a sensação que torna uma aplicação GUI demasiado lenta! Por isso implementei o meu próprio tablemodel.
Gostaria de pedir alguns documentos a ler sobre listener, visto ser a parte em que sinto mais dificuldade. :S
Este é o meu codigo, mas este listener só funciona em caso de DELETE ou INSERT, não funciona em caso de update!
Esta minha tabela tem todas as marcas de carros, e editarem uma marca de carro na minha jtable eu quero fazer determinada acção! Mas não estou a conseguir tentar o update :?
P
paty_trind
funciona para update tmbm vou t mandar um exemplo meu q so consegui resolver com a ajuda de outros colegas daki do guj
table.getModel().addTableModelListener(newTableModelListener(){@OverridepublicvoidtableChanged(TableModelEventarg0){StringBuildersql=newStringBuilder("UPDATE financeiro SET ");switch(arg0.getColumn()){case0:sql.append("valor_entrada = '");sql.append(table.getModel().getValueAt(table.getSelectedRow(),0));sql.append("'");break;case1:sql.append("valor_total = '");sql.append(table.getModel().getValueAt(table.getSelectedRow(),1));sql.append("'");break;case2:sql.append("parcelas = '");sql.append(table.getModel().getValueAt(table.getSelectedRow(),2));sql.append("'");break;case3:sql.append("observacao = '");sql.append(table.getModel().getValueAt(table.getSelectedRow(),3));sql.append("'");break;case4:sql.append("valor_parcela = '");sql.append(table.getModel().getValueAt(table.getSelectedRow(),4));sql.append("'");break;case5:sql.append("data_pgto = '");sql.append(table.getModel().getValueAt(table.getSelectedRow(),5));sql.append("'");break;}sql.append(" WHERE rc_aluno='");sql.append(t2.getText());sql.append("'");Stringupdate=sql.toString();System.out.println(update);try{comando.executeUpdate(update);}catch(SQLExceptione){// TODO Auto-generated catch blocke.printStackTrace();}}});
estou usando switch e altero algo em uma coluna na minha jtable e depois altero no banco de dados
espero que te ajude
=]
T
tmagostinho
Agradeço muito a sua ajuda, mas jáfiz o codigo igual al seu e ele não reage ao UPDATE :? é como se o UPDATE não fgizesse disparar o evento! já não sei que faça mais :?
E
Eric_Yuzo
O seu TableModel está notificando as mudanças que ocorrem nele?
T
tmagostinho
Eric Yuzo:
O seu TableModel está notificando as mudanças que ocorrem nele?
Este é o meu código e realmente ele não implementa nada sobre os listener e eu não digo que tenho de alterar, na verdade é que se editar um celula e carregar no enter o valor mantém-se igual ao que tinha antes de ter começado a escrever. Sendo assim acho que não sei como fazer o tablemodel se modificar. :?
E
Eric_Yuzo
O AbstractTableModel já implementa os métodos relacionados ao TableModelListener. Cabe a nós apenas notificar a mudança usando os métodos "fire...", como você fez nos métodos addRow e removeRow.
Agora que entendi seu problema, você quer digitar as alterações diretamente na célula certo? Para isso não precisa do TableModelListener.
Quando alguma alteração é feita no conteúdo da célula, o método "setValueAt" do TableModel é invocado. AbstractTableModel implementa este método para não fazer nada, por isso não está havendo modificação. Portanto, você deve implementar o método, segue um exemplo:
@OverridepublicvoidsetValueAt(ObjectaValue,introwIndex,intcolumnIndex){Markm=list.get(rowIndex);// Carrega o item da linha que deve ser modificadoswitch(columnIndex){case0:// modifica o item da coluna 0m.setIdMark(aValue);case1:// modifica o item da coluna 1m.setMark(aValue);default:thrownewIndexOutOfBoundsException("columnIndex out of bounds");fireTableCellUpdated(rowIndex,columnIndex);// Notifica a atualização da célula}
T
tmagostinho
Eric Yuzo:
O AbstractTableModel já implementa os métodos relacionados ao TableModelListener. Cabe a nós apenas notificar a mudança usando os métodos "fire...", como você fez nos métodos addRow e removeRow.
Agora que entendi seu problema, você quer digitar as alterações diretamente na célula certo? Para isso não precisa do TableModelListener.
Quando alguma alteração é feita no conteúdo da célula, o método "setValueAt" do TableModel é invocado. AbstractTableModel implementa este método para não fazer nada, por isso não está havendo modificação. Portanto, você deve implementar o método, segue um exemplo:
@OverridepublicvoidsetValueAt(ObjectaValue,introwIndex,intcolumnIndex){Markm=list.get(rowIndex);// Carrega o item da linha que deve ser modificadoswitch(columnIndex){case0:// modifica o item da coluna 0m.setIdMark(aValue);case1:// modifica o item da coluna 1m.setMark(aValue);default:thrownewIndexOutOfBoundsException("columnIndex out of bounds");fireTableCellUpdated(rowIndex,columnIndex);// Notifica a atualização da célula}
Voce é genial!! Até acertou nos nome dos meus metodos :D
Sim, realmente percebi o meu problema, no fundo o setValueAt funciona da mesma forma que o getValueAt, e como não o tinha implementado o table model não alterava!
Relativamente ao facto de ter um listener. Essa questão vem porque eu queria ter uma tabela com para fazer "orçamentos" e adicionava produtos a tabela e caso fosse necessário mudar o valor ao preço era só alterar na JTable e automaticamente era recalculado o valor total do orçamento. Deu para entender o que pretendo?
Já agora um muito obrigado a todos que participaram neste tópico de ajuda! Não espera ter tanta ajuda! Muito obrigado!! :oops:
T
tmagostinho
Depois de ter redefinido o metodo setValeuAt, o meu listener já passou a reagir ao update também! Está mesmo perfeito!
Agora de seguida vou tentar incluir uma JCheckBox na Jtable.
Se tudo correr bem vou definitivamente passar para a programação em ECLIPSE com VISUAL EDITOR, para me libertar do netbeans :?
E
Eric_Yuzo
Viva as especificações. \o/
Uma dica: O TableModel tem o método getColumnClass, fazendo ele retornar Boolean.class para o índice da coluna que vai ter o checkBox, a JTable já utiliza automaticamente o CellRenderer com checkBox.