Lintz, realmete funcionou mas eu não consegui entender o porque! Eu criei esse meto e chamo ele no construtor
da minha Tela de Consulta simplismente.
public void AlteraCellRenderer() {
jtTabela.setDefaultRenderer(Object.class, new MyCellRenderer());
jtTabela.setDefaultRenderer(Integer.class, new MyCellRenderer());
jtTabela.setDefaultRenderer(Double.class, new MyCellRenderer());
jtTabela.setDefaultRenderer(Float.class, new MyCellRenderer());
}
Teria como vc explicar?
O unico problema que esta ocrrendo é esse Exception quando clico em uma celula que possui os tipos Double e Float
[quote]Exception occurred during event dispatching:
java.lang.NumberFormatException: For input string: “10.0”[/quote]
Mas uma vez eu agradeço a atenção. Realmete estou aprendendo muito com esse topico. Gostaria de saber tbm se vc conheçe algum livro que fale sobre os Models e Renderes tanto do JTable quanto do JComboBox e outros componentes que usam modelo, Estou fascinado com o que eles podem proporcionar, encontrei muito material legal na net mas são meio vagos. Quero realmente entender essas classes alguma dica?
Então, pega todos os topicos que eu te passei neste post que foi onde eu aprendi…quando eu nao sei sobre alguma coisa eu procuro tudo na net ou procuro no javadoc.Não precisa de livro…outra forma de vc aprender é ler bastante aqui no guj, principalmente mensagens e dicas que o ViniGodoy sempre posta aqui no guj.Realmente o cara conhece muito sobre Swing…
Abraços.
Outro problema que encontrei é o seguinte: Não consigo pegar o getValueAt correto de uma celula quando eu utilizo o RowSorter ou o RowFilter o problema esta aqui, mas não consegui resolver.
// lista (List<?> de beans)
public Object getValueAt(int rowIndex, int columnIndex) {
try {
Object objeto = lista.get(rowIndex);
for (Method m : classe.getDeclaredMethods()) {
Coluna c = m.getAnnotation(Coluna.class);
if (c != null && c.posicao() == columnIndex) {
return m.invoke(objeto);
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
return "";
}
Neste codigo eu pego o valor da celula pelo index da minha lista de beans, sendo assim quando eu aplico o RowSorter ou o RowFilter o meu getValueAt não funciona como esperado.
Josimarsis, vc não está usando os códigos que te passei, né?.Faz um teste usando os códigos que eu te passei… acredito que um dos problemas que vc tem vai resolver.
public Object getValueAt(int rowIndex, int columnIndex) {
try{
Object objeto = lista.get(rowIndex);
for(Method m : classe.getDeclaredMethods()){
Coluna c = m.getAnnotation(Coluna.class);
if(c != null && c.posicao() == columnIndex){
if(c.type == String.class){
return String.format(c.formato(), m.invoke(objeto));
}else{
return m.invoke(objeto);
}
}
}catch(Exception ex){
ex.printStackTrace();
}
return "";
}
//----------------------------------
public Class getColumnClass(int c) {
return getValueAt(0, c).getClass();
}
//----------------------------------
package comum;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Coluna {
String nome();
int posicao();
String formato();
Class type();
}
Abraços
Só uma coisa. A cada getValueAt a sua classe vai rodar a classe inteira procurando o método para pegar o valor.
Imagina uma tabela de 15 linhas apenas e 4 colunas. Isso já vai chamar o método getValueAt 60 vezes.
Seria bom voce pensar em algo melhor nessa parte.
Alguém viu o artigo que postei?
Nesse artigo tem o código e exemplos. Tudo que estão fazendo já esta pronto.
Bom, eu já usei desda maneira em alguns códigos e nunca tive problema. Posso afirmar que está muito bem testado…
Mas fica a dica ai para o josimarsis…
Abraços.
Olá galera estou com o seguinte problema: Não consigo pegar o getValueAt correto da minha JTable quando
utilizo o RowSorter ou o RowFilter. Segue abaixo a classe que estou utilizando como modelo:
[code]
package comum;
import java.lang.reflect.Method;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import javax.swing.table.AbstractTableModel;
public class TableModelPadraoParaBean extends AbstractTableModel {
private Class<?> classe;
private List<?> lista;
public TableModelPadraoParaBean(List<?> linhas) {
this.setLinhas(linhas);
if (linhas != null) {
this.classe = linhas.get(0).getClass();
}
}
public int getRowCount() {
if (lista != null) {
return lista.size();
} else {
return 0;
}
}
public int getColumnCount() {
int colunas = 0;
for (Method m : classe.getDeclaredMethods()) {
if (m.isAnnotationPresent(Coluna.class)) {
colunas++;
}
}
return colunas;
}
@Override
public boolean isCellEditable(int row, int col) {
return false;
}
@Override
public Class getColumnClass(int c) {
return getValueAt(0, c).getClass();
}
public void setLinhas(List<?> linhas) {
this.lista = linhas;
fireTableDataChanged();
}
public Object getValueAt(int rowIndex, int columnIndex) {
try {
Object objeto = lista.get(rowIndex);
for (Method m : classe.getDeclaredMethods()) {
Coluna c = m.getAnnotation(Coluna.class);
if (c != null && c.posicao() == columnIndex) {
if(c.formato() == Date.class){
return ConverteDataParaString(ConverteDataParaBanco(m.invoke(objeto).toString()));
}
return m.invoke(objeto);
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
return "";
}
@Override
public String getColumnName(int coluna) {
for (Method m : classe.getDeclaredMethods()) {
Coluna c = m.getAnnotation(Coluna.class);
if (c != null && c.posicao() == coluna) {
return c.nome();
}
}
return "";
}
public String ConverteDataParaString(Date date) throws ParseException{
DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
String data = formatter.format(date);
return data;
}
public Date ConverteDataParaBanco(String data) throws ParseException{
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
java.sql.Date date = new java.sql.Date(formatter.parse(data).getTime());
return date;
}
}[/code]
Metodo action onde eu crio o RowSorter e o RowFilter
[code]
private void jtfFiltroKeyReleased(java.awt.event.KeyEvent evt) {
// cria um TableRowSorter a partir do TableModelPadraoParaBean
final TableRowSorter sorter = new TableRowSorter(new TableModelPadraoParaBean(getLista()));
// Adiciona o objeto TableRowSorter à Tabela
jtTabela.setRowSorter(sorter);
String text = jtfFiltro.getText();
if (text.length() == 0) {
sorter.setRowFilter(null);
} else {
try {
// Cria um Filtro de pesquisa com base na coluna selecionada
sorter.setRowFilter(RowFilter.regexFilter(’^’ + text, getColuna()));
setStatusParaAtualizacao(false);
} catch (PatternSyntaxException pse) {
System.err.println("Erro");
}
}
} [/code]
Metodo action responsavel por setar a coluna de filtragem e setar o codigo que esta na primeira coluna que sera utilizado para efetuar as consultas necessarias para realizar as operações de Alteração e Deleção.
private void jtTabelaMouseClicked(java.awt.event.MouseEvent evt) {
if (evt.getClickCount() == 1 && jtTabela.getSelectedRow() >= 0) {
// Seta o indice da coluna selecionada para o RowSorter e RowFilter
setColuna(jtTabela.getSelectedColumn());
/* Seta o Codigo da primeira coluna
para realizar as consultas necessarias à alteração e exclusão de dados*/
setCodigoPesquisado(Integer.valueOf(((TableModelPadraoParaBean) jtTabela.getModel()).getValueAt(jtTabela.getSelectedRow(), 0).toString()));
setStatusParaAtualizacao(true);
}
}
Funciona perfeitamente desde que eu não utilize o RowSorter ou o RowFilter. Alguem tem uma dica? Grato!
Josimarsis, eu não tinha usado este RowSorter até então.
Não sabia como funcionava, então achei melhor ler sobre ele e acabei descobrindo o seu problema:
http://java.sun.com/docs/books/tutorial/uiswing/components/table.html
Quando um jtable usa um sorter, os dados que são vistos na view do jtable podem estar em uma ordem diferente do que o especificado pelo modelo(TableModelPadraoParaBean ) de dados, e pode não incluir todos os registros especificados pelo modelo de dados. Os dados que o usuário vê na verdade é conhecido como wiew, e tem seu próprio conjunto. JTable fornece métodos que converte de modelo para view:
- convertColumnIndexToView
- convertRowIndexToView
- convertColumnIndexToMode
- convertRowIndexToModel
Coloque este código e faça um teste…
int viewRow = table.getSelectedRow();
if (viewRow < 0) {
//Selection got filtered away.
System.out.println("");
} else {
int modelRow = table.convertRowIndexToModel(viewRow);
System.out.println( String.format("Selected Row in view: %d. " + "Selected Row in model: %d.",viewRow, modelRow));
}
Abraços.
Olá comunidade GUJ, Gostaria primeiramente de agradecer todos que me ajudaram neste tópico em especial ao Lintz. E afim de explicar a solução proposta e compartilhar o conhecimento adquirido estou disponibilizando o código fonte comentado bem como uma explicação da idéia envolta no desenvolvimento desta JTable Dinâmica. Obs: o script do banco de dados se encontra dentro da pasta do projeto
[b] JTable Dinâmica[/b]
O intuito era desenvolver uma JTable de consulta única que proporcionasse mecanismos de filtragem e ordenação e funcionasse para o sistema todo, e desta forma diminuir consideravelmente o tempo de desenvolvimento pois se levarmos em consideração que um sistema tem N telas e para cada tela temos uma consulta então teríamos N telas de consulta.
A idéia da JTable desenvolvida é definir consultas prontas em Views no banco de dados e criar Dao?s persistentes a partir destas Views, sendo assim a consulta seria realizada em cada view especifica. Você deve estar se perguntando o porquê da view ao invés da própria entidade persistente mapeada no banco de dados? A resposta é: quando criamos uma veiw ?Temos uma tabela virtual no banco de dados definida por comandos SQL? desta forma podemos recuperar campos com chave estrangeira de outra tabela e assim mapear estes campos no Dao criado a partir da view por intermédio de uma Annotation e assim lê-la dinamicamente utilizando Reflection.
[b]Tecnologias Utilizadas[/b]
JPA ? Java Persistence API;
Hibernate;
Banco de Dados ? Mysql 5;
Netbeans 6.5;
[b]Dicas para Entendimento[/b]
Para ser possível realizar a construção deste projeto foi necessário estudar:
Reflection ? Necessário para ler as Annotations ;
AbstractTableModel ? Pois Foi criado um modelo TableModel capaz de atender as necessidades exigidas.
Annotations ? Necessárias para mapear o Dao.
DefaultTableCellRenderer ? Para possibilitar os efeitos de seleção e o efeito zebrado da Tabela.
Muito legal.
Uma coisa que reparei olhando o código da sua tabela. Não é possivel ver apenas algumas colunas da tabela apenas todas que estiverem marcadas. Também não é possivel ver as variaveis das variaveis da classe.
Também não é possivel ver classes que voce nao tem acesso ao código fonte. Por exemplo a classe Calendar.
Aquilo de Date foi uma gambiarra por que a pessoa pode querer mudar o formato.
Eu já tinha resolvido essas questões e tinha colocado o link da que postei.
Mark_Ameba, eu sinceramente ja tinha baixado seu codigo e vi seu artigo e infelizmente não consegui entende-lo, por isso continuei com a construção da Tabela mesmo apos vc ter disponibilizado o codigo da que vc fez. Sou iniciante em java e gosto de programar mais como vc viu ainda não sou um profissional e meu ingles é muito basico tanto que ja estou procurando um meio de me matricular em um curso de ingles. Vou começar a desenvolver uma pequena aplicação e tive a ideia de tentar fazer algum mecanismo onde eu pudesse ter uma tabela dinamica ou seja uma JTable pra o sistema todo. Tive dificuldades em pegar campos que são chave estrangeira por isso utilizei a veiw. Utilizando seu modelo eu consigo recuperar dados de uma chave estrangeira?
Não sei se é pedir d+ mas acho que seria de enorme valia tanto pra mim quanto pra varias pessoas que enfrentam esse problema principamente os novatos. Seria possivel vc explicar as principais funcionalidades da sua tabela bem como os principais parametros para que ela funcione ou documenta - la escrito em Portugues?
Obrigado.
Ok. Vou traduzir o artigo que fiz. Eu só tinha feito em ingles pra ver se a ideia era aceita pela comunidade.
Ok! Creio que o entendimento da sua ideia e do seu codigo fonte sera de grande valia para a comuindade.
Sei que demorei um tempo. Mas finalmente. Ta ai.
Desculpe a formatação. Mas ainda não sei como deixo o código identado.
Valeu Mark! vou conferir, com certeza será de grande valia à comunidade. Obrigado!
Tenho esse codigo do rowsorter queria que filtrasse por inteiros, tem como finalidade pesquisar os alunos cadastrados queria que pesquisar usando o codigo dos alunos!!
Que mudanças tenho que fazer no codigo Alguem poderia me ajudar??
codigo:
public class rowSorter extends Converter {
private JTable table;
public JTable getTable() {
return table;
}
public void setTable(JTable table) {
this.table = table;
}
public Object convertForward(Object value) {
return value.toString();
}
public Object convertReverse(Object mask) {
TableRowSorter sorter = new TableRowSorter(table.getModel());
sorter.setRowFilter(RowFilter.regexFilter("." + mask + "."));
return sorter;
}
}