Projeto Towel: AutoFiltro em JTable

Boma noite ao pessoal do forum.

Sou iniciante em Swing e estou penando na parte de tabelas.
Baixei o exemplo do Vini mas nao consegui adaptar para uma tabela vinda do banco de dados com varias colunas.
Como exemplo tenho uma tabela de Municipios que teria os campos codEstado, codigo e descricao.
Minha pergunta é como implementar a enumeracao para que receba os tres valores. No exemplo é recebido somente
uma .

É possivel receber um vetor (por exemplo) ou a propria classe “municipio” ? como fica a declaracao ?

public enum apMunicipio implements Column { // como fica a a substituicao do para vincular aos campos abaixo
codEstado {
public Object getValue(String element) {
return element;
}
},
codigo {
public Object getValue(String element) {
return element;
}
},
descricao {
public Object getValue(String element) {
return element;
}
}
;

Obrigado

Só com uma String fica impossível. Você precisa de uma lista de Municipios, então, crie uma classe Municipio contendo os três valores e faça um Column<Municipio>.

Boa tarde galera!

Bom eu sou novo em programação java e estou estudando esse modelo de tabela porque até então eu usava a DefaultTableModel.
Mas eu não estou entendendo como eu adiciono as colunas nessa tabela.
Alguem me ajude por favor!

desde já agradeço

Você está tentando usar qual modelo? O Auto-Filtro não é um modelo, é só o filtro.
Junto ali tem o ColumnTableModel, é o que você está usando?

Eu recomendo que você use o ObjectTableModel, do Mark.

Sim, eu estou tentando usar o ColumnTableModel.

Bom eu acho q eh isso, me fale se eu estiver errado.

Eu tenho q criar um outro Enum implementando a classe Column, e lah eu adiciono as colunas?

outra coisa, qualquer um desses modelos funciona bem com o Hibernate?

obrigado

Mas de qualquer forma eu vou estudar o modelo do mark.

Vini eu queria uma opinião sua.

Eu sou recem formado em Sistemas de Informação, eu vi java na faculdade, mais foi basico.
Ai vai minha pergunta: como vcs sabem tudo isso de java, apenas estudando em livros, ou com cursos?
Eu estou estudando o livro Java como Programar do Deitel e tbm o manual do Hibernate, mas tem coisas que são difíceis de entender.

oq vc me sujere, para eu aprender melhor sobre java.

obrigado pela atenção.

Oi.

Fiz segundo grau Técnico em Processamento de Dados, na UFPR. Também me formei em Informática pela UTFPR. E ainda tenho pós-graduações em Jogos Digitais pela Universidade Positivo, além de 15 anos de profissão.

Então, como a gente sabe tanto de java? Estudando, trabalhando e ralando pra xuxu. :slight_smile:

É importante não querer fazer as coisas nas coxas. Tem muita gente que se acomoda e simplesmente “faz funcionar”, sem se preocupar se está ou não usando as melhores práticas, ou com manutenção futura. Se você começar a codificar sem entender o que está fazendo, está com um problema.

Para usar o ColumnTableModel, você deve criar um Enum de columns da sua classe de negócio. Ela certamente não será a classe String. O model funciona perfeitamente bem com Hibernate.

Por exemplo, qual é a sua classe de negócio que você quer exibir na tabela? Pode posta-la aqui? Se for uma tabela de clientes, a classe provavelmente será Cliente. Se for de produtos, será Produto. Enfim, que classe vc quer exibir na tabela?

Como eu estou utilizando uma classe simples apenas para estudo. Se eu entender o funcionamento basico o resto eu me viro bem.

estou utilizando a classe PessoaDTO (Modelo MVC).

ai esta a minha classe.

package br.com.JavaHibernate.DTO;

public class PessoaDTO
{
private String nome, rg, cpf, sexo;
private int id_pessoa;

//Metodos set's e get's ocultos.

}

Oi,

Uma dica: quando postar código aqui no fórum, ponha entre as tags code:
[code]
Seu código aqui
[/code]

Ok. Vamos fazer com sua classe simples.
Embora seja apenas um DTO (você deveria fazer o model sobre as classes quentes, não sobre os DTOs).

O columnTableModel trabalha com duas interfaces. A Column (para colunas read only) e a EditableColumn (para as editáveis). No caso, vamos fazer uma tabela não editável.

[code]public enum PessoaColumns implements Column<PessoaDTO> {
ID("Id") {
//Esse método precisa retornar para o table o ID da pessoa
public Object getValue(Pessoa p)
{
return p.getId();
}
},
NOME("Nome") {
public Object getValue(Pessoa p)
{
return p.getNome();
}
},
RG("R.G.") {
public Object getValue(Pessoa p)
{
return p.getNome();
}
};

//Daqui para baixo, são configurações que valem para todas as colunas
private final String nome;

private PessoaColumns(String nome) {
this.nome = nome;
}

public Class< ? > getColumnClass() {
return Object.class;
}

public String getName() {
    return nome;
}

public TableCellRenderer getRenderer() {
return null;
}

public int getModelIndex() {
    return ordinal();
}

public int getWidth() {
    return 100;
}

}[/code]

Agora, bastaria fazer um ColumnTableModel<PessoaDTO> e passar as colunas desse enum para ele. E sua tabela já sairia funcionando.

Oi, ja estou entendendo, e vou parar de tomar seu tempo …hehehe…, mas eu soh gostaria de saber:

Eu não entendi sobre classes quentes.

no construtor do codigo q vc me passou, o Enum aceita apenas o modificador private e nao public como vc utilizou, posso deixar como private?

obs: ate hj eu nao tinha visto um construtor private!!

Porque vc me aconselha o modelo do mark (ObjectTableModel)?
É melhor q esse?

e eu consegui colocar as colunas na tabela. Muito obrigado mesmo pela grande ajuda.

obrigado.

Oi Vinny! Eu estou tentando fazer funcionar o seu modelo de TableModel mas estou tendo problemas na hora de setar as colunas…

estou fazendo dessa forma:

 public void preenche_jtable(JTable MostraTabela, String nome) throws PersistenciaException
    {  

  ArrayList lista = new ArrayList();
        ClienteVO cli = null;
       
        String comandoSQL = "SELECT idCliente, nCartao, nome, telefone,celular, email FROM Cliente WHERE nome LIKE '" + nome.trim() + "%' ORDER BY nome";

        try {
             PreparedStatement comando = con.getConexao().prepareStatement(comandoSQL);
            ResultSet rs = comando.executeQuery();
         //   ColumnTableModel modelo = (ColumnTableModel) MostraTabela.getModel();
            //modelo.setNumRows(0);
            while (rs.next()) {
               cli = new ClienteVO();

                //.set(rs.get(""));
                cli.setId(rs.getInt("idCliente"));
                cli.setnCartao(rs.getString("nCartao"));
                cli.setNome(rs.getString("nome"));
                cli.setTelefone(rs.getString("telefone"));
                cli.setCelular(rs.getString("celular"));
                cli.setEmail(rs.getString("email"));
                lista.add(cli);



            }
            comando.close();
           
           ColumnTableModel modelo = new ColumnTableModel(lista);
          
           MostraTabela.setModel(modelo); 

        } catch (Exception ex) {
            throw new PersistenciaException(ex,"Erro na seleção por Nome");
        }
}

O erro que aparece é este: “You must provide at least one column!”

Eu nao estou entendendo esta parte de setar o numero de colunas…

vc pode me explicar?

Obrigada.

Dê uma olhadinha no construtor. Ele aceita 2 parâmetros, não 1.

Você deve passar para ele a definição das colunas com as quais ele vai trabalhar (veja o exemplo que dei ao caceres, na página anterior).

No caso, são as que você criou naquele enum.

[code]//Pegamos as colunas do enum
Column<ClienteVO> colunas = ClienteVOColumns.values();

//Passamos para o model
ColumnTableModel modelo = new ColumnTableModel(lista, colunas); [/code]

[quote=caceres]Porque vc me aconselha o modelo do mark (ObjectTableModel)?
É melhor q esse?[/quote]

O do Mark é mais automático. Não exige tantas definições. Trabalha com anotações.

E pode deixar o construtor private sim, era o jeito certo, eu que me enganei.

De qualquer forma, ambos os modelos trabalham diretamente com sua classe de negócio, e não com aquela abominação de Vectors de Vectors de Objects que o DefaultTableModel faz. Nenhum deles exige que você use o getValueAt ou setValueAt diretamente. Sem casts, sem nada. Basta usar o get() e obter um objeto completo, do seu tipo. E o objeto terá, por exemplo, o getId() mesmo que o ID não esteja sendo exibido na tabela.

Nenhum deles faz qualquer tipo de cópia desnecessária de dados, e o Default trabalha baseado em cópias.

Ambos são super simples de usar, mais ainda de manter.

Além disso, ambos permitem que você faça as operações básicas como remover ou adicionar objetos ao modelo. Tudo usando os tipos corretos, reduzindo chances de bugs.

O DTO não é sua classe de negócio. Pelo menos, não deveria ser. Como o nome do padrão já diz é apenas um “Data Transfer Object”. Uma classe que você usa para transportar dados entre camadas diferentes da sua aplicação.

Se você usa-la como classe mesmo, estará criando um modelo anêmico, que deve ser evitado. Eu dificilmente uso DTOs, pois na minha opinião (também) eles vão contra o próprio princípio básico de se ter OO em primeiro lugar. Bem, esse assunto é tema para muita discussão.

Quando falei em classes quentes, falei para você usar as classes de negócio mesmo dentro do model, não os DTOs.

[quote=caceres]Porque vc me aconselha o modelo do mark (ObjectTableModel)?
É melhor q esse?[/quote]

Fora isso, a unica razão de eu e Vini termos implementado um TableModel pratico é que eu construi o meu sem saber da existencia do dele, pois provavelmente eu teria usado esse também.

Mas de qualquer forma… o resultado acabou ficando mais simples mesmo.

Obrigado ViniGodoy e Marky. Vou estudar essas melhores praticas dialogadas.
É engraçado q, eu acabei de me formar e ja vejo que algumas coisas q eu aprendi não é uma das melhores opções. (DTO’s da vida).
Eu só pesso um favor a quem puder ai. Mostrar algum tópico onde exemplifica o modelo de desenvolvimento em camadas sem o DTO.
Pode ser em forma de UML, desenhos no paint, qualquer coisa. Mas de qualquer forma eu estou estudando toda essas “novidades”.

Se não for incomodar é claro.
Obrigado, e vcs sao fera msm… hehehe
abraço a todos

O problema não está na existência de DTOs, per-se.
Mas os DTOs tem um propósito: servir de objetos de transporte para otimizar o uso de rede.
As versões mais modernas de EJB já dispensam a existência de DTOs em boa parte dos casos.

Mas, se você estudar a modelagem de objetos básica, vai ver que geralmente a lógica e os dados caminham juntos. Esse é o princípio da OO. E o que dizem os DTOs? Geralmente o contrário. Os DTOs nada mais são que agrupados de dados com gets e sets e, fora deles estão métodos para processar esses dados.

Mas conjuntos de dados separados das funções que as processam tem um nome: programação estruturada. DTOs não são muito diferentes de structs, assim como objetos sem atributos não são muito diferentes de namespaces de funções.

Quanto à referências, fica difícil te indicar uma assim, de bate e pronto. Mas você vai cruzar com bastante enquanto estiver estudando arquitetura. A maioria está em livros, como os do Fowler (inclusive o pattern DTO também está descrito no livro dele).

Ah, removi o seu e-mail do tópico anterior. Não poste e-mails aqui na área pública do GUJ, pq os bots de internet não perderão tempo em encontra-lo e te enviar muito lixo. Lembre-se, o fórum é publico para esses programinhas maldosos de e-mail marketing também. :wink:

Bom. Por mim esta encerrado. Obrigado, desculpas em perguntar um assunto fora do tópico (AutoFiltro em JTable).
Mas acho q pode ter ajudado mais pessoas tbm.
:smiley:

Boa tarde.

Alguém pode me informar onde eu altero as configurações da largura da coluna no JTable com o AutoFiltro (modelo do Vini), para ficar do tamanho da maior string da coluna que foi pega no banco de dados.

Eu tentei analisar o post no começo desse tópico que fala sobre isso, mas não entendi.

E tem como eu bloquear as colunas da tabela para que não sejam trocadas de lugar umas com as outras, com o mouse?

desde já agradeço.

Da um ligo nesse código que coloquei junto com meu projeto.

http://code.google.com/p/markutils/source/browse/trunk/src/mark/utils/swing/table/Resizer.java
Só adicionei o método fitAllColumns e aproveitei o código de um amigo aqui do fórum.
Ele faz o resize para o maior conteudo das celulas.