[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

Henrique.tenorio
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.

ViniGodoy

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