TableModel apontando para Object[][] incorreto

9 respostas
viniciusfaleiro

Ola pessoal… Criei um TableModel personalizado e to com um problema muito estranho… Quando meu objeto que guarda os dados da tabela ( Object[][]) está vazio e tento inserir uma nova linha no banco de dados atraves da interface gráfica meu programa gera uma exception ao chamar o método getValueAt(row,column). Bom… o que eu faço é ao inserir um novo registro no banco eu chamo o método atualizaModel() do meu TableModel para que ele pegue os novos valores do banco de dados e crie um novo array de Objetos com os dados encontrados… Ai vem o problema…

Antes de fazer a inclusão no banco e chamar o método atualizaModel() que cria um novo Object[][] pra mim dentro da mesma variável main_data… pelo que parece meu TableModel apontava para um objeto Ljava.lang.Object;@725967… porém… quando faço esse new Object[][] ele logicamente cria um novo objeto aparentemente com identificador Ljava.lang.Object@3d12a6… Porém… ao tentar chamar o método getValueAt() utilizado pela Jtable para criar a tabela… ele tenta buscar os dados no objeto Ljava.lang.Object;@725967 que está vazio ainda… gerando um nullpointerexception…

Somente depois q eu coloco o mouse em cima da linha da Jtable é que o meu model começa a referenciar o objeto correto … no caso o Ljava.lang.Object@3d12a6… e assim sucessivamente…

Não sei o que fazer… O máximo que cheguei foi até ai…

Segue o código…

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package TableModelsPersonalizados;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import commun.BDConection;
import commun.MyLogger;
import java.sql.PreparedStatement;
import java.util.ArrayList;
import java.util.Date;
import javax.swing.JOptionPane;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableModel;
import org.jdesktop.swingx.JXTable;

/**
 *
 * @author gs99860
 */
public class MyTableModel implements TableModel {

    private String SQL_UPDATE;
    private ArrayList<Object> list;
    private int ncolumns;
    private String[] names;
    private int[] columns;
    private int[] pk;
    private int[] popup;
    private Object[][] main_data;
    PreparedStatement select;
    private Object[] pk_keeped_values;
    private boolean has_a_change;

    public void setSelect(PreparedStatement s) {
        select = s;
    }

    public void setColNames(String[] n) {
        names = n;
    }

    public void setStringUpdate(String s) {
        SQL_UPDATE = s;
    }

    public void setEditableColumn(int[] col) {
        columns = col;
    }

    public void setPk(int[] primary) {
        pk = primary;
    }

    public void setPopups(int[] pop) {
        popup = pop;
    }

    public void keepPkValues(int row) {
        pk_keeped_values = new Object[pk.length];
        
        for (int i = 0; i < pk.length; i++) {
            pk_keeped_values[i] = this.getValueAt(row, pk[i]);
        }
    }

    public void atualizaModel() {

        if(main_data != null){
             System.out.println("Id data before insertion:" + main_data.toString());
        }
       
        try {
            
            
            ResultSet rs = select.executeQuery();

            ResultSetMetaData rsmeta = (ResultSetMetaData) rs.getMetaData();
            ncolumns = rsmeta.getColumnCount();

            list = new ArrayList<Object>();

            while (rs.next()) {
                for (int i = 1; i <= ncolumns; i++) {
                    list.add(rs.getObject(i));
                }
            }

        } catch (Exception e) {
            JOptionPane.showMessageDialog(null, "Erro Desconhecido:" + e.getMessage());

            e.printStackTrace();
        }

        main_data = new Object[list.size() / ncolumns][ncolumns];

        for (int j = 0; j < list.size(); j = j + ncolumns) {
            for (int i = 0; i < ncolumns; i++) {
                if (list.get(j + i) == null) {
                    main_data[j / ncolumns][i] = "-";
                } else {
                    main_data[j / ncolumns][i] = list.get(j + i);
                }
            }
        }
        
        System.out.println("Id data after insertion:" + main_data.toString());

    }

    public void atualizaLinhaBanco(int row, JXTable t1) {
        try {
            //Define Valores das PKS
            Object[] pk_values = new Object[pk.length];

            Connection con = new BDConection().getCon();
            PreparedStatement stm = con.prepareStatement(SQL_UPDATE);

            int values_count = 1;
            //Define todos os novos values
            for (int i = 1; i <= columns.length; i++) {
                System.out.println(this.getValueAt(row, i - 1));

                if (this.getValueAt(row, i - 1).toString().compareTo("-") == 0) {
                    stm.setString(i, null);
                } else {
                    if(this.getValueAt(row, i - 1).getClass() == new Date().getClass()){
                        java.util.Date date = (java.util.Date)this.getValueAt(row, i - 1);
                        java.sql.Date d1 = new java.sql.Date(date.getTime());
                        
                        stm.setDate(i,d1);
                    }else{
                        stm.setString(i, this.getValueAt(row, i - 1).toString());
                    }
                }

                values_count++;
            }

            //Seta os valores das PKS para condição WHERE
            for (int j = values_count; j < pk.length + values_count; j++) {
                stm.setString(j, pk_keeped_values[(j - values_count)].toString());
            }

            stm.execute();

            this.atualizaModel();

            has_a_change = false;

            t1.updateUI();
            t1.repaint();

        } catch (Exception e) {
            String msg = "Erro ao atualizar banco. Verifique os dados inseridos e se esse registro" +
                    " tem relações com outros cadastros!";

            e.printStackTrace();

            JOptionPane.showMessageDialog(null, msg);

            new MyLogger(msg, e);

            this.atualizaModel();

            has_a_change = false;
            
            t1.updateUI();
            t1.repaint();
        }
    }

    public boolean hasDataChange(){
        return has_a_change;
    }

    public int getColumnCount() {
        return names.length;
    }

    public int getRowCount() {
        return main_data.length;
    }

    public Object getValueAt(int row, int col) {


         System.out.println("Id data on getValue:" + main_data.toString());
        System.out.println("Linha:" + row + " Col:" + col);

        return main_data[row][col];
    }

    @Override
    public String getColumnName(int column) {
        return names[column];
    }

    @Override
    public Class getColumnClass(int col) {
        return getValueAt(0, col).getClass();
    }

    public boolean isCellEditable(int row, int col) {
        boolean is_editable = false;
        boolean pop = false;

        for (int i = 0; i < columns.length; i++) {
            if (columns[i] == col) {
                is_editable = true;

                break;
            }
        }

        for (int i = 0; i < popup.length; i++) {
            if (popup[i] == col) {
                pop = true;

                break;
            }
        }

        if (is_editable && !pop) {
            System.out.println("Verdadeiro:" + is_editable + " " + pop);

            return true;
        }

         System.out.println("Falso:" + is_editable + " " + pop);

        return false;
    }

    public void setValueAt(Object aValue, int row, int column) {
        Object old_value = main_data[row][column];

        main_data[row][column] = aValue;

        if(!old_value.equals(aValue)){
            has_a_change = true;
        }
    }

    public void addTableModelListener(TableModelListener l) {
    }

    public void removeTableModelListener(TableModelListener l) {
    }
};

9 Respostas

viniciusfaleiro

Pultz… ng se habilita?

fabiofalci

Ao invés de trabalhar com um tableModel que manipule Object[][] pq não usar
um que se baseia em List e em JavaBean? Facilita.

Procure no fórum pois o vinygodoy criou um e postou aqui.

Marky.Vasconcelos

Fora o do ViniGodoy tem o ObjectTableModel que tem o link na minha sign.

fabiofalci

Boa Mark! Não daria pra empacotar esse código num projetinho do github pra facilitar?

viniciusfaleiro

É… lá vou eu de novo… hahahahha…

fabiofalci

Bem vindo ao maravilhoso mundo da JTable! :wink:

Marky.Vasconcelos

Tenho mesmo… eu ia hospedar hoje no SourceForge… mas não achei uma descrição que falasse sobre o projeto inteiro e não só o TableModel.

ViniGodoy

Também acho que se for para fazer um model de object[][], então é melhor usar o DefaultTableModel de uma vez, já que é exatamente isso que ele é…
Entretanto, é também uma péssima abordagem usar o DefaultTableModel, embora seja ainda pior reimplementa-lo.

Nesse caso, aprenda a trabalhar corretamente com o TableModel. Isto é, internamente, seu model deverá ter uma lista de objetos da sua classe. Não haverá conversões, casts, nem coisas desse tipo.

viniciusfaleiro

Galera… vlw mesmo pelas dicas… de qualquer maneira encontrei o problema…

public Class getColumnClass(int col) {   
        return getValueAt(0, col).getClass();   
    }

Ele tentava buscar a classe da coluna antes de ter dados dentro do main_data…

agora ficou assim

public Class getColumnClass(int col) {   
        return Object.class
    }

Más prometo que vou estudar a opção de vocês para colocar aqui!! Vlw mesmo! :smiley:

Criado 19 de outubro de 2009
Ultima resposta 20 de out. de 2009
Respostas 9
Participantes 4