Alteração de dados em Jtable

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é?? :smiley: ).
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… :!: :?:

Agradeço ajuda.

vlw
[]'s

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 ?

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

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.

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

Seguinte, dá uma olhada nesse codigo aqui e adiciona esse codigo abaixo, logo depois da criação das colunas ( md.addColumn ):

md.addTableModelListener(new TableModelListener(){
            public void tableChanged(TableModelEvent e){
                
                int col = e.getColumn();
                int row = e.getLastRow();
                
                DefaultTableModel md = (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.

blz… vou fazer alguns testes. Depois posto os resultados.
Muito obrigado.
vlw msm.

Huahuahua esse exemplo serviu para mim também kra valews XD.

Abraços,

Sinistrão.

[quote=brlima]Seguinte, dá uma olhada nesse codigo aqui e adiciona esse codigo abaixo, logo depois da criação das colunas ( md.addColumn ):

md.addTableModelListener(new TableModelListener(){
            public void tableChanged(TableModelEvent e){
                
                int col = e.getColumn();
                int row = e.getLastRow();
                
                DefaultTableModel md = (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.[/quote]

Tentei usar este metodo no meu tablemodel mas não funcionou :frowning:
Simplesmente não dispara listener nenhum! :? É preciso fazer algo mais do que isso?

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.

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

eu estava com o mesmo problema e consegui resolver
olha este topico
http://www.guj.com.br/java/231503-alterar-jtableresolvido
espero que te ajude!

[code]getMyTableModel().addTableModelListener(new TableModelListener(){
public void tableChanged(TableModelEvent e){

            	System.out.println("MUDEI");
            }
		});[/code]

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 :?

funciona para update tmbm vou t mandar um exemplo meu q so consegui resolver com a ajuda de outros colegas daki do guj

[code]table.getModel().addTableModelListener(new TableModelListener() {

			@Override
			public void tableChanged(TableModelEvent arg0) {
				StringBuilder sql = new StringBuilder("UPDATE financeiro SET ");  
				  
				switch (arg0.getColumn()) {  
				   case 0:  
				      sql.append("valor_entrada = '");  
				      sql.append(table.getModel().getValueAt(table.getSelectedRow(),0 ));  
				      sql.append("'");  
				      break;  
				   case 1:  
					   sql.append("valor_total = '");  
					      sql.append(table.getModel().getValueAt(table.getSelectedRow(),1 ));  
					      sql.append("'");  
					      break;
				   case 2:
					   sql.append("parcelas = '");  
					      sql.append(table.getModel().getValueAt(table.getSelectedRow(),2 ));  
					      sql.append("'");  
					      break;
				   case 3:
					   sql.append("observacao = '");  
					      sql.append(table.getModel().getValueAt(table.getSelectedRow(),3 ));  
					      sql.append("'");  
					      break;
				   case 4:
					   sql.append("valor_parcela = '");  
					      sql.append(table.getModel().getValueAt(table.getSelectedRow(),4 ));  
					      sql.append("'");  
					      break;
				   case 5 :
					   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("'");  
				  
				String update = sql.toString();  
				System.out.println(update);  
				try {
					comando.executeUpdate(update);
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}  
				
			}
		});[/code]

estou usando switch e altero algo em uma coluna na minha jtable e depois altero no banco de dados
espero que te ajude
=]

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 :?

O seu TableModel está notificando as mudanças que ocorrem nele?

[code]
public class MyTableModel extends AbstractTableModel{

/**
 * 
 */
private static final long serialVersionUID = 1L;
private String[] nameCol = {"ID MARK", "MARK"};
private ArrayList<Mark> list;

public MyTableModel(){};

public MyTableModel(ArrayList<Mark> list){

	this.list = list;
	
}

@Override
public int getColumnCount() {
	return nameCol.length;
}

@Override
public int getRowCount(){
	if(list==null) return 0;
	return list.size();
}

@Override
public Object getValueAt(int rowIndex, int columnIndex) {
	Mark m = list.get(rowIndex);
	switch(columnIndex){
		case 0: return m.getIdMark();
		case 1: return m.getMark();
	}
	return null;
}

public void addRow(Mark m){
	list.add(m);
	fireTableRowsInserted(list.size()-1, list.size()-1);
}

public void removeRow(int index){
	list.remove(index);
	fireTableRowsDeleted(index, index);
}
@Override
public String getColumnName(int columnIndex){
	return nameCol[columnIndex];
}

@Override   
public boolean isCellEditable(int rowIndex, int columnIndex){   
    return true;   
}

}[/code]

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. :?

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:

[code] @Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
Mark m = list.get(rowIndex); // Carrega o item da linha que deve ser modificado

    switch (columnIndex) {
        case 0: // modifica o item da coluna 0
            m.setIdMark(aValue);
        case 1: // modifica o item da coluna 1
            m.setMark(aValue);
        default:
            throw new IndexOutOfBoundsException("columnIndex out of bounds");

    fireTableCellUpdated(rowIndex, columnIndex); // Notifica a atualização da célula
}[/code]

[quote=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:

[code] @Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
Mark m = list.get(rowIndex); // Carrega o item da linha que deve ser modificado

    switch (columnIndex) {
        case 0: // modifica o item da coluna 0
            m.setIdMark(aValue);
        case 1: // modifica o item da coluna 1
            m.setMark(aValue);
        default:
            throw new IndexOutOfBoundsException("columnIndex out of bounds");

    fireTableCellUpdated(rowIndex, columnIndex); // Notifica a atualização da célula
}[/code][/quote]

Voce é genial!! Até acertou nos nome dos meus metodos :smiley:
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:

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 :?