Popular JTable

8 respostas
F

Boa tarde pessoal,

Sou novo aqui e estou começando a me aventurar no mundo Java. Várias dúvidas vem surgindo e com muita pesquisa encontra as respostas, mas neste caso não consegui achar nada.

Estou desenvolvendo uma aplicação aqui no trabalho. No meu frame principal coloquei uma tabela de 4 colunas, onde as ações tomadas pelo usuário, devem ser mostradas (uma espécie de histórico em tela). Na primeira coluna entrará um ícone mostrando se foi bem sucedida a ação ou não, no segundo o que foi feito (Programa Iniciado, alteração de alguma configuração), no terceiro o dia e a hora em que ocorreu e no quarto apenas uma mensagem falando que já foi concluído.

Acontece que eu criei um Internal Frame para as configurações e ao salvar esta alteração, não consigo mandar ele gravar a ação numa nova linha da tabela que está no meu Frame principal.

O que vocês me sugerem fazer?

Obrigado.

8 Respostas

guilherme.dio

Implemente seu TableModel !

Use o AbstractTableModel.

F

Poderia me explicar melhor? Como eu disse, estou começando a me aprofundar mais em Java agora, portanto alguns conceitos eu ainda não entendo.

Rocklee6544

Vc tem que extender abstract table model

package br.com.caelum.argentum.ui;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;

import javax.swing.table.AbstractTableModel;

public class MinhaTabela<E> extends AbstractTableModel{

	List<E> lista;
	Method[] metodos;
	Field[] campos;
	
	public MinhaTabela(List<E> lista) {
		this.lista = lista;
		Class<?> classe = lista.get(0).getClass();
		metodos = classe.getMethods();
		campos = classe.getFields();
	}

	@Override
	public int getColumnCount() {
		return metodos.length;
	}

	@Override
	public int getRowCount() {
		return lista.size();
	}

	@Override
	public Object getValueAt(int linha, int coluna) {
		try {
			E obj = lista.get(linha);
			return metodos[coluna].invoke(obj);
		}  catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

}
Rocklee6544

Vc deve extender AbstractTableModel
E implementar alguns de seu métodos.

No exemplo abaixo eu crio um tableModel para qualquer tipo de objeto.

A Tabela modelo descobre quantos métodos e atributos tem na classe que eu desejo trabalhar
e invoca o seus métodos get para exibir em um grid.

package br.caelum.argetum.util;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import javax.swing.table.AbstractTableModel;

public class GenericTableModel extends AbstractTableModel{

	private List lista;
	private Field[] campos;
	private List<Method> metodosGet;
	
	public GenericTableModel(List lista) {
		if(lista.isEmpty()){
			throw new IllegalArgumentException("Lista não pode ser vazia");			
		}
		
		Class<?> classe=lista.get(0).getClass();
		campos = classe.getDeclaredFields();
		metodosGet=new ArrayList<Method>(); 
		for (Method metodo :  classe.getMethods()) {
			if(metodo.getName().startsWith("get")){
				metodosGet.add(metodo);
			}
		}
		
		this.lista = lista;
	}

	@Override
	public int getRowCount() {
		return lista.size();
	}

	@Override
	public int getColumnCount() {
		return campos.length;
	}

	@Override
	public Object getValueAt(int linha, int coluna) {
		Object negocio = this.lista.get(linha);
		
		try {
			Object invoke = metodosGet.get(coluna).invoke(negocio);
			return invoke;
		} catch (Exception e) {
			e.printStackTrace();
		}
		 
		return null;
	}
	
	@Override
	public String getColumnName(int column) {
		return campos[column].getName();
	}

}
paulork

Você poderia nos dar um exemplo pratico de uso pra essa sua classe aí acima?

agradeço…

Rocklee6544

Desculpa pela demora aqui em casa eu fiz com anotação, devo confessar que sem annotations apanhei para fazer.

No modelo de negócio que eu fiz , eu utilizei apenas métodos get, então não tive nenhum problema.

Mas ao criar um exemplo pra vc tive alguns problemas. Pois neste caso existia alguns métodos set.

A solução que eu pensei para o teste foi essa:

Classe Contato:
package br.com.agenda.bean;

import java.util.Calendar;
import java.util.List;

public class Contato {
	private Integer id;
	private String nome;
	private String endereco;
	private String email;
	private Calendar dataNascimento;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	

	public String getNome() {
		return nome;
	}
	public void setNome(String nome) {
		this.nome = nome;
	}
	public String getEndereco() {
		return endereco;
	}
	public void setEndereco(String endereco) {
		this.endereco = endereco;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public Calendar getDataNascimento() {
		return dataNascimento;
	}
	public void setDataNascimento(Calendar dataNascimento) {
		this.dataNascimento = dataNascimento;
	}

	
}
Classe TesteReflection:
package br.com.agenda.bean;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;

public class TestaReflection<E>{
	private List<E>lista;
	private Field[] campos;
	private Method[] metodos;
	
        //método recebe  uma lista de Objetos qualquer e o tipo de Classe
	public TestaReflection(List<E> lista,Class<E> classe) {

                //obtem o vetor(Array) de campos(atributos) da classe
		this.campos = classe.getDeclaredFields();

                //Obtem um vetor de métodos da classe
		this.metodos = classe.getDeclaredMethods();

                //inicializa a lista da classe
		this.lista = lista;
	}
	
	
	public Object getValueAt(int linha, int coluna) {

                /*pega o objeto da lista . Não se  preocupe com o E, é simplesmente um coringa que diz que a sua classe trabalha 
                com determinado tipo objeto. 
               ex: new TestaReflection<Contato>(); diz que todo E é  visto como um tipo Contato     
               Esse tipo de classe é se chama classe parametrizada */

		E negocio = this.lista.get(linha);
		
		try {
                        //para cada metodo  de metodos pega  nome do metodo.
			for (Method metodo : metodos) {
                                /*se nome  começar com get o metodo é invocado. O metodo invoke precisa saber de qual objeto
                                ele invocará o método, por este motivo passamos negocio*/
				if(metodo.getName().startsWith("get")){
					Object invoke = metodo.invoke(negocio);
					System.out.println(invoke);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		 
		return null;
	}
}
Main:
package br.com.agenda.bean;

import java.util.ArrayList;
import java.util.List;


public class TestaContato {
	public static void main(String[] args){
		Contato contato = new Contato();
		contato.setNome("João Henrique");
		contato.setEmail("[email removido]");
		
		Contato contato2 = new Contato();
		contato2.setNome("João Henrique");
		contato2.setEmail("[email removido]");
		
		List<Contato> lista=new ArrayList<Contato>();
		
		lista.add(contato);
		lista.add(contato2);
		
		TestaReflection testaReflection = new TestaReflection(lista,Contato.class);
		
		testaReflection.getValueAt(1,1);
	}
}
[color=red]Nesse caso nem precisava passar o Class como parâmetro para o construtor , só precisava pegar o objeto e chamar seu método getClass() para obter o molde do mesmo.[/color]
R_chieck

Ola, caso não quiser ou não conseguir implementar o seu pode usar a biblioteca Towel do Mark

https://github.com/MarkyVasconcelos/Towel
la tem diversas classes uteis, e inclusive uma ObjectTableModel genérica, ou seja não precisará criar uma para classe

P

Pessoal, apesar de todas as dicas, ainda não consegui identificar o que está ocorrendo no meu caso. O sistema não mostra nenhum erro mas o jTable some da tela (já tentei colocar o setVisible mas não resolve).

try {
            while (rsLupa.next()) {
                int cont = 0;
                int cod = rsLupa.getInt("cod");
                String razSocial = rsLupa.getString("razSocial");
                String fantasia = rsLupa.getString("fantasia");
                String cnpj = rsLupa.getString("cnpj");
                String cpf = rsLupa.getString("cpf");
                if (cnpj == null) {
                    //Atribuir valor com CPF
                    modelo.addRow(new Object[]{cod, razSocial, fantasia,cpf});
                } else {
                    //Atribuir valor com CNPJ
                    modelo.addRow(new Object[]{cod, razSocial, fantasia,cnpj});
                }
            }
            System.out.println(modelo);
            jTable1.setModel(modelo);//adiciona o modelo a tabela criada para consulta
            //jTable1.setVisible(true);
        } catch (SQLException ex) {
            Logger.getLogger(TelaLupaCliente.class.getName()).log(Level.SEVERE, null, ex);
        }

Outra coisa que foi percebida é que quando eu tento imprimir o modelo ele mostra somente o endereço do objeto, apesar das informações das viriáveis (razSocial, fantasia, etc) estarem gravadas corretamenta.

Alguem pode me ajudar?

Criado 21 de maio de 2012
Ultima resposta 12 de ago. de 2012
Respostas 8
Participantes 6