[RESOLVIDO] Exibir imagem com ObjectTableModel e JTable

5 respostas
V

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!

5 Respostas

V

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


M

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

V

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é +!

M

Hehhe… e ainda tem gente que perde tempo com DefaultTableModel

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

V

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é +!

Criado 10 de abril de 2012
Ultima resposta 12 de abr. de 2012
Respostas 5
Participantes 2