JTable Dinamica!

É isso mesmo 71C4700… vc está certo.

Tem que implementar uma logica que já retorne com o tipo desejado, pois, hj ele retorna tipo String.Mas o método public Class getColumnClass(int c) deve continuar,pois, é ele que informa ao jtabel para qual tipo converter,já que o método getValuAt(int c) retorna Object…

Pense em alguma lógica para retornar com o tipo apropriado… vc pode utilizar o método que o nosso amigo Mark_Ameba te passou, para isso.

Se não conseguir avisa.

Abraços.

Galera creio que o problema esta aqui oh, na criação da minha annotation:

[code]
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 {
//vamos utilizar esta annotation para pegar o nome da coluna,posicao no jtable e o formato que queremos mostrar
String nome();
int posicao();
String formato() default “%s”; // Como eu faria para esse formato ser o formato que eu desejasse? onde eu encontro esses fomatos?
}[/code]

no meu bean eu faço assim oh:

[code]
package bean;

import comum.Coluna;
import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;

/**
*

  • @author rh
    */
    @Entity
    @Table(name = “cliente”)
    @NamedQueries({@NamedQuery(name = “Cliente.findAll”, query = “SELECT c FROM Cliente c”), @NamedQuery(name = “Cliente.findByCliCodigo”, query = “SELECT c FROM Cliente c WHERE c.cliCodigo = :cliCodigo”), @NamedQuery(name = “Cliente.findByCliNome”, query = “SELECT c FROM Cliente c WHERE c.cliNome = :cliNome”), @NamedQuery(name = “Cliente.findByCliCpf”, query = “SELECT c FROM Cliente c WHERE c.cliCpf = :cliCpf”), @NamedQuery(name = “Cliente.findByCliIdade”, query = “SELECT c FROM Cliente c WHERE c.cliIdade = :cliIdade”)})
    public class Cliente implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = “cli_codigo”)
    private Integer cliCodigo;
    @Basic(optional = false)
    @Column(name = “cli_nome”)
    private String cliNome;
    @Basic(optional = false)
    @Column(name = “cli_cpf”)
    private String cliCpf;
    @Basic(optional = false)
    @Column(name = “cli_idade”)
    private int cliIdade;
    @JoinColumn(name = “empr_codigo”, referencedColumnName = “empr_codigo”)
    @ManyToOne(optional = false)
    private Empresa emprCodigo;

    public Cliente() {
    }

    public Cliente(Integer cliCodigo) {
    this.cliCodigo = cliCodigo;
    }

    public Cliente(Integer cliCodigo, String cliNome, String cliCpf, int cliIdade) {
    this.cliCodigo = cliCodigo;
    this.cliNome = cliNome;
    this.cliCpf = cliCpf;
    this.cliIdade = cliIdade;
    }
    @Coluna(posicao=0,nome=“Código”)//posicao no jtable e o nome para exibir na coluna (Aqui eu deveria informar que é Integer)
    public Integer getCliCodigo() {
    return cliCodigo;
    }

    public void setCliCodigo(Integer cliCodigo) {
    this.cliCodigo = cliCodigo;
    }
    @Coluna(posicao=1,nome=“Nome”)//posicao no jtable e o nome para exibir na coluna
    public String getCliNome() {
    return cliNome;
    }

    public void setCliNome(String cliNome) {
    this.cliNome = cliNome;
    }
    @Coluna(posicao=2,nome=“CPF”)//posicao no jtable e o nome para exibir na coluna
    public String getCliCpf() {
    return cliCpf;
    }

    public void setCliCpf(String cliCpf) {
    this.cliCpf = cliCpf;
    }
    @Coluna(posicao=3,nome=“Idade”)//posicao no jable e o nome para exibir na coluna
    public int getCliIdade() {
    return cliIdade;
    }

    public void setCliIdade(int cliIdade) {
    this.cliIdade = cliIdade;
    }
    @Coluna(posicao=4,nome=“Empresa”)//posicao no jable e o nome para exibir na coluna
    public Empresa getEmprCodigo() {
    return emprCodigo;
    }

    public void setEmprCodigo(Empresa emprCodigo) {
    this.emprCodigo = emprCodigo;
    }

    @Override
    public int hashCode() {
    int hash = 0;
    hash += (cliCodigo != null ? cliCodigo.hashCode() : 0);
    return hash;
    }

    @Override
    public boolean equals(Object object) {
    // TODO: Warning - this method won’t work in the case the id fields are not set
    if (!(object instanceof Cliente)) {
    return false;
    }
    Cliente other = (Cliente) object;
    if ((this.cliCodigo == null && other.cliCodigo != null) || (this.cliCodigo != null && !this.cliCodigo.equals(other.cliCodigo))) {
    return false;
    }
    return true;
    }

    @Override
    public String toString() {
    return “bean.Cliente[cliCodigo=” + cliCodigo + “]”;
    }

}[/code]

Eu comentei no primeiro codigo o que eu considero errado: mas no codigo abaixo eu tbm estou transformando o valor em String! e quando eu coloquei somente o

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 String.format(c.formato(), m.invoke(objeto)); // Como eu faria pra ele mostrar na tabela o valor no formato que ele vier sem usar o String.format(c.formato(), m.invoke(objeto))? return c.formato().getClass(); // Ele esta jogando os valores nas colunas assim oh: "class java.lang.String" } } }catch(Exception ex){ ex.printStackTrace(); } return ""; }

Uma solução seria adicionar outra tag a sua anottaion ai voce declararia o tipo e no metodo getClass() vc faria algo assim

public Class getColumnClass(int c) { try{ Object objeto = lista.get(rowIndex); for(Method m : classe.getDeclaredMethods()){ Coluna c = m.getAnnotation(Coluna.class); if(c != null && c.posicao() == columnIndex){ return c.classe(); } } }catch(Exception ex){ ex.printStackTrace(); } return ""; }
E na sua anotação

[code]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 {
//vamos utilizar esta annotation para pegar o nome da coluna,posicao no jtable e o formato que queremos mostrar
String nome();
int posicao();
String formato() default “%s”; // Como eu faria para esse formato ser o formato que eu desejasse? onde eu encontro esses fomatos?
Class classe();
}[/code]

Veja se resolve, mas acredito que da forma que o Mark postou seja a melhor maneira…

Salve Galera do Guj :-o : Eu fundi a ideia do Mark_Ameba com a do 71C4700 e deu certo. Já esta quase pronto!
Ficou assim oh no meu modelo:

public Class getColumnClass(int c) { for (Method m : classe.getDeclaredMethods()) { Coluna col = m.getAnnotation(Coluna.class); if (col != null && col.posicao() == c) { return m.getReturnType(); } } return null; }

e no metodo getValueAt observer o return

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 ""; }

A minha Annotation ficou assim oh:

[code]
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 {

//vamos utilizar esta annotation para pegar o nome da coluna,posicao no jtable e o formato que queremos mostrar
String nome();
int posicao();
Class formato();
}[/code]

dai no bean é so passar o tipo do dado que eu quero assim oh:

[code]
@Coluna(posicao=0,nome=“Codigo”, formato=Integer.class)//posicao no jtable e o nome para exibir na coluna
public Integer getCliCodigo() {
return cliCodigo;
}

@Coluna(posicao=1,nome="Nome", formato=String.class)//posicao no jtable e o nome para exibir na coluna
public String getCliNome() {
    return cliNome;
}[/code]

Observe que vc nao utiliza o formato() de sua anotação…Então VC ta seguindo a ideia do Mark_Ameba…

Que acho que seja melhor…

[quote=71C4700]Observe que vc nao utiliza o formato() de sua anotação…Então VC ta seguindo a ideia do Mark_Ameba…

Que acho que seja melhor…

[/quote]

Então Josimarsis, acho melhor vc verificar o código novamente heim, pois, realmente o codigo não está usando a tag formato() e além disso vc testou este código quando o tipo retornado for uma Data(por exemplo Calendar)?. Por que quando eu criei este TableModel(e vc agora está adaptando as suas necessidades), eu não tinha necessidade de saber o tipo retornado, então, eu retornava tudo em String mesmo e usei esta linha String.format(c.formato(), m.invoke(objeto)); para retornar uma data formatada em String.Quando eu anotei no PessoaBean o formato de apresentação era com este objetivo:

@Coluna(posicao=5,nome="Data Nascimento", formato="%1$Td/%1$Tm/%1$TY ")
	public Calendar getDataNascimento()

E quando for número como está apresentando(está assim: ###.###,### ou assim: ###,###.###)?.

Abraços.

josimarsis, já que vc quer criar mais uma tag na annotetion, então faz assim: o que for string continua da mesma forma que estava antes e quando nao for retorna o valor direto. E o método getColumnClass(int c) saberá o tipo.

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.

Agora que esta quase pronto… se quiser pode dar uma olhada nesse TableModel que postei no CodeProject.

http://www.codeproject.com/KB/java/objecttablemodel.aspx

Postado como artigo… me desculpe mas não sei escrever artigos direito e esse ainda foi em inglês.

Quando tinha pensado parecia uma boa idéia e tava pensando em colocar um artigo no GUJ também. Se possivel queria que dessem um feedback ^^

Galera, estou tentando fazer o seguinte: Quero que quando uma coluna for selecionada ela mude de cor (mais somente ela).

estou utilizando este metodo:

public void AlteraCorColuna() { jtTabela.repaint(); TableColumn coluna = jtTabela.getColumnModel().getColumn(jtTabela.getSelectedColumn()); coluna.setCellRenderer(new ColorColumnRenderer(Color.orange, Color.blue)); }

Eu criei este TableCellRenderer:

[code]class ColorColumnRenderer extends DefaultTableCellRenderer {

    Color bkgndColor, fgndColor;

    public ColorColumnRenderer(Color bkgnd, Color foregnd) {
        super();
        bkgndColor = bkgnd;
        fgndColor = foregnd;

    }

    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
            boolean hasFocus, int row, int column) {
        Component cell = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
            cell.setBackground(bkgndColor);
            cell.setForeground(fgndColor);
        return cell;
    }
}[/code]

Mas esta ocorrendo o seguinte eu clico na coluna ela muda a cor, quando eu clico em outra ele pinta tbm e assim consecutivamente. Eu necessitaria que ficasse pintada so a coluna que eu selecionar.
A Tabela esta pronto e so falta eu acertar isso! Resolvendo isso vou preparar um artigo como Mark_Ameba me aconselhou e postar o codigo fonte.

Assim como o TableModel NÃO extenda DefaultTableCellRenderer. Implemente TableCellRenderer.

Mark_Ameba, eu confesso que não consegui entender o TableCellRenderer e creio que muita gente tem dificuldades
com ele. Seria possivel vc fazer uma breve explicação? Pois não estou conseguindo pintar somente a coluna selecionada e isso se deve creio eu à falta de entendimento da classe TableCellRenderer. Se vc tiver algum exemplo!

Coloca seu Jtabel para selecionar apenas uma linha:

 jTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

Se vc quiser colocar um efeito zebrado no grid usa este CellRenderer aqui:

class MyCellRenderer extends DefaultTableCellRenderer {
        private Color whiteColor = new Color(254, 254, 254);
        private Color alternateColor = new Color(204, 204, 204);
        private Color selectedColor = new Color(61, 128, 223);

        @Override
        public Component getTableCellRendererComponent(JTable table,
                Object value, boolean selected, boolean focused, int row,
                int column) {

            super.getTableCellRendererComponent(table, value, selected, focused, row, column);

            Color bg;
            if (!selected)
                bg = (row % 2 == 0 ? alternateColor : whiteColor);
            else
                bg = selectedColor;

            setBackground(bg);
            setForeground(selected ? Color.white : Color.black);

          /*  if (value instanceof ImageIcon) {
                setIcon((ImageIcon) value);
                setText("");
            } else
                setIcon(null);
          */
            return this;
        }
    }

Abraços

[quote=Lintz_net]
Coloca seu Jtabel para selecionar apenas uma linha:

 jTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

Se vc quiser colocar um efeito zebrado no grid usa este CellRenderer aqui:

class MyCellRenderer extends DefaultTableCellRenderer {
        private Color whiteColor = new Color(254, 254, 254);
        private Color alternateColor = new Color(204, 204, 204);
        private Color selectedColor = new Color(61, 128, 223);

        @Override
        public Component getTableCellRendererComponent(JTable table,
                Object value, boolean selected, boolean focused, int row,
                int column) {

            super.getTableCellRendererComponent(table, value, selected, focused, row, column);

            Color bg;
            if (!selected)
                bg = (row % 2 == 0 ? alternateColor : whiteColor);
            else
                bg = selectedColor;

            setBackground(bg);
            setForeground(selected ? Color.white : Color.black);
            /*
            if (value instanceof ImageIcon) {
                setIcon((ImageIcon) value);
                setText("");
            } else
                setIcon(null);
           */
            return this;
        }
    }

Abraços[/quote]

Ahh esqueci… vc precisa setar o jtable com o seu renderer:

jTable.setDefaultRenderer(Object.class, new MyCellRenderer());

[quote=josimarsis]Galera, estou tentando fazer o seguinte: Quero que quando uma coluna for selecionada ela mude de cor (mais somente ela).

estou utilizando este metodo:

public void AlteraCorColuna() { jtTabela.repaint(); TableColumn coluna = jtTabela.getColumnModel().getColumn(jtTabela.getSelectedColumn()); coluna.setCellRenderer(new ColorColumnRenderer(Color.orange, Color.blue)); }

Eu criei este TableCellRenderer:

[code]class ColorColumnRenderer extends DefaultTableCellRenderer {

    Color bkgndColor, fgndColor;

    public ColorColumnRenderer(Color bkgnd, Color foregnd) {
        super();
        bkgndColor = bkgnd;
        fgndColor = foregnd;

    }

    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
            boolean hasFocus, int row, int column) {
        Component cell = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
            cell.setBackground(bkgndColor);
            cell.setForeground(fgndColor);
        return cell;
    }
}[/code]

Mas esta ocorrendo o seguinte eu clico na coluna ela muda a cor, quando eu clico em outra ele pinta tbm e assim consecutivamente. Eu necessitaria que ficasse pintada so a coluna que eu selecionar.
A Tabela esta pronto e so falta eu acertar isso! Resolvendo isso vou preparar um artigo como Mark_Ameba me aconselhou e postar o codigo fonte.[/quote]

Josimaris, vc precisa colocar uma lógica no seu método getTableCellRendererComponent.Quando for a linha selecionada vc pinta de uma cor, senão vc pinta de outra cor…

if (isSelected)//se estiver selecionado vc pinda de uma cor
     cell.setBackground("cor selecionada");
     cell.setForeground("cor selecionada");
else//se nao estiver selecionado vc pinta de outra cor.
    cell.setBackground("outra cor");
    cell.setForeground("outra cor");

Abraços.

E como eu faria caso eu queria pintar somente a coluna que eu clicar?

Ahhh desculpa cara, mas não tinha prestado atenção que era no click de uma unica celula. Mas é a mesma lógica: a coluna que vc selecionou vc pinta, senao for a celula que vc selecinou vc precisa voltar a cor que estava antes.

Isso aqui vai te ajudar: http://life.csu.edu.au/java-tut/uiswing/components/table.html e um exemplo de código do que Mark_Ameba falou(segue em anexo).

Abraços.

Nossa… quantas vezes eu vi Mark_Ameba escrito sendo comentado nesse tópico.

Eu ia implementar os exemplos do CellRendered mas não acho que precise mais.

O nosso caro amigo Lintz_net, solucionou o problema.

Na classe anexo ao seu post anterior, tem um exemplo que ‘colori’ a celula a qual o mouse esta por cima.

Para uma adaptação acredito que :

  1. Ao inves de capturar a coluna selecionada, pois podem existir varias, usa
table.columnAtPoint(e.getPoint());
  1. Quando for alterar o codigo da classe Estudos,substitui o metodo getTableCellRendererComponent, por esse.

[code] public Component getTableCellRendererComponent(
JTable table, Object value,
boolean isSelected, boolean hasFocus,
int row, int column) {
if (column == coluna) {
this.setBackground(Color.yellow);

            } else {
                this.setBackground(table.getBackground());
            }

            this.setText(value.toString());
            return this;
        }[/code]

Agora é só observar e verificar como esta se comportando o codigo, veja que agora ele colore toda a linha a qual o mouse esta sobreposto. Altere o evento pro click e acredito que funcione

Galera Boa noite. Com as ideias e exemplos que vcs me deram eu consegui fazer o que eu queria que era zebrar a tabela e mudar a cor de uma celula quando selecionada e cheguei a pensar que enfim tinha concluido minha Tabela Dinamica. Porém realizando alguns testes percebi que quando minha tabela possui colunas de valores Integer, Float ou Double o CellRenderer que eu fiz simplismente não funciona. Se eu mando os dados para a Tabela como String o RowSorter não funciona corretamente para as colunas do tipo (Integer, Float e Double).

Annotation criada para mapear os campos que quero mostrar na consulta:

[code]
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 {
//vamos utilizar esta annotation para pegar o nome da coluna,posicao no jtable e o formato que queremos mostrar
String nome();
int posicao();
Class formato();
}[/code]

Metodo do modelo “que pelo que eu entendi” é responsavel por preencher as colunas (classe: TableModelPadraoParaBean):

@Override public Class getColumnClass(int c) { for (Method m : classe.getDeclaredMethods()) { Coluna col = m.getAnnotation(Coluna.class); if (col != null && col.posicao() == c) { return m.getReturnType(); } } return null; }

Bean definido a partir da view criada no banco de dados para ser mostrado na consulta. Classe: (ViewTeste). Segue a baixo o trecho do codigo onde eu seto os valores definidos na Annotation criada.

@Coluna(posicao=0,nome="Codigo", formato=Integer.class)//posicao no jable e o nome para exibir na coluna public Integer getCliCodigo() { return cliCodigo; }

Classe MyCellRenderer responsavel por zebar e permitir o efeito de seleção da Tabela. Essa Classe se encontra dentro da Classe FrmConsulta.

[code]
class MyCellRenderer extends DefaultTableCellRenderer {

    private Color whiteColor = new Color(254, 254, 254);
    private Color alternateColor = new Color(123, 193, 255);
    private Color selectedColor = new Color(61, 128, 223);

    @Override
    public Component getTableCellRendererComponent(JTable table,
            Object value, boolean selected, boolean focused, int row,
            int column) {

        super.getTableCellRendererComponent(table, value, selected, focused, row, column);

        Color bg = null;
        // Testa se não existe celula selecionada, se não existir zebra a tabela
        if (!selected) {
            bg = (row % 2 == 0 ? alternateColor : whiteColor);
        } // Testa se existe celula selecionada, se exitir tambem zebra a tabela
        else {

// bg = selectedColor;
bg = (row % 2 == 0 ? alternateColor : whiteColor);
}
// Pinta a celula selecionada de amarelo
if (row == table.getSelectedRow() && column == table.getSelectedColumn()) {
bg = Color.YELLOW;
}
setBackground(bg);
// setForeground(selected ? Color.red : Color.black);

        return this;
    }
}[/code]

Segue anexo tbm o projeto feito no netbeans e o scrip do banco mysql que está dentro da pasta do projeto.

Josimarsis, este problema é classico e eu já tive tbm. :lol: E acho que vc pode resolver colcando setDefaultRenderer para Integer e Double.Onde vc seta o seu renderer?Deve ter algo assim, né:

 jTabela.setDefaultRenderer(Object.class, new MyCellRenderer());

Coloque mais duas linhas:

 jTabela.setDefaultRenderer(Integer.class, new MyCellRenderer());
 jTabela.setDefaultRenderer(Double.class, new MyCellRenderer());

E veja se funfa…se funfar avisa.Senão funfar eu vejo o seu código para vê se consigo te ajudar.

Abraços.