Problema com TableModel

Gente escrevi meu tablemodel mas to com prblemas com ele. Mas especificamento no metodo setValueAt.

package br.com.folhax.gui.controls;

import java.util.List;
import javax.swing.table.AbstractTableModel;

/**
 *
 * @author Matheus
 */

public class MatheusTableModel extends AbstractTableModel{
    private List nomecoluna; //Lista com os nomes das colunas;
    private List<List> dadoscoluna; // Lista bidimenssional
    private boolean celledit = false;

    public MatheusTableModel(List nomecoluna, List<List> dadoscoluna){
        this.nomecoluna = nomecoluna;
        this.dadoscoluna = dadoscoluna;
    }

    public int getRowCount() { // Cada produto uma linha
        return dadoscoluna.size();
    }

    public int getColumnCount() { // Quantidade de colunas
        return nomecoluna.size();
    }

    public Object getValueAt(int rowIndex, int columnIndex) { //Dados que serão exibidos
        return dadoscoluna.get(rowIndex).get(columnIndex);
    }

    @Override
    public String getColumnName(int columnIndex){ // Nomes das colunas.
        return nomecoluna.get(columnIndex).toString();
    }

    @Override
    public Class getColumnClass(int columnIndex) { // Classe que representa a coluna
        return dadoscoluna.get(0).get(columnIndex).getClass();
    }

    @Override
    public void setValueAt(Object dados, int rowIndex, int columnIndex){ // Adiciona um dado a uma celula.
        dadoscoluna.get(rowIndex).add(columnIndex, dados);
        fireTableCellUpdated(rowIndex, columnIndex);
    }

    public void setTableEditable(boolean celledit){ // Seta a tabela será editável
        this.celledit = celledit;
        fireTableStructureChanged();
    }

    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex){ // Retorna se a celula é editavel
        return celledit;
    }

    public void addDados(List dados){ // Adiciona dados a tabela
        dadoscoluna.add(dados);
        fireTableRowsInserted(dadoscoluna.size()-1, dadoscoluna.size()-1);
    }

    public void removeDados(int rowIndex) { // Remove dados da tabela
        dadoscoluna.remove(rowIndex);
        fireTableRowsDeleted(rowIndex, rowIndex);
    }

    public List getRowData(int rowIndex){
        return dadoscoluna.get(rowIndex);
    }

}

Quando eu sobescrevo esse metodo a jtable fica copiando as celulas sozinhas, digamos

|Codigo|Nome |
|_||
|_||

Essa minha tabela terá suas celulas editaveis. Quando eu dou duplo clique em uma celula da coluna código e depois clico em qualquer outra celula da tabela, o valor que esta na celula que eu cliquei se copia para a celula da coluna ao lado, ou seja, para a celula da coluna nome.
Quando eu removo o metodo setValueAt do modelo o bug não acontece mais. O que pode estar errado com o mudelo?

Isso por que voce usa o método add em uma List e adiciona no index da coluna que voce queria sobrepor.
Mude de add em:

dadoscoluna.get(rowIndex).add(columnIndex, dados);   

Para

dadoscoluna.get(rowIndex).set(columnIndex, dados);   

MAS… seu TableModel está errado, ele deveria trabalhar com objetos e não com List.

Opa, mateus!

@Override public void setValueAt(Object dados, int rowIndex, int columnIndex){ // Adiciona um dado a uma celula. dadoscoluna.get(rowIndex).add(columnIndex, dados); fireTableCellUpdated(rowIndex, columnIndex); }

Acima, está o seu código…

1º: Como a Marky disse, teu TableModel tá errado. Ele deveria ser orientado a um objeto específico.
2º: Aqui vai um exemplo de um tableModel baseado em uma classe chamada Aluno, por exemplo:

public void setValueAt(Object data, int row, int col)
{
   int index = alunos.indexOf(data);
   
   if (col == COLCODIGO)  alunos.get(index).setCodigo(Integer.parseInt(data.toString()));
   if (col == COLNOME)  alunos.get(index).setNome(data.toString());
   if (col == COLTURMA)  alunos.get(index).setTurma( (Turma) data.toString());
}

Faça-o baseado em um objeto específico e poste de novo!

Abraços!

[quote=Nicolas Fernandes]Opa, mateus!

@Override public void setValueAt(Object dados, int rowIndex, int columnIndex){ // Adiciona um dado a uma celula. dadoscoluna.get(rowIndex).add(columnIndex, dados); fireTableCellUpdated(rowIndex, columnIndex); }

Acima, está o seu código…

1º: Como a Marky disse, teu TableModel tá errado. Ele deveria ser orientado a um objeto específico.
2º: Aqui vai um exemplo de um tableModel baseado em uma classe chamada Aluno, por exemplo:

public void setValueAt(Object data, int row, int col)
{
   int index = alunos.indexOf(data);
   
   if (col == COLCODIGO)  alunos.get(index).setCodigo(Integer.parseInt(data.toString()));
   if (col == COLNOME)  alunos.get(index).setNome(data.toString());
   if (col == COLTURMA)  alunos.get(index).setTurma( (Turma) data.toString());
}

Faça-o baseado em um objeto específico e poste de novo!

Abraços![/quote]

Um modelo para cada tabela do banco :shock: ?

[quote=matheusssilva]
Um modelo para cada tabela do banco :shock: ?[/quote]

Um modelo para cada JTable. Entretanto, você pode usar um TableModel parametrizado, como o Glazed Lists ( http://publicobject.com/glazedlists ) ou os que o ViniGodoy ou o Marky.Vasconcelos apresentaram.

Da um exemplo de um modelo generico usando objetos. Mas um exemplo simples apenas sobescrevendo os métodos necessários. Nada de soluções complexas com mais de 1000 linhas de código para ler.

Aqui no GUJ o Vini e o Mark tem essas soluções, mas por estarem muito completas o código é grande dificultando bastante a leitura.
Queria um exemplo simples de modelo generico usando objetos, com apenas os métodos necessários sem muitas frescuras, só o suficiente para carregar e pegar os dados das tabelas.
As soluções do Mark e do Vini são ótimas mas para ser usanda como base é ruin pois estão bastante robustas. É muita informação ao mesmo tempo.
Não quero usar soluções de terceiros quero usar a minha própria, simples e funcional, não pretendo distribuir, isso eu deixo pro pessoal que gosta de ficar extendendo a linguagem. Seria apenas para uso próprio.

Ah, esses métodos genéricos (parametrizados) são um pouco grandes, porque eles precisam fazer alguma introspecção (“reflection”) para funcionarem.
Vou dar um exemplo boboca.
Digamos que você crie um TableModel que é parametrizado em cima do seu DAO, por exemplo:

List<MeuDAO> dados = new ArrayList<MeuDAO>();
String[] titulos = {"Nome", "Endereco", "Telefone"};
String[] colunas = {"nome", "endereco", "telefone"}; // deve haver um "getNome", "getEndereco" e "getTelefone" no seu DAO
TableModel tm = new TableModelGenerico<MeuDAO> (MeuDAO.class, dados, titulos, colunas);

Essa classe TableModelGenerico, fora o fato de herdar de AbstractTableModel, precisa olhar nos campos de MeuDAO, e chamar os getters (e setters, se seu modelo não for apenas para leitura) correspondentes, de acordo com as colunas passadas no array colunas.

Uma coisa interessante do Glazed Lists, por exemplo, é que você não precisa ficar chamando “fire____” a torto e a direito quando precisa atualizar um dado em uma determinada linha e/ou coluna. A própria lista de objetos (que é um “EventList” nesse caso) se encarrega de chamar os “fire___” se você chamar os “set” ou “add” ou “remove” - um EventList é igualzinha a um ArrayList, mas também sobrecarrega os “set” ou “add” ou “remove” para chamar os “fire___” de forma otimizada (conforme você pode ver no site do Glazed Lists. Ele inventou um algoritmo super-otimizado para só dar os “fire___” quando realmente necessário. Se você olhar aqui no meu computador uma aplicação que estou para visualização de livros de ofertas funcionando (mercado de ações), nunca iria pensar que uma JTable pudesse atualizar tão rápido assim :slight_smile: