Problema ao editar JTable

26 respostas
K

e ai pessoal?
Estou com um problema em relacao a edicao de celulas do JTable, ao editar o texto de uma célula e tentar editar outra célula,
no momento que eu seleciono outra célula ele apaga uma linha chamando o método remove automaticamente.
Eu tenho um modelo implementado

Modelo:
public class ModeloTabelaDinamica extends AbstractTableModel
{
   private ArrayList<String> nomesDasColunas; //Nome das colunas da tabela
   private ArrayList<Object[]> dados; //Referentes a uma linha, ou seja um Object[] em cada linha


   public ModeloTabelaDinamica(ArrayList<String> nomesColunas, ArrayList<Object[]> linhas)
   {
       if(nomesColunas != null)
            this.nomesDasColunas = nomesColunas;
       else
            throw new NullPointerException("Nomes das colunas não especificados");
       this.fireTableStructureChanged();
       if(linhas != null)
       {
           this.dados = linhas;
           this.fireTableDataChanged();
       }
       else
           this.dados = new ArrayList<Object[]>();
   }

   public ModeloTabelaDinamica(ArrayList<String> nomeColunas)
   {
       this(nomeColunas, null);
   }

   public ModeloTabelaDinamica(String... nomeColunas)
   {
       if(nomeColunas == null)
           throw new NullPointerException("Nome das Colunas nulo");
       this.nomesDasColunas = new ArrayList<String>();
       this.dados = new ArrayList<Object[]>();
       for(String s: nomeColunas)
       {
           this.nomesDasColunas.add(s);
       }
       this.fireTableStructureChanged();
   }

   public int getColumnCount()
   {
       return nomesDasColunas.size();
   }

   public int getRowCount()
   {
       return dados.size();
   }

   public Object getValueAt(int linha, int coluna)
   {
       return dados.get(linha)[coluna];
   }

   @Override
   public void setValueAt(Object valor, int linha, int coluna)
   {
       if(dados.size() > linha)
       {
           Object[] novo = dados.get(linha);
           novo[coluna] = valor;
           this.fireTableCellUpdated(linha, coluna);
       }
       else
       {
           Object[] novo = new Object[this.nomesDasColunas.size()];
           novo[coluna] = valor;
           dados.add(linha, novo);
           this.fireTableRowsInserted(linha, linha);
       }
   }
        
    public void adicionar(Object... cadastro)
    {
        if(cadastro.length != this.nomesDasColunas.size())
            throw new IllegalArgumentException("Tamanho do vetor diferente do numero de colunas da Tabela");
        this.dados.add(cadastro);
        this.fireTableDataChanged();
    }


    public void remove(int linha)
    {
        this.dados.remove(linha);
        this.fireTableRowsDeleted(linha, linha);
    }

    public int getTamanho()
    {
        return dados.size();
    }

    @Override
    public String getColumnName(int i)
    {
        return this.nomesDasColunas.get(i);
    }

    public void limpaTabela()
    {
        this.dados.clear();
        this.fireTableDataChanged();
    }

   public void adicionarNoMeio(int linha, Object...cadastro)
   {
       if(cadastro.length != this.nomesDasColunas.size())
           throw new IndexOutOfBoundsException("Array com dimensão diferente do numero de colunas");
       dados.add(linha, cadastro);
       this.fireTableRowsInserted(linha, linha);
   }
}
Tabela que extends o JTable
public class TabelaDinamica extends JTable
{
    private ModeloTabelaDinamica modelo;

    public TabelaDinamica(ArrayList<String> nomesDasColunas, ArrayList<Object[]> dados)
    {
        this.modelo = new ModeloTabelaDinamica(nomesDasColunas, dados);
        this.setModel(this.modelo);
    }

    public TabelaDinamica(ArrayList<String> colunas)
    {
        this(colunas, null);
    }

    public TabelaDinamica(String...nomesDasColunas)
    {
        this.modelo = new ModeloTabelaDinamica(nomesDasColunas);
        this.setModel(this.modelo);
    }

    public void adicionar(Object ...cadastro)
    {
        this.modelo.adicionar(cadastro);
    }

    @Override
    public void remove(int linha) throws ArrayIndexOutOfBoundsException
    {
        this.modelo.remove(linha);
    }

    public int getTamanho()
    {
        return this.modelo.getTamanho();
    }

    public void limpaTabela()
    {
        this.modelo.limpaTabela();
    }

    public void adicionarNoMeio(int linha, Object...cadastro)
    {
        this.modelo.adicionarNoMeio(linha, cadastro);
    }

    public void ajustarTamanhoDasColunas(int... array)
    {
        if(array.length != this.getColumnCount())
            throw new IllegalArgumentException("Array diferente do numero de colunas da tabela");
        //AjudanteSwing.ajustarTamanhoDasColunas(this, array);
    }
    
}
e uma outra classe que extends a classe TabelaDinamica para tornar editavel
public class TabelaEditavel extends TabelaDinamica{

    public TabelaEditavel(ArrayList<String> nomesDasColunas, ArrayList<Object[]> dados){
        super(nomesDasColunas, dados);
    }

    public TabelaEditavel(ArrayList<String> colunas){
        this(colunas, null);
    }

    public TabelaEditavel(String...nomesDasColunas){
        super(nomesDasColunas);
    }

    
    public boolean isCellEditable(int row, int col){
        if (col < 1) {
            return false;
        } else {
            return true;
        }
    }

    public Class getColumnClass(int c) {
            return getValueAt(0, c).getClass();
    }
}

preciso disso, pois quando o usuário alterar o conteúdo de uma célula, a alteração será efetivada no
Banco de dados ao clicar no botao salvar.

26 Respostas

Marky.Vasconcelos

Algumas considerações.

1° O seu TableModel parece com o DefaultTableModel, mas invés de um array bidimensional voce esta usando uma lista de vetores, voce deveria ter uma lista de objetos do tipo da sua classe.

2° Voce não precisa criar um filho de JTable, voce só precisa criar o modelo e passa-lo como argumento para JTable

3° Sua lógica para torna-la editavel devia estar no primeiro model, não em outra extensão.

Veja nos links da minha assinatura como fazer isso.

K

Então eu tenho que implementar um modelo para cada tipo de objeto que eu for exibir na jtable ou eu posso criar lista de Generics para ser o tipo da lista.

Fiz a alteração no modelo para:

public class ModeloTabelaDinamica<T> extends AbstractTableModel
{
   private ArrayList<String> nomesDasColunas; //Nome das colunas da tabela
   private ArrayList<T> dados; //Referentes a uma linha, ou seja um Object[] em cada linha
   private boolean [] colunasEdicao;

   public ModeloTabelaDinamica(ArrayList<String> nomesColunas, ArrayList<T> linhas, boolean[] edicao){
        if(nomesColunas != null)
            this.nomesDasColunas = nomesColunas;
        else
            throw new NullPointerException("Nomes das colunas não especificados");
        if(edicao != null)
            this.colunasEdicao = edicao;
        else
            throw new NullPointerException("Colunas editaveis não especificadas");
        fireTableStructureChanged();
       if(linhas != null)
       {
           this.dados = linhas;
           this.fireTableDataChanged();
       }
       else
           this.dados = new ArrayList<T>();
   }

   public ModeloTabelaDinamica(ArrayList<String> nomeColunas, boolean[] edicao){
       this(nomeColunas, null, edicao);
   }

   public void setColunas(ArrayList<String> strings){
        nomesDasColunas = strings;
   }

   public void setLinhas(ArrayList<T> list){
       dados = list;
   }

   public ArrayList<String> getColunas(){
       return this.nomesDasColunas;
   }

   public ArrayList<T> getLinhas(){
       return this.dados;
   }

   public int getColumnCount(){
       return this.getColunas().size();
   }

   public int getRowCount(){
       return this.getLinhas().size();
   }

   public Object getValueAt(int linha, int coluna){
       String [] linhas = (String[]) this.getLinhas().get(linha);
       return linhas[coluna];
   }

   @Override
   public String getColumnName(int col){
        return (String)this.nomesDasColunas.get(col);
   }

   @Override
   public boolean isCellEditable(int row, int collumn){
       return this.colunasEdicao[collumn];
   }

   @Override
   public void setValueAt(Object valor, int linha, int coluna)
   {
       String [] linhas = (String []) this.getLinhas().get(linha);

       linhas[coluna] = (String) valor;

       fireTableCellUpdated(linha, coluna);
   }
        
   public void adicionar(T... cadastro)
   {
       if(cadastro.length != this.nomesDasColunas.size())
           throw new IllegalArgumentException("Tamanho do vetor diferente do numero de colunas da Tabela");
       this.dados.add((T) cadastro);
       this.fireTableDataChanged();
   }

   public void remove(int linha)
   {
       this.dados.remove(linha);
       this.fireTableRowsDeleted(linha, linha);
   }

   public int getTamanho()
   {
       return dados.size();
   }

   public void limpaTabela()
   {
       this.dados.clear();
       this.fireTableDataChanged();
   }
}
Marky.Vasconcelos

Mesmo com List dados voce ainda considera que será um uma lista de String[].

Um TableModel genérico deve ser capaz de armazenar qualquer tipo de objeto como lista de dados e exibir apenas as colunas necessarias na tabela.

Se quiser ver um TableModel genérico que eu fiz da uma olhada no ObejctTableModel. O código dele está disponivel no github

K

Mark obrigado por estar me ajudando.

fiz umas alterações com base na sua classe ObjectTableModel

public class ModeloTabelaDinamica<T> extends AbstractTableModel
{
   private List<String> nomesDasColunas; //Nome das colunas da tabela
   private List<T> dados; //Referentes a uma linha
   private boolean [] colunasEdicao;
   private boolean editDefault;

   public ModeloTabelaDinamica(List<String> nomesColunas, List<T> linhas, boolean[] edicao){
        if(nomesColunas != null)
            this.nomesDasColunas = nomesColunas;
        else
            throw new NullPointerException("Nomes das colunas não especificados");
        if(edicao != null)
            this.colunasEdicao = edicao;
        else
            throw new NullPointerException("Colunas editaveis não especificadas");
        fireTableStructureChanged();
       if(linhas != null)
       {
           this.dados = linhas;
           this.fireTableDataChanged();
       }
       else
           this.dados = new ArrayList<T>();
   }

   public ModeloTabelaDinamica(List<String> nomeColunas, boolean[] edicao){
       this(nomeColunas, null, edicao);
   }

   public void setColunas(List<String> strings){
        nomesDasColunas = strings;
   }

   public void setLinhas(List<T> list){
       dados = list;
   }

   public List<String> getColunas(){
       return this.nomesDasColunas;
   }

   public List<T> getLinhas(){
       return this.dados;
   }

   public int getColumnCount(){
       return this.getColunas().size();
   }

   public int getRowCount(){
       return this.getLinhas().size();
   }

   public T getValueAt(int linha, int coluna){
       return this.getLinhas().get(linha);
   }

   @Override
   public String getColumnName(int col){
        return (String)this.nomesDasColunas.get(col);
   }

   public void setEditableDefault(boolean editable) {
           editDefault = editable;
   }

   @Override
   public boolean isCellEditable(int row, int collumn){
       if(colunasEdicao == null)
           return editDefault;
       else
           return this.colunasEdicao[collumn];
   }

   @Override
   public void setValueAt(Object valor, int linha, int coluna)
   {
       this.getLinhas().add((T) valor);

       fireTableCellUpdated(linha, coluna);
   }
        
   public void adicionar(T... cadastro)
   {
       if(cadastro.length != this.nomesDasColunas.size())
           throw new IllegalArgumentException("Tamanho do vetor diferente do numero de colunas da Tabela");
       this.dados.add((T) cadastro);
       this.fireTableDataChanged();
   }

   public void remove(int linha)
   {
       this.dados.remove(linha);
       this.fireTableRowsDeleted(linha, linha);
   }

   public int getTamanho()
   {
       return dados.size();
   }

   public void limpaTabela()
   {
       this.dados.clear();
       this.fireTableDataChanged();
   }
}

Não sei se está correto e tenho duvidas sobre o setValueAt e o getValueAt.

Marky.Vasconcelos

getValueAt e setValueAt são praticamente o coração do model.

O getValueAt(int row, int col) deve retornar o valor que deve estar na célula na posição [row x col].
O setValueAt(Object value, int row, int col) indica o novo valor[value] que está em [row x col], voce deve atualizar seus dados com esse novo valor.

Marky.Vasconcelos

Uma dica, não use NullPointerException caso os valores sejam nulos, é bem mais interessante lançar um IllegalArgumentException.

K

Dessa maneira ira funcionar para todas as minhas classes?
os metodos setValueAt e getValueAt estao corretos?

K

e como eu vou adicionar dados apos a consulta?

Marky.Vasconcelos

Então, do modo que está. não.

Se por exemplo voce tem uma lista de Pessoas como os dados, e o getValueAt pediu as informações de [20,3], e na sua quarta coluna (0-based) voce exibe o telefone das pessoas, então voce deveria retornar o telefone da pessoa na posição 20 da sua lista de dados.

No método setValueAt se for passado um objeto e com as coordenadas [19,3] voce deve setar o numero de telefone da pessoa da 19° posição da lista com o value passado como parametro.

Veja em: http://www.guj.com.br/java/132698-jtable-removendo-colunas-em-tempo-de-execucao#714736
Como foi implementado para Livros.

Para voce não ter que criar um model para cada, voce precisa arrumar um modo de fazer o getValueAt e setValueAt se virar com qualquer tipo de dados, eu resolvi isso no meu com Reflection.

K

Marky. onde posso fazer o download da sua api para utilizar o ObjectTableModel, e um exemplo de como utilizar o model.

obrigado

Marky.Vasconcelos
K

Obrigado Marky, estou usando o seu modelo, só que estou com um problema, estou usando o hibernate para a persistencia dos dados, possuo um relacionamento ManyToOne entre os pojos ‘Tecnicos e Empresa’ só que quando vou exibir na tabela a empresa para qual o Tecnico trabalha não aparece o nome e sim: br.com.sistecam.Empresa@2c03ff.

Olhe o meu Pojo Tecnico:

@Entity
@Table(name="Tecnicos", schema="Tecnicos")

public class Tecnicos implements Serializable {

    @Id
    @SequenceGenerator(name="SEQ_TEC", sequenceName="SEQ_TECNICOS", allocationSize=1)
    @GeneratedValue(strategy= GenerationType.SEQUENCE, generator="SEQ_TEC")
    @Column(name="tec_id")
    @Resolvable(colName="ID")
    private Integer id;

    @Column(name="tec_codext", nullable=false)
    @Resolvable(colName="CÓD.TÉCNICO")
    private Integer codigoExterno;

    @Column(name="tec_descricao", nullable=false, length=80)
    @Resolvable(colName="DESCRIÇÃO")
    private String descricao;

    @Column(name="tec_email", nullable=false, length=100)
    @Resolvable(colName="EMAIL")
    private String email;

    @Column(name="tec_situreg")
    @Resolvable(colName="SITUAÇÃO")
    private String situ_reg;

    @ManyToOne(fetch=FetchType.EAGER)
    @JoinColumn(name="tec_emp_id", insertable=true, updatable=true)
    @Fetch(FetchMode.JOIN)
    @Cascade(CascadeType.SAVE_UPDATE)
    @Resolvable(colName="EMPRESA")
    private Empresa empresa;

    @ManyToMany(fetch=FetchType.LAZY)
    @JoinTable(name="tecnico_cliente", schema="Tecnicos",
            joinColumns=@JoinColumn(name="teccli_tec_id"),
            inverseJoinColumns=@JoinColumn(name="teccli_cli_id"))
    @Resolvable(colName="CLIENTES")
    private Collection<Cliente> clientes;

    @ManyToMany(fetch=FetchType.LAZY)
    @JoinTable(name="questionario_tecnico", schema="Tecnicos",
            joinColumns=@JoinColumn(name="tec_id"),
            inverseJoinColumns=@JoinColumn(name="ques_id"))
    @Resolvable(colName="QUESTIONARIO")
    private Collection<Questionario> questionarios;

e o meu Empresa:

@Entity
//Informata a tabela do mapeamento e o schema do BD
@Table(name ="Empresa", schema="Tecnicos")

public class Empresa implements Serializable{

    //define que emp_id é o id da tabela
    @Id
    @SequenceGenerator(name="SEQ_EMP", sequenceName="SEQ_EMPRESA", allocationSize=1)
    @GeneratedValue(strategy= GenerationType.SEQUENCE, generator="SEQ_EMP")
    @Column(name = "emp_id")
    @Resolvable(colName="ID")
    private Integer emp_id;

    @Column(name = "emp_fili_codi")
    @Resolvable(colName="FILIAL")
    private Integer emp_fili_codi;

    @Column(name = "emp_nome", nullable=false, length=80)
    @Resolvable(colName="NOME")
    private String emp_nome;

    @Column(name = "emp_email", length=100)
    @Resolvable(colName="EMAIL")
    private String emp_email;

    @OneToMany(mappedBy="empresa", fetch=FetchType.LAZY)
    @Cascade(CascadeType.ALL)
    @Resolvable(colName="TÉCNICOS")
    private Collection<Tecnicos> tecnicos;

    @OneToMany(mappedBy="empresa", fetch=FetchType.LAZY)
    @Cascade(CascadeType.ALL)
    @Resolvable(colName="QUESTIONÁRIO")
    private Collection<Questionario> questionario;
Marky.Vasconcelos

Cade onde voce instancia o model?

Voce provavelmente passou apenas “empresa” mas devia ser “empresa.emp_nome”

K

o outro eu resolvi.
estou com o mesmo problema em outra classe

@Entity
@Table(name="Cliente", schema="Tecnicos")
public class Cliente implements Serializable {

    @Id
    @SequenceGenerator(name="SEQ_CLI", sequenceName="SEQ_CLIENTE", allocationSize=1)
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SEQ_CLI")
    @Column(name="cli_id", nullable=false)
    @Resolvable(colName="ID")
    private Integer Id;

    @Column(name="cli_codext")
    @Resolvable(colName="CÓDIGO")
    private Integer codigoExterno;

    @Column(name="cli_fili")
    @Resolvable(colName="FILIAL")
    private Integer filial;

    @Column(name="cli_razaosocial", length=80)
    @Resolvable(colName="RAZÃO SOCIAL")
    private String razaoSocial;

    @Column(name="cli_nomefantasia", length=80)
    @Resolvable(colName="NOME FANTASIA")
    private String nomeFantasia;

    @Column(name="cli_cnpj", length=20)
    private String cnpj;

    @Column(name="cli_inscest", length=30)
    private String InscEst;

    @Column(name="cli_endereco", length=200)
    private String endereco;

    @Column(name="cli_bairro", length=45)
    private String bairro;

    @Column(name="cli_cidade", length=50)
    private String cidade;

    @Column(name="cli_estado", length=2)
    private String estado;

    @Column(name="cli_cep", length=20)
    private String cep;

    @Column(name="cli_telefone", length=20)
    @Resolvable(colName="TELEFONE")
    private String telefone;

    @Column(name="cli_situreg", length=20)
    private String situ_reg;
    
    @Column(name="cli_emailPrincipal", length=150)
    @Resolvable(colName="EMAIL")
    private String emailPrincipal;

    @OneToMany(mappedBy="cliente", fetch=FetchType.LAZY)
    @Cascade(CascadeType.ALL)
    private Collection<EmailCliente> email;

    @ManyToMany(fetch=FetchType.LAZY)
    @JoinTable(name="tecnico_cliente", schema="Tecnicos",
            joinColumns=@JoinColumn(name="teccli_cli_id"),
            inverseJoinColumns=@JoinColumn(name="teccli_tec_id"))
    private Collection<Tecnicos> tecnicos;

    @ManyToMany(fetch=FetchType.LAZY)
    @JoinTable(name="questionario_cliente", schema="Tecnicos",
            joinColumns=@JoinColumn(name="cli_id"),
            inverseJoinColumns=@JoinColumn(name="ques_id"))
    private Collection<Questionario> questionarios;

preciso preencher uma tabela somenta com os tecnicos do cliente

new ObjectTableModel<Cliente>(resolver,"tecnicos.id:ID,tecnicos.codigoExterno:CÓDIGO,tecnicos.descricao:NOME");
K

Ta aparecendo o seguinte erro:

java.lang.NoSuchFieldException: id
        at java.lang.Class.getDeclaredField(Class.java:1882)
        at com.towel.el.annotation.AnnotationResolver.resolve(AnnotationResolver.java:94)
        at com.towel.el.annotation.AnnotationResolver.resolve(AnnotationResolver.java:54)
        at com.towel.el.annotation.AnnotationResolver.resolve(AnnotationResolver.java:77)
        at com.towel.swing.table.ObjectTableModel.<init>(ObjectTableModel.java:36)
        at br.com.amazonas.sistecam.view.FormCliente.getPainelConsultaInf(FormCliente.java:200)
        at br.com.amazonas.sistecam.view.FormCliente.initComponents(FormCliente.java:75)
        at br.com.amazonas.sistecam.view.FormCliente.<init>(FormCliente.java:60)
        at br.com.amazonas.sistecam.view.Principal$ListenerMenuCliente.actionPerformed(Principal.java:123)
        at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
        at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
        at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
        at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
        at javax.swing.AbstractButton.doClick(AbstractButton.java:357)
        at javax.swing.plaf.basic.BasicMenuItemUI.doClick(BasicMenuItemUI.java:1223)
        at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(BasicMenuItemUI.java:1264)
        at java.awt.Component.processMouseEvent(Component.java:6267)
        at javax.swing.JComponent.processMouseEvent(JComponent.java:3267)
        at java.awt.Component.processEvent(Component.java:6032)
        at java.awt.Container.processEvent(Container.java:2041)
        at java.awt.Component.dispatchEventImpl(Component.java:4630)
        at java.awt.Container.dispatchEventImpl(Container.java:2099)
        at java.awt.Component.dispatchEvent(Component.java:4460)
        at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4577)
        at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4238)
        at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4168)
        at java.awt.Container.dispatchEventImpl(Container.java:2085)
        at java.awt.Window.dispatchEventImpl(Window.java:2478)
        at java.awt.Component.dispatchEvent(Component.java:4460)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
java.lang.NoSuchFieldException: codigoExterno
        at java.lang.Class.getDeclaredField(Class.java:1882)
        at com.towel.el.annotation.AnnotationResolver.resolve(AnnotationResolver.java:94)
        at com.towel.el.annotation.AnnotationResolver.resolve(AnnotationResolver.java:54)
        at com.towel.el.annotation.AnnotationResolver.resolve(AnnotationResolver.java:77)
        at com.towel.swing.table.ObjectTableModel.<init>(ObjectTableModel.java:36)
        at br.com.amazonas.sistecam.view.FormCliente.getPainelConsultaInf(FormCliente.java:200)
        at br.com.amazonas.sistecam.view.FormCliente.initComponents(FormCliente.java:75)
        at br.com.amazonas.sistecam.view.FormCliente.<init>(FormCliente.java:60)
        at br.com.amazonas.sistecam.view.Principal$ListenerMenuCliente.actionPerformed(Principal.java:123)
        at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
        at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
        at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
        at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
        at javax.swing.AbstractButton.doClick(AbstractButton.java:357)
        at javax.swing.plaf.basic.BasicMenuItemUI.doClick(BasicMenuItemUI.java:1223)
        at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(BasicMenuItemUI.java:1264)
        at java.awt.Component.processMouseEvent(Component.java:6267)
        at javax.swing.JComponent.processMouseEvent(JComponent.java:3267)
        at java.awt.Component.processEvent(Component.java:6032)
        at java.awt.Container.processEvent(Container.java:2041)
        at java.awt.Component.dispatchEventImpl(Component.java:4630)
        at java.awt.Container.dispatchEventImpl(Container.java:2099)
        at java.awt.Component.dispatchEvent(Component.java:4460)
        at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4577)
        at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4238)
        at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4168)
        at java.awt.Container.dispatchEventImpl(Container.java:2085)
        at java.awt.Window.dispatchEventImpl(Window.java:2478)
        at java.awt.Component.dispatchEvent(Component.java:4460)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
java.lang.NoSuchFieldException: descricao
        at java.lang.Class.getDeclaredField(Class.java:1882)
        at com.towel.el.annotation.AnnotationResolver.resolve(AnnotationResolver.java:94)
        at com.towel.el.annotation.AnnotationResolver.resolve(AnnotationResolver.java:54)
        at com.towel.el.annotation.AnnotationResolver.resolve(AnnotationResolver.java:77)
        at com.towel.swing.table.ObjectTableModel.<init>(ObjectTableModel.java:36)
        at br.com.amazonas.sistecam.view.FormCliente.getPainelConsultaInf(FormCliente.java:200)
        at br.com.amazonas.sistecam.view.FormCliente.initComponents(FormCliente.java:75)
        at br.com.amazonas.sistecam.view.FormCliente.<init>(FormCliente.java:60)
        at br.com.amazonas.sistecam.view.Principal$ListenerMenuCliente.actionPerformed(Principal.java:123)
        at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
        at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
        at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
        at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
        at javax.swing.AbstractButton.doClick(AbstractButton.java:357)
        at javax.swing.plaf.basic.BasicMenuItemUI.doClick(BasicMenuItemUI.java:1223)
        at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(BasicMenuItemUI.java:1264)
        at java.awt.Component.processMouseEvent(Component.java:6267)
        at javax.swing.JComponent.processMouseEvent(JComponent.java:3267)
        at java.awt.Component.processEvent(Component.java:6032)
        at java.awt.Container.processEvent(Container.java:2041)
        at java.awt.Component.dispatchEventImpl(Component.java:4630)
        at java.awt.Container.dispatchEventImpl(Container.java:2099)
        at java.awt.Component.dispatchEvent(Component.java:4460)
        at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4577)
        at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4238)
        at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4168)
        at java.awt.Container.dispatchEventImpl(Container.java:2085)
        at java.awt.Window.dispatchEventImpl(Window.java:2478)
        at java.awt.Component.dispatchEvent(Component.java:4460)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
        at com.towel.swing.table.ObjectTableModel.getColumnName(ObjectTableModel.java:167)
        at javax.swing.JTable.addColumn(JTable.java:2770)
        at javax.swing.JTable.createDefaultColumnsFromModel(JTable.java:1264)
        at javax.swing.JTable.tableChanged(JTable.java:4374)
        at javax.swing.JTable.setModel(JTable.java:3676)
        at javax.swing.JTable.<init>(JTable.java:612)
        at javax.swing.JTable.<init>(JTable.java:553)
        at br.com.amazonas.sistecam.view.FormCliente.getPainelConsultaInf(FormCliente.java:201)
        at br.com.amazonas.sistecam.view.FormCliente.initComponents(FormCliente.java:75)
        at br.com.amazonas.sistecam.view.FormCliente.<init>(FormCliente.java:60)
        at br.com.amazonas.sistecam.view.Principal$ListenerMenuCliente.actionPerformed(Principal.java:123)
        at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
        at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
        at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
        at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
        at javax.swing.AbstractButton.doClick(AbstractButton.java:357)
        at javax.swing.plaf.basic.BasicMenuItemUI.doClick(BasicMenuItemUI.java:1223)
        at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(BasicMenuItemUI.java:1264)
        at java.awt.Component.processMouseEvent(Component.java:6267)
        at javax.swing.JComponent.processMouseEvent(JComponent.java:3267)
        at java.awt.Component.processEvent(Component.java:6032)
        at java.awt.Container.processEvent(Container.java:2041)
        at java.awt.Component.dispatchEventImpl(Component.java:4630)
        at java.awt.Container.dispatchEventImpl(Container.java:2099)
        at java.awt.Component.dispatchEvent(Component.java:4460)
        at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4577)
        at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4238)
        at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4168)
        at java.awt.Container.dispatchEventImpl(Container.java:2085)
        at java.awt.Window.dispatchEventImpl(Window.java:2478)
        at java.awt.Component.dispatchEvent(Component.java:4460)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
Marky.Vasconcelos

Isso não funciona mesmo.

Se voce quer uma lista dos tecnicos do cliente voce precisa passar
“id:ID,codigoExterno:CÓDIGO,descricao:NOME” como parametro.

E a lista de dados ser o Cliente.getTecnicos(), do modo que voce fez ele vai procurar esses atributos dentro de Collections.

K

Entao o meu modelo dever ser
ObjectTableModel e não
ObjectTableModel

Marky.Vasconcelos

Ah sim, também.

K

Mesmo trocando o tipo do modelo continua aparecendo o erro

K

o outro eu consegui fazendo:

this.modelo = new ObjectTableModel<Tecnicos>(resolver, "id,codigoExterno,descricao,email,situ_reg,empresa.emp_nome:EMPRESA");

por isso eu tentei na classe cliente.

K

Esta e minha classe Form
ta meio bagunçado

public class FormCliente extends JDialog{

    //declaração dos campos do formulario
    private JTabbedPane abas;
    private ObjectTableModel<Cliente> modelo, modeloTecnicos, modeloHisVen;
    private JTable tabela, tabelaTecnicos, tabelaHisVen;
    private JTable tabelaEmail;
    private JScrollPane scroll, scrollTecnicos, scrollVendas, scrollEmail;
    private JPanel painelCon, painelConInf, painelHistorico, painelPesquisar, painelEmail;
    private JLabel labelCodExt, labelFilial, labelRazSoc, labelFantasia, labelCNPJ,
            labelInscEst, labelEndereco, labelBairro, labelCidade, labelEstado,
            labelCep, labelTelefone, labelEmail, labelTecnicos, labelPesqNome;
    private JTextField codExt, filial, razaoSocial, nomeFantasia, endereco,
            bairro, cidade, estado, email, pesqNome;
    private JFormattedTextField cnpj, inscEst, cep, telefone;
    private JButton pesquisar, emailNovoItem, emailApagar, salvarEmail;
    private int linha = -1;
    private Session session;
    

    public FormCliente(){
        this.initComponents();
        this.setSize(800, 600);
        this.setLocation(100, 120);
        this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
        this.setModal(true);
        this.setVisible(true);
    }

    private void initComponents(){
        this.setTitle("Pesquisa de Clientes");
        
        //Incializa as abas

        this.abas = new JTabbedPane();
        this.abas.addTab("Consulta", null, this.getPainelConsulta(), "Consulta de Clientes");
        this.abas.addTab("Informações", null, this.getPainelConsultaInf(), "Informações do Cliente");
        this.abas.addTab("Histórico", null, this.getPainelHisVendas(), "Histórico de Vendas");
        this.abas.addTab("Email", null, this.getPainelEmail(), "Emails do Cliente");

        this.abas.addChangeListener(new ListenerAbas());
        
        this.emailNovoItem.addActionListener(new ListenerJButtonNovoItem());
        this.emailApagar.addActionListener(new ListenerJButtonApagaItem());
        
        this.getContentPane().add(this.abas);
    }

    private JPanel getPainelConsulta(){

        this.painelCon = new JPanel();
        this.painelCon.setLayout(new BorderLayout());

        AnnotationResolver resolver = new AnnotationResolver(Cliente.class);
        this.modelo = new ObjectTableModel<Cliente>(resolver,
                "Id,codigoExterno,filial,razaoSocial,nomeFantasia,telefone,emailPrincipal");

        this.tabela = new JTable(this.modelo);
        this.tabela.getTableHeader().setReorderingAllowed(false);
        this.tabela.setSelectionMode(0);
        this.tabela.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        this.tabela.setRowSelectionAllowed(true);
        this.scroll = new JScrollPane(this.tabela);
        this.scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        this.scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        this.scroll.setVisible(true);
        int [] tamColunas = {30,60,60,250,200, 80, 200};
        AjudanteSwing.ajustarTamanhoDasColunas(tabela, tamColunas);

        this.tabela.addMouseListener(new ListenerTabela());
        this.painelCon.add(this.getPesquisar(), BorderLayout.NORTH);
        this.painelCon.add(this.scroll, BorderLayout.CENTER);

        return this.painelCon;
    }

    private JPanel getPainelConsultaInf(){
        this.painelConInf = new JPanel();
        this.painelConInf.setLayout(new MigLayout("","10[]10","10[]10[]0[]0[]0[]0[]0[]0[]20[]0[]10"));
        //Label
        this.labelCodExt = new JLabel("Código");
        this.labelRazSoc = new JLabel("Razão Social");
        this.labelFantasia = new JLabel("Nome Fantasia");
        this.labelCNPJ = new JLabel("CNPJ");
        this.labelInscEst = new JLabel("Insc.Estadual");
        this.labelFilial = new JLabel("Filial");
        this.labelEndereco = new JLabel("Endereço");
        this.labelBairro = new JLabel("Bairro");
        this.labelCidade = new JLabel("Cidade");
        this.labelCep = new JLabel("Cep");
        this.labelEstado = new JLabel("Estado");
        this.labelTelefone = new JLabel("Telefone");
        this.labelEmail = new JLabel("Email");
        //Campos de texto
        this.codExt = new JTextField(10);
        this.razaoSocial = new JTextField(40);
        this.nomeFantasia = new JTextField(40);
        this.cnpj = new JFormattedTextField(AjudanteSwing.getMascara("##.###.###/####-##", '0'));
        this.inscEst = new JFormattedTextField(AjudanteSwing.getMascara("####.####.####.####", '0'));
        this.filial = new JTextField(10);
        this.endereco = new JTextField(40);
        this.bairro = new JTextField(20);
        this.cidade = new JTextField(20);
        this.cep = new JFormattedTextField(AjudanteSwing.getMascara("#####-###", '0'));
        this.estado = new JTextField(20);
        this.telefone = new JFormattedTextField(AjudanteSwing.getMascara("(##)####-####", '0'));
        this.email = new JTextField(60);
        this.painelConInf.add(new JLabel(AjudanteSwing.getImageIcon(this, "images/iconeCliente.jpg")), "wrap");
       
        //auxiliares para montagem do layout
        JPanel aux1 = new JPanel();
        aux1.setLayout(new FlowLayout(FlowLayout.LEADING));
        aux1.add(this.labelCodExt);
        aux1.add(this.codExt);
        aux1.add(this.labelRazSoc);
        aux1.add(this.razaoSocial);
        this.painelConInf.add(aux1, "wrap");

        JPanel aux2 = new JPanel();
        aux2.setLayout(new FlowLayout(FlowLayout.LEADING));
        aux2.add(this.labelFantasia);
        aux2.add(this.nomeFantasia);
        aux2.add(this.labelCNPJ);
        aux2.add(this.cnpj);
        this.painelConInf.add(aux2, "wrap");

        JPanel aux3 = new JPanel();
        aux3.setLayout(new FlowLayout(FlowLayout.LEADING));
        aux3.add(this.labelInscEst);
        aux3.add(this.inscEst);
        aux3.add(this.labelFilial);
        aux3.add(this.filial);
        aux3.add(this.labelTelefone);
        aux3.add(this.telefone);
        this.painelConInf.add(aux3, "wrap");

        JPanel aux4 = new JPanel();
        aux4.setLayout(new FlowLayout(FlowLayout.LEADING));
        aux4.add(this.labelEndereco);
        aux4.add(this.endereco);
        aux4.add(this.labelBairro);
        aux4.add(this.bairro);
        this.painelConInf.add(aux4, "wrap");

        JPanel aux5 = new JPanel();
        aux5.setLayout(new FlowLayout(FlowLayout.LEADING));
        aux5.add(this.labelCidade);
        aux5.add(this.cidade);
        aux5.add(this.labelCep);
        aux5.add(this.cep);
        aux5.add(this.labelEstado);
        aux5.add(this.estado);
        this.painelConInf.add(aux5, "wrap");

        JPanel aux6 = new JPanel();
        aux6.setLayout(new FlowLayout(FlowLayout.LEADING));
        aux6.add(this.labelEmail);
        aux6.add(this.email);
        this.painelConInf.add(aux6, "wrap");

        //tabela de Técnicos associados aos Clientes
        this.labelTecnicos = new JLabel("Responsável Técnico");
        AnnotationResolver resolver = new AnnotationResolver(Cliente.class);
        this.modeloTecnicos = new ObjectTableModel<Cliente>(resolver, "tecnicos.id:ID,tecnicos.codigoExterno:CÓDIGO,tecnicos.descricao:NOME");
        this.tabelaTecnicos = new JTable(this.modeloTecnicos);
        this.tabelaTecnicos.getTableHeader().setReorderingAllowed(false);
        this.tabelaTecnicos.setSelectionMode(0);
        this.tabelaTecnicos.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        this.tabelaTecnicos.setRowSelectionAllowed(false);
        this.scrollTecnicos = new JScrollPane(this.tabelaTecnicos);
        this.scrollTecnicos.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        this.scrollTecnicos.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        this.scrollTecnicos.setVisible(true);
        int [] tamColunas = {25, 70, 355};
        AjudanteSwing.ajustarTamanhoDasColunas(tabelaTecnicos, tamColunas);
        this.painelConInf.add(this.labelTecnicos, "wrap");
        this.painelConInf.add(this.scrollTecnicos);

        return this.painelConInf;
    }
...
private void preencheInformacoes(){
        modeloTecnicos.clear();
        if(linha != -1){
            Integer id = Integer.parseInt(tabela.getValueAt(linha, 0).toString());
            session = HibernateUtil.getSessionFactory().openSession();
            GenericDAO<Cliente> dao = new GenericDAO<Cliente>(Cliente.class, session);

            if(abas.getSelectedIndex() == 1){
                try{
                    Cliente cli = dao.findByID(id);

                    codExt.setText(cli.getCodigoExterno().toString());
                    razaoSocial.setText(cli.getRazaoSocial());
                    nomeFantasia.setText(cli.getNomeFantasia());
                    cnpj.setText(cli.getCnpj());
                    inscEst.setText(cli.getInscEst());
                    filial.setText(cli.getFilial().toString());
                    endereco.setText(cli.getEndereco());
                    bairro.setText(cli.getBairro());
                    cidade.setText(cli.getCidade());
                    cep.setText(cli.getCep());
                    estado.setText(cli.getEstado());
                    telefone.setText(cli.getTelefone());
                    email.setText(cli.getEmailPrincipal());
                    
                    modeloTecnicos.setData(null);
                    /*
                    Iterator it = cli.getTecnicos().iterator();
                    for(int i = 0; i < cli.getTecnicos().size();i++){
                        Tecnicos tec = (Tecnicos) it.next();
                        tabelaTecnicos.adicionar(new Object[]{tec.getId(),
                            tec.getCodigoExterno(), tec.getDescricao()});
                    }*/

                }
                catch(HibernateException ex){
                    JOptionPane.showMessageDialog(null, "Erro: "+ex.getMessage(),
                        "Erro", JOptionPane.ERROR_MESSAGE);
                }
                catch(Exception ex){
                    JOptionPane.showMessageDialog(null, "Erro: "+ex.getMessage(),
                        "Erro", JOptionPane.ERROR_MESSAGE);
                }
                finally{
                    session.close();
                }
            }
        }
    }
Marky.Vasconcelos

Pera ai, voce quer mostrar quais dados?

Voce quer exibir os Tecnicos de um Cliente?

Voce pode usar esse:

this.modelo = new ObjectTableModel<Tecnicos>(resolver, "id,codigoExterno,descricao,email,situ_reg,empresa.emp_nome:EMPRESA");

Mas na lsita de dados voce passa:

modelo.addAll(cliente.getTecnicos());
Marky.Vasconcelos

Voce usou Generics para todos os models com

private ObjectTableModel<Cliente> modelo, modeloTecnicos, modeloHisVen;

O correto seria:

private ObjectTableModel<Cliente> modelo;
private ObjectTableModel<Tecnico>modeloTecnicos;
private ObjectTableModel<TipoDesse> modeloHisVen;
K

O que eu estou fazendo é o seguinte:
na primeira aba do meu dialog o usuario clica no botao pesquisar e pesquisa os clientes, eu coloquei um evento para quando o usuario selecionar um cliente na tabela de clientes ele preencheria varios JTextField de uma segunda aba com as informacoes do cliente ex(cnpj, iest,…) e ao mesmo tempo preencher uma tabela com todos os técnicos que atendem o determinado cliente.

K

Marky consegui resolver graças a sua dica de uma modelo para cada tipo de objeto.

Gostaria de saber agora se é possivel inserir linhas em branco em tempo de execucao usando o seu modelo??

vlw.

Marky.Vasconcelos

Voce pode adicionar um objeto novo no modelo, como ele não vai ter valor então vai aparecer em branco.

Criado 16 de fevereiro de 2011
Ultima resposta 17 de fev. de 2011
Respostas 26
Participantes 2