Problema ao exibir dados JTable

14 respostas
malves_info

Ae galera estou com problema em exibir meu dados do banco na Table. Defini as linhas para receber os dados do tipo Object pois utilizo para outros fins Ex.: colocar um botão em uma coluna. Bom o problema que os dados estão sendo exibidos assim: Ex.: " [Ljava.lang.Object;@6eb38a ". Utilizo o modelo Default.Segue abaixo o fonte:

public class JTableGeneric extends JTable{
	
	private DefaultTableModel model = null;
	private Object[][] linhas = null;
	private String[] colunas = null;
	
	
	public JTableGeneric(String[] colunas){
		this.colunas = colunas;
		this.linhas = new Object[1][colunas.length];
		model = new DefaultTableModel(this.linhas,this.colunas);
	}
	
	
	public void popularJTable(ResultSet rs,int opcaoTemp)throws SQLException{
		
		ResultSetMetaData rsmd = rs.getMetaData();
		
		int r = 0;
		rs.last(); 
		r = rs.getRow(); 
		rs.beforeFirst();
	
		Object[][] linhaNova = new Object[r][model.getColumnCount()];

		r = 0;
		//Enquanto existir dados ele preenche o atributo linhaNova
		while(rs.next()){
		   if(opcaoTemp == 0){	
			for(int i=0; i < rsmd.getColumnCount(); i++){
				
				switch (rsmd.getColumnType(i + 1)) {
					case Types.INTEGER: 
							linhaNova[r][i] = rs.getInt(rsmd.getColumnName(i + 1));
							break;
					case Types.VARCHAR:
							linhaNova[r][i] = rs.getString(rsmd.getColumnName(i + 1));
							break;
				}
				
			}
			model.addRow(linhaNova);
			r++;
	     }else{
		       for(int i=0; i < rsmd.getColumnCount(); i++){
		    		   linhaNova[r][i] = rs.getString(rsmd.getColumnName(i + 1));
		       }
	    	model.addRow(linhaNova);
	    	r++;
	       }
		}	   
		this.setModel(model);
	}
	
}

Quem puder ajudar eu agradeço!!.. []'s

14 Respostas

kicolobo

Basta sobrescrever o método toString() dos objetos que serão expostos no seu JTable.

Caso contrário, será exposto algo como [nome da classe]@[endereço da memória], tal como você expôs, que é como o método toString encontra-se definido na classe java.lang.Object

malves_info

Sim vou sobrescrever mas o que vou colocar nesse método??? como ele vai ser chamado?

kicolobo

Este método deve retornar a representação do conteúdo do objeto no formato de uma String.
O conteúdo que você quer expor na sua JTable por exemplo.

malves_info

Se eu passar o atributo linhas para “String[][]” resolveria?

kicolobo

É uma solução tosca, mas resolveria.

malves_info

Realmente é tosca, mas não resolveu. Bom vou utilizar por exemplo o atributo linhaNova que é Object para guardar os dados , e como me disse implementar o método toString para incluir estes dados na JTable, mas não sei de que forma vou utilizar o método toString para retornar estes valores, se tenho que converter os dados em String e passar no método addRow, mas pensando nisso cai na mesma teoria se eu utilizasse o atributo linhaNova como String. Se puder dar um exemplo agradeço!

kicolobo

Na realidade, você não precisa fazer nada.

O objeto JTable, quando é impresso, já chama o método toString na hora de gerar a visualização.

malves_info

Poise na teoria era pra mostrar os dados corretamente, não estou mais implementado o toString por pensar tbm que o JTable ja chama esse método internamente… agora ferrou tudo!..

kicolobo

Aí que tá: então vai continuar aparessendo [nome da classe]@[endereço], pois quando for chamar o método toString, vai chamar aquele que encontra-se implementado por default (da classe java.lang.Object), e não o que você for sobrescrever, entendeu?

Logo, se você não sobrescrever, NUNCA vai aparecer o valor correto, a não ser que você, no método getValueAt do seu TableModel, chame o método equivalente que retorne uma representação correta no formato String, sacou?

malves_info

Estou implementando o método toString e encontrei outro problema, na ideia eu utilizaria o método toString para pasar meu dados em Object para String , mas o método toString retorna um tipo String normal e não Vector String[][] como é utilizado por mim e pelo addRow. E Também converter de Object para String :frowning:

kicolobo

Reparou que o método getValueAt do seu TableModel retorna um objeto do tipo Object?

É só retornar o objeto, e o seu método toString será chamado em seguida.

malves_info

Me desculpe mas não entendi. vou postar como estou implementando meu toString:

public String toString() {
		String[][] linhasAux = null;
		
		for(int i = 0; i < linhas.length; i++){
			for(int c = 0; c < linhas[c].length; c++){
				if(linhas[i][c] != null)
					//??? Da problema nessa conversão
					linhasAux = (String[][])linhas[i][c];
			}
		}
		//???
		return linhasAux;
	}

Método toString eu iria executar ao chamar o addRow na linha 42 no fonte que postei no inicio. Não seria assim?

kicolobo

Entendi a confusão:
seguinte: não é pra você implementar o método toString do TableModel, mas sim dos objetos que este manipula.

Pelo que estou vendo, você tentou criar um TableModel que sirva pra qualquer coisa, correto?
Bem, o problema é que… bem: no final das contas, você vai acabar vendo que esta idéia é inviável.

Pense comigo: vou te dar um exemplo: um tableModel que gerencie classes do tipo Pessoa, tal como definida abaixo

class Pessoa {
     String nome
     String cidade
     String qualquerCoisa
     Pais pais; // suponha que exista no seu sistema uma classe Pais
    // gets e sets  pra baixo você ignora
}

No seu TableModel, o que você está fazendo (aliás, nem é o TableModel, você está criando uma nova implementação da classe JTable):
os seus dados estão na forma:

Object[][] linhas = null;
  String[] colunas = null;

Para trabalhar com a classe acima, você teria de definir o valor da matriz colunas, assim como da matriz bidimensional linhas com os valores que você quer.
Ou seja, daria muito mais trabalho!

O mais interessante, é você implementar um TableModel (dê uma olhada na classe javax.swing.table.AbstractTableModel), pois nele você terá um método chamado getValueAt(int column, int row) que será implementado mais ou menos assim:

public class TableModel extends javax.swint.table.AbstractTableModel {

 List<Pessoa> pessoas = conteudo; // imagine gets e sets relacionados
 ...
   public Object getValueAt(int column, int row)
   {
       Pessoa pessoa = pessoas.get(row);
       switch (column)
       {
           case 0: return pessoa.getNome();
           case 1: return pessoa.getCidade();
           case 2: return pessoa.getQualquerCoisa(); // bla bla bla
           case 3: return pessoa.getPais(); // neste caso, na hora da exposição, o método toString da classe Pais será chamado
        }
   }
 ...}

No mesmo TableModel, você reimplementará o método que define o nome das colunas

public String getColumnName(int column)
   {
                switch (column)
                {
                    case 0: return "Nome;
                    case 1: return "Cidade";
                    // bla bla bla
                 }
   }

E, se quiser, pode reimplementar todos os métodos responsáveis pelo comportamento do TableModel. Assim você consegue ter um controle total sobre o que está fazendo.
Claro agora?

Na realidade, no Swing, você não precisa reimplementar a classe JTable. Basta criar a sua própria versão do TableModel, ou extendendo a classe AbstractTableModel ou implementando a interface TableModel. É bem mais tranquilo.

PS: vai por mim, o JTable genérico é perda de tempo como você vai perceber daqui a pouco.

malves_info

Eu já tenho uma classe que implementa TableModel… não estou utilizando ela por que fui inlcuir botões em uma coluna da Table e ele fica bloqueado e usando o DefaultTable funciona normal, tenho isso postado aqui no forum se souber o que pode ser ai resolve de vez o problema:
http://www.guj.com.br/posts/list/97926.java

Criado 25 de julho de 2008
Ultima resposta 25 de jul. de 2008
Respostas 14
Participantes 2