[RESOLVIDO]Foto em cada célula de uma coluna Jtable e não na coluna toda

Pessoal,

Estou desenvolvendo um aplicativo em que tem uma opção de “Pesquisar Pessoa”, que mostra em um JTable o resultado da busca ao Banco com os Dados: Código, Nome e Foto. Porém não estou conseguindo colocar a foto de cada pessoa na célula correspondente aos seus dados, mas somente na coluna toda!

O código que uso para inserir os dados e a foto é o seguinte (porém está colocando a foto do último registro buscado para todas as linhas coluna FOTO):

[code]
DefaultTableModel modelo = (DefaultTableModel) tabelaPesquisa.getModel();
modelo.setNumRows(0); // zera os dados da tabela caso haja

    try {

        while (rs.next()) {     
            // insere uma nova linha com os dados Código e Nome (o campo Foto vai estar vazio)           
            modelo.addRow(new Object[] {
                                        rs.getInt("CodPessoa"),
                                        rs.getString("Nome"),                                            
                                        });

            // pegando a foto do registro:
            SerialBlob blob = new SerialBlob(rs.getBlob("Foto"));
            BufferedInputStream bInputStream = new BufferedInputStream(blob.getBinaryStream());
            byte[]   dados = null;
            ImageIcon foto = null;
            try {
                dados = new byte[bInputStream.available()];
                bInputStream.read(dados, 0, dados.length);
                foto = new ImageIcon(dados); // cria a imagem 
            } catch (IOException ex) {
                System.out.println(ex.getMessage());
            }

            // Setanto a foto na 3ª coluna da JTable
            TableColumnModel columnModel = tabelaPesquisa.getColumnModel();
            JTableRenderer rendererImagem = new JTableRenderer(foto);     // classe JTableRenderer está abaixo           
            columnModel.getColumn(2). setCellRenderer(rendererImagem);
        }

    } catch (SQLException ex) {
        System.out.println(ex.getMessage());
    }[/code]

Classe interna responsável por inserir a imagem no JTable:

    // classe interna necessária para inserir as imagens nas células
    private final class JTableRenderer extends DefaultTableCellRenderer {
        ImageIcon imagem = null;

        public JTableRenderer(ImageIcon imagem){
            this.imagem = imagem;
            setValue(imagem);
        }
        @Override
	        protected void setValue(Object value) {
	            if (value instanceof ImageIcon) {
	                if (value != null) {
	                    ImageIcon d = (ImageIcon) value;
	                    setIcon(d);
	                } else {
	                    setText("");
	                    setIcon(null);
	                }
	            } else {
	                super.setValue(value);
	            }
	        }
    }

Alguém pode me ajudar a colocar a foto de cada pessoa na célula correspondente aos seus dados e não na coluna toda???
Obrigado :!:

O TableCellRenderer recebe este nome porque ele é responsável por desenhar uma célula mas é sempre configurado para uma coluna toda. Como você pode ver na documentação: http://download.oracle.com/javase/6/docs/api/javax/swing/table/TableColumn.html#setCellRenderer(javax.swing.table.TableCellRenderer)

Como no seu caso está colocando o CellRenderer com a foto da última pessoa, ela aparecerá para todos os registros.

Você teria que colocar o BufferedImage no seu array junto com os dados (nome e id). Aí precisa configurar o Renderer só uma vez, que ele irá fazer o restante do trabalho para você.

[quote=visola]O TableCellRenderer recebe este nome porque ele é responsável por desenhar uma célula mas é sempre configurado para uma coluna toda. Como você pode ver na documentação: http://download.oracle.com/javase/6/docs/api/javax/swing/table/TableColumn.html#setCellRenderer(javax.swing.table.TableCellRenderer)

Como no seu caso está colocando o CellRenderer com a foto da última pessoa, ela aparecerá para todos os registros.

Você teria que colocar o BufferedImage no seu array junto com os dados (nome e id). Aí precisa configurar o Renderer só uma vez, que ele irá fazer o restante do trabalho para você.[/quote]

Ops! Vlw pela dica. Vou testar e se der certo aviso! MAS uma dúvida… tenho que colocar no array o BufferedImage mesmo? não seria o array do tipo Byte ou a variável foto do tipo ImageIcon não? Vlw.

visola, será que poderia me explicar melhor como faço para :

[quote]configurar o Renderer só uma vez, que ele irá fazer o restante do trabalho para você.[/quote] ?? poderia me mostrar um código, porque tentei mas ainda não consegui! Teria como me mostrar com base no meu código inserido acima? Obrigado pela atenção.
Um Abç!

Você tem razão. ImageIcon é o correto.

Quando eu digo configurar o renderer uma única vez é configurá-lo fora do while, fora do seu loop e não precisa passar nenhum valor para ele no construtor. Na verdade você não precisa estender DefaultTableCellRenderer, pode estender JLabel e implementar TableCellRenderer diretamente. Assim, no método getTableCellRendererComponent você simplesmente pega o valor passado e coloca como ícone, algo do tipo:

private final class JTableRenderer extends JLabel implements TableCellRenderer {
   public Component getTableCellRendererComponent( // um monte de coisas aqui 
      if (value != null) {
         // Se só colocou ícones na coluna 2, então não pode sair outra coisa aqui
         ImageIcon d = (ImageIcon) value;
         this.setIcon(d);
      } else {
         this.setText("");
         this.setIcon(null);
      }
      return this;
   }
}

No seu código, coloque a linha 29 na linha 5 e tire o objeto que estava passando no construtor:

   columnModel.getColumn(2). setCellRenderer(new JTableRenderer());

Muito Obrigado, visola. Com sua ajuda consegui! :smiley:
vlw mesmo, que Deus continue lhe dando a sabedoria que tem! :wink:
Para outros que precisem, segue abaixo o código:

classe interna necessária para inserir as imagens nas células:

private class TableRenderer_Imagem extends JLabel implements TableCellRenderer{        

        public java.awt.Component getTableCellRendererComponent(javax.swing.JTable table,
               Object value, boolean isSelected, boolean hasFocus, int row, int column) {

            if (value instanceof ImageIcon) {
	            if (value != null) {
	                ImageIcon d = (ImageIcon) value;
	                setIcon(d);
	            } else {
	                setText("");
	                setIcon(null);
	            }
	        }

          return this;
        }

        @Override
        public void validate() {}
        @Override
        public void revalidate() {}
        @Override
        protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {}
        @Override
        public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {}
    }

método que preenche a tabela (JTable):

private void preencherJtable(ResultSet rs) {

       DefaultTableModel modelo = (DefaultTableModel) tabelaPesquisa.getModel();
       modelo.setNumRows(0); // zera os dados da tabela caso haja

        try {
            
            TableColumnModel columnModel = tabelaPesquisa.getColumnModel(); // obtém o modelo da minha tabela
            TableRenderer_Imagem rendererImagem = new TableRenderer_Imagem();
            columnModel.getColumn(2).setCellRenderer(rendererImagem);
            
            while (rs.next()) {

                // pegando a foto do registro:
                SerialBlob blob = new SerialBlob(rs.getBlob("Foto"));
                BufferedInputStream bInputStream = new BufferedInputStream(blob.getBinaryStream());
                byte[]   dados = null;
                ImageIcon foto = null;
                try {
                    dados = new byte[bInputStream.available()];
                    bInputStream.read(dados, 0, dados.length);
                    foto = new ImageIcon(dados); // cria a imagem
                } catch (IOException ex) {
                    System.out.println(ex.getMessage());
                }

                modelo.addRow(new Object[] {
                                            rs.getInt("CodPessoa"),
                                            rs.getString("Nome"),
                                            foto,
                                            });                                
            }

        } catch (SQLException ex) {
            System.out.println(ex.getMessage());
        }
    }