[RESOLVIDO] Exibir imagem com ObjectTableModel e JTable

Boa tarde pessoal.

Estou precisando exibir um ícone/imagem para cada registro de um JTable. Venho utilizando o ObjectTableModel do framework Towel 1.2.2 (excelente framework) e estou com algumas dúvidas para renderizar a imagem nas células da tabela.

A situação é a seguinte: Eu recebo do BD uma lista de objetos Produto, e cada um contém um atributo String nome e um atributo byte[] foto. Ao popular o ObjectTableModel com a lista de produtos, o nome do produto aparece, mas a foto não. Estava aparecendo um valor em hex (provavelmente o valor hex dos bytes). Agora consegui fazer aparecer a string de um objeto do tipo ImageIcon, mas não o ícone em si (ver imagem abaixo).

Seguindo este tópico (http://www.guj.com.br/java/211452-resolvidoobjecttablemodel-e-imageicon) eu tentei implementar um Formatter e um CellRenderer para exibir a imagem, mas sem sucesso. Gostaria de saber se alguém já passou por situação parecida ou se tem alguma idéia que possa ajudar. Segue um exemplo do que fiz até agora:

ImageFormatter.java

import com.towel.bean.Formatter;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import javax.swing.ImageIcon;

public class ImageFormatter implements Formatter
{

    public ImageIcon format(Object o)
    {
        try
        {
            //formata byte[] para ImageIcon
            ByteArrayOutputStream bStream = new ByteArrayOutputStream();
            ObjectOutputStream oStream = new ObjectOutputStream(bStream);
            oStream.writeObject(o);
            ImageIcon icon = new ImageIcon(bStream.toByteArray());
            return icon;
        }
        catch (IOException ex)
        {
            System.out.println("Erro no format do Formatter: " + ex.getMessage());
            return null;
        }
    }

    public String getName()
    {
        return "ImageFormatter";
    }

    public ImageIcon parse(Object o)
    {
        try
        {
            ByteArrayOutputStream bStream = new ByteArrayOutputStream();
            ObjectOutputStream oStream = new ObjectOutputStream(bStream);
            oStream.writeObject(o);
            ImageIcon icon = new ImageIcon(bStream.toByteArray());
            return icon;
        }
        catch (IOException ex)
        {
            System.out.println("Erro no parse do Formatter: " + ex.getMessage());
            return null;
        }
    }
}

ImageCellRenderer.java

import java.awt.Component;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;

public class ImageCellRenderer extends DefaultTableCellRenderer
{

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
    {
        JLabel label = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);

        if (value != null)
        {
            try
            {
                /*ByteArrayOutputStream bStream = new ByteArrayOutputStream();
                ObjectOutputStream oStream = new ObjectOutputStream(bStream);
                oStream.writeObject(value);
                ImageIcon icon = new ImageIcon(bStream.toByteArray());
                setText((String) value);*/
                
                ImageIcon icon = (ImageIcon) value;               
                label.setIcon(icon);
            }
            catch (Throwable ex)
            {
                System.out.println("Erro: " + ex.getMessage());
            }
        }

        return label;
    }
}

Na classe Produto utilizei assim:

@Resolvable(formatter=ImageFormatter.class)
    private byte[] foto;

//getters and setters

Na tabela utilizei assim:

tabela.getColumnModel().getColumn(0).setCellRenderer(new ImageCellRenderer());

Obrigado!

Olá pessoal.

Consegui resolver. O problema era a forma em que eu estava transformando Object do método format(Object o) do Formatter para byte[] e alguns detalhes do CellRenderer. Resumindo, ficou assim:

ImageCellRenderer.java

import javax.swing.ImageIcon;
import javax.swing.table.DefaultTableCellRenderer;

public class ImageCellRenderer extends DefaultTableCellRenderer
{

    @Override
    protected void setValue(Object value)
    {
        ImageIcon icon = (ImageIcon) value;
        setIcon(icon);
    }
}

ImageFormatter.java

package br.pc.util;

import com.towel.bean.Formatter;
import javax.swing.ImageIcon;

public class ImageFormatter implements Formatter
{

    public ImageIcon format(Object o)
    {
        try
        {
            byte[] imageInByte = (byte[]) o;
            return new ImageIcon(imageInByte);
        }
        catch (Throwable ex)
        {
            System.out.println("Erro no format do Formatter: " + ex.getMessage());
            return null;
        }
    }

    public String getName()
    {
        return "ImageFormatter";
    }

    public ImageIcon parse(Object o)
    {
        try
        {
            byte[] imageInByte = (byte[]) o;
            return new ImageIcon(imageInByte);
        }
        catch (Throwable ex)
        {
            System.out.println("Erro no parse do Formatter: " + ex.getMessage());
            return null;
        }
    }
}


Parabéns, vou guardar essa solução como referencia.

Blz Marky! Parabéns pelo framework. Já venho usando a algum tempo e não consigo pensar mais em JTable sem o ObjectTableModel hehehe.

Aproveitando, gostaria de sugerir novamente que a lib do Towel fosse disponibilizada em algum repositório Maven, para facilitar a utilização dela em projetos Maven.

Até +!

Hehhe… e ainda tem gente que perde tempo com DefaultTableModel

Eu não sei como disponibilizo em um repositorio Maven.

Olha eu também nunca postei (só utilizo…rs), mas não deve ser complicado.

Aqui tem o tutorial da Apache: http://maven.apache.org/guides/mini/guide-central-repository-upload.html

Até +!