Imagem em um Jtable

Galera preciso colocar uma imagem em algumas celulas de um Jtable, Mas como fazer isso?
tentei da forma abaixo mas na celula aparece o caminho da imagem e não a imagem;

DefaultTableModel modelo=(DefaultTableModel)JTable1.getModel(); modelo.setValues(new ImageIcon("/Imagem/amarelo.png"),1,4);

Alguem pode me ajudar? Valeu!!!

Pesquise como fazerseu proprio tablecellrenderer…

se nao me engano tem algo sobre isso na seção de artigos do guj…

DefaultTableModel é problemático. Ele acessa métodos polimórficos de dentro do construtor.

Ao invés disso, use alguma coisa que herde de AbstractCellEditor, ou implemente TableCellEditor e herde de Object.

Observe que o retorno do método getTableCellRendererComponent é um java.awt.Component, que é o componente que será usado para renderizar a célula. Normalmente esse componente é um JLabel, mas você pode sobrescrever esse método para ele retornar qualquer outra coisa, inclusive algum componente com imagens.

Aliás, é possível colocar-se imagens em JLabel :slight_smile:

public class MeuCellRenderer extends AbstractCellEditor {

    private JLabel renderer = ...;

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
        renderer.setIcon(...);
        renderer.setText(...);
        renderer.setXXX(...);
        return renderer;
    }
}

Fods deste metodo utilizando o TableCellRenderer é que ele monta uma formatação unica para a tabela como o todo, queri algo mais facil, mas pelo jeito não tem, imagina montar uma tabela como a de baixo, eu to fudido.

[quote=Shakall]Fods deste metodo utilizando o TableCellRenderer é que ele monta uma formatação unica para a tabela como o todo, queri algo mais facil, mas pelo jeito não tem, imagina montar uma tabela como a de baixo, eu to fudido.

[/quote]

Sim, isso é um saco. Já virei uma madrugada aqui na empresa por causa de uma tabela desse tipo. Virou uma godclass extremamente gambiarrizada com mais de 3 mil linhas. Depois refatorei ela e se tornou 29 classes diferentes, mais ainda são 29 classes de POG. :slight_smile:

Basicamente, o jeito mais simples (mas não o melhor, mas já vai quebrar o seu galho) é:

public class MeuCellRenderer extends AbstractCellEditor {

    private static Color LARANJA = new Color(255, 128, 0);

    private JLabel renderer = new JLabel();

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
        if (row == 0) {
            renderer.setBackground(Color.CYAN);
        } else if (condicaoDeCelulaLaranja) {
            renderer.setBackground(LARANJA);
        } else {
            renderer.setBackground(Color.DARK_GRAY);
        }

        if (column == 1) {
            ...
        } else if (column == 2) {
            ...
        } ...
        return renderer;
    }
}

O ideal seria você tentar criar uma classe de CellRenderer por coluna, para acabar com a maioria destes ifs. Mas desse jeito aí em cima já vai resolver.

então a idéia éque cada vez que ele for desenhar uma celula ele chama este método? assim eu consigo verificar através dos parametros row e columm qual a celula que estou no momento.

Exato. Pode usar os demais parâmetros se for necessário.
E é recomendado você reutilizar sempre o mesmo JLabel. O JTable foi projetado para reutilizar os componentes das CellRenderers e CellEditors, assim você não precisa criar centenas deles, um para cada célula. Normalmente basta criar apenas 1.

fiz desta forma:

[code]public class Table extends DefaultTableCellRenderer {

@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
    if (isSelected) {
        setBackground(table.getSelectionBackground());
    } else {
        setBackground(table.getBackground());
    }

    if ((row == 0 || row==2|| row==3|| row==6|| row==7|| row==10) && column==4) {
        setIcon(new ImageIcon(getClass().getResource("/Imagem/amarelo.png")));
    } else if (row == 4 || row==9) {
        setIcon(new ImageIcon(getClass().getResource("/Imagem/vermelho.png")));
    } else if (row == 8) {
        setIcon(new ImageIcon(getClass().getResource("/Imagem/verde.png")));
    }else{
        setIcon(null);
    }
    if(row==1|| row==5|| row==11){//laranja
        setBackground(Color.gray);
    }
    if(row==12){//vermelha
        setBackground(Color.GRAY);
    }

    return this;
}

}[/code]

agora como eu jogo este render na jtable que possuo?

[quote=Shakall]fiz desta forma:

[code]public class Table extends DefaultTableCellRenderer {

@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
    if (isSelected) {
        setBackground(table.getSelectionBackground());
    } else {
        setBackground(table.getBackground());
    }

    if ((row == 0 || row==2|| row==3|| row==6|| row==7|| row==10) && column==4) {
        setIcon(new ImageIcon(getClass().getResource("/Imagem/amarelo.png")));
    } else if (row == 4 || row==9) {
        setIcon(new ImageIcon(getClass().getResource("/Imagem/vermelho.png")));
    } else if (row == 8) {
        setIcon(new ImageIcon(getClass().getResource("/Imagem/verde.png")));
    }else{
        setIcon(null);
    }
    if(row==1|| row==5|| row==11){//Cinza
        setBackground(Color.gray);
    }
    if(row==12){//Vermelho
        setBackground(Color.red);
    }

    return this;
}

}[/code]

agora como eu jogo este render na jtable que possuo?[/quote]

Outra coisa tu sabe como eu faço pra deixar alguns valores centralizados?

label.setHorizontalAlignment(JLabel.RIGHT);
label.setHorizontalAlignment(JLabel.LEFT);
label.setHorizontalAlignment(JLabel.CENTER);

label.setVerticalAlignment(JLabel.TOP);
label.setVerticalAlignment(JLabel.BOTTOM);
label.setVerticalAlignment(JLabel.CENTER);

[quote=Shakall]fiz desta forma:

...

agora como eu jogo este render na jtable que possuo?[/quote]

Cara, DefaultTableCellRenderer é uma faca de dois gumes, é importante que você saiba.

O primeiro porém é que DefaultTableCellRenderer EXTENDS JLabel. Esse é um caso de mau uso de herança. Por um lado é fácil, pois a maioria dos detalhes cruéis de renderização da célula já são tratados pelo DefaultTableCellRenderer e o método getTableCellRendererComponent sempre retorna this. O problema é quando você quer mudar o tipo de retorno disso ou então não gosta de algumas das propriedades padrão do DefaultTableCellRenderer.

Um dia desses eu tava com um problema parecido com o teu, fiz a classe que extendia DefaultCellRender e mesmo assim não funcionava.
Para resolver o problema :

table.setAutoCreateColumnsFromModel(false);
TableCellRenderer weirdRenderer = new WeirdRenderer();
table = new JTable(...) {
    public TableCellRenderer getCellRenderer(int row, int column) {
        if ((row == 0) && (column == 0)) {
            return weirdRenderer;
        }
        // else...
        return super.getCellRenderer(row, column);
    }
};

fonte: http://java.sun.com/docs/books/tutorial/uiswing/components/table.html

ok valeu consegui fazer o que eu queria!!