[RESOLVIDO]Problema com JTable

5 respostas
R
Boa noite. Estou tentanto usar o JTable através do Netbeans e estou tendo um problema para começar. A idéia é fazer uma tabela mostrar somente números inteiros que leio de um arquivo de texto. Eu primeiro leio o arquivo passo todos os valores para uma matriz e depois faço o JTable mostrar na tela. Li o tutorial http://devsv.wordpress.com/2012/07/08/como-implementar-um-tablemodel/ e tentei fazer mais ou menos igual. A primeira coisa que fiz foi estender a classe AbstractTableModel como mostrado abaixo:
import java.util.List;
import javax.swing.table.AbstractTableModel;

public class Tabela extends AbstractTableModel
{
      List<int[]> matriz;// Será uma matriz de valores inteiros que eu tentarei mostrar na tabela.

// O método abaixo receberá uma matriz já formada por outra classe e definirá ela como atributo desta classe para eu poder mostrar na tabela. Como não posso herdar a classe que contém a tabela, a única solução que encontrei foi essa.      
      public void setMatriz(List<int[]> matriz)
      {
            this.matriz = matriz;
      }
      @Override
      public int getRowCount()
      {
            return this.matriz.size();
      }

      @Override
      public int getColumnCount()
      {
            return this.matriz.get(0).length;
      }

      @Override
      public Object getValueAt(int rowIndex, int columnIndex)
      {
            throw new UnsupportedOperationException("Not supported yet.");
      }

}
Na classe "Inteface", que contém todos os objetos que mostrarei na tela, tentei instanciar JTable de um modo diferente do padrão feito automaticamente pelo NetBeans. Tentei imitar o que vi neste link: http://docs.oracle.com/javase/1.4.2/docs/api/javax/swing/table/TableModel.html#setValueAt%28java.lang.Object,%20int,%20int%29
TableModel myData = new MyTableModel(); JTable table = new JTable(myData);
Então lá na classe eu fiz assim:
// No momento em que faço a instanciação de Tabela, como abaixo, a matriz com os valores lidos do arquivo ainda não está formada.
private Tabela tab = new Tabela();
jTable1 = new javax.swing.JTable(tab);// A declaração de JTable não está aqui. Achei desnecessário mostrar.

Mas quando tento compilar, acontece a seguinte exceção:

Exception in thread "main" java.lang.NullPointerException
at Tabela.getColumnCount(Tabela.java:22)
at javax.swing.JTable.createDefaultColumnsFromModel(JTable.java:1290)
at javax.swing.JTable.tableChanged(JTable.java:4389)
at javax.swing.JTable.setModel(JTable.java:3691)
at javax.swing.JTable.(JTable.java:633)
at javax.swing.JTable.(JTable.java:574)
at Interface.initComponents(Interface.java:94)
at Interface.(Interface.java:15)
at Main.main(Main.java:16)
Java Result: 1

O que está acontecendo?

5 Respostas

H
robgeek:
Boa noite. Estou tentanto usar o JTable através do Netbeans e estou tendo um problema para começar. A idéia é fazer uma tabela mostrar somente números inteiros que leio de um arquivo de texto. Eu primeiro leio o arquivo passo todos os valores para uma matriz e depois faço o JTable mostrar na tela. Li o tutorial http://devsv.wordpress.com/2012/07/08/como-implementar-um-tablemodel/ e tentei fazer mais ou menos igual. A primeira coisa que fiz foi estender a classe AbstractTableModel como mostrado abaixo:
import java.util.List;
import javax.swing.table.AbstractTableModel;

public class Tabela extends AbstractTableModel
{
      List<int[]> matriz;// Será uma matriz de valores inteiros que eu tentarei mostrar na tabela.

// O método abaixo receberá uma matriz já formada por outra classe e definirá ela como atributo desta classe para eu poder mostrar na tabela. Como não posso herdar a classe que contém a tabela, a única solução que encontrei foi essa.      
      public void setMatriz(List<int[]> matriz)
      {
            this.matriz = matriz;
      }
      @Override
      public int getRowCount()
      {
            return this.matriz.size();
      }

      @Override
      public int getColumnCount()
      {
            return this.matriz.get(0).length;
      }

      @Override
      public Object getValueAt(int rowIndex, int columnIndex)
      {
            throw new UnsupportedOperationException("Not supported yet.");
      }

}
Na classe "Inteface", que contém todos os objetos que mostrarei na tela, tentei instanciar JTable de um modo diferente do padrão feito automaticamente pelo NetBeans. Tentei imitar o que vi neste link: http://docs.oracle.com/javase/1.4.2/docs/api/javax/swing/table/TableModel.html#setValueAt%28java.lang.Object,%20int,%20int%29
TableModel myData = new MyTableModel(); JTable table = new JTable(myData);
Então lá na classe eu fiz assim:
// No momento em que faço a instanciação de Tabela, como abaixo, a matriz com os valores lidos do arquivo ainda não está formada.
private Tabela tab = new Tabela();
jTable1 = new javax.swing.JTable(tab);// A declaração de JTable não está aqui. Achei desnecessário mostrar.

Mas quando tento compilar, acontece a seguinte exceção:

Exception in thread "main" java.lang.NullPointerException
at Tabela.getColumnCount(Tabela.java:22)
at javax.swing.JTable.createDefaultColumnsFromModel(JTable.java:1290)
at javax.swing.JTable.tableChanged(JTable.java:4389)
at javax.swing.JTable.setModel(JTable.java:3691)
at javax.swing.JTable.(JTable.java:633)
at javax.swing.JTable.(JTable.java:574)
at Interface.initComponents(Interface.java:94)
at Interface.(Interface.java:15)
at Main.main(Main.java:16)
Java Result: 1

O que está acontecendo?

A sua matriz está vazia uai!

this.matriz.get(0).length;

No índice 0 não tem nada por isso o NullPointerException, vocÊ está passando uma lista vazia para o construtor da classe Tabela.

R

Mas eu não implementei o construtor de Tabela! Ele é o default, achei que ele não fizesse nada com o atributo linha. Por isso implementei o método “setMatriz(List<int[]> matriz)”, ele sim faz acesso ao atributo “linha” da classe.
E em "return this.matriz.get(0).length; ", eu não chamei o método em parte alguma do código, porque então ele está dando erro? Ele deveria dar erro se eu chamasse ele, aí sim, seria passado algo nulo para ele.

V

Por que a tabela é quem vai chamar os métodos do seu TableModel. A tabela “pergunta” ao TableModel as informações que tem que desenhar.
É o papel do TableModel explicar isso para ela.

E, mesmo que você corrija, com certeza vai dar outra exceção, pq a tabela usa o método getValueAt, usado pela tabela para saber que valores ela deve desenhar, está disparando uma exceção sozinho.

Note que isso está escrito, inclusive, no próprio tutorial que você linkou:

Por que a JTable precisa de um TableModel?

A JTable chama os métodos do TableModel para obter informações sobre o conteúdo da tabela, como número de linhas e colunas, conteúdo de cada célula, etc. Com estas informações em mãos, ela pode montar os dados na tela corretamente.

R
Pessoal, resolvi o problema, muito obrigado. Vou dizer o que fiz. Primeiro, reimplementei o método getValueAt, fiz como está abaixo:
@Override
      public Object getValueAt(int rowIndex, int columnIndex)
      {
            Integer numero = this.matriz.get(rowIndex)[columnIndex];
            
            return numero;
      }
Depois, no método "private void jButton1ActionPerformed(java.awt.event.ActionEvent evt)" que é onde coloquei o código para ele ler o arquivo de texto que contém a tabela que quero mostrar, bem no final das instruções, depois que a matriz já está formada, coloquei o seguinte:
tab.setMatriz(this.hist.matriz);
                              this.jTable1.setModel(tab);

Achei que só podera passar minha tablemodel pelo construtor de JTable, aí olhei melhor na documentação java e vi o método setModel, aí tudo funcionou perfeitamente.

R

Obrigado, tópico encerrado.

Criado 9 de janeiro de 2013
Ultima resposta 9 de jan. de 2013
Respostas 5
Participantes 3