Imagem em um Jtable

14 respostas
S

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

14 Respostas

_Renatu

Pesquise como fazerseu proprio tablecellrenderer…

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

victorwss

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

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.

victorwss

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.

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.

S

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.

victorwss

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.

S

fiz desta forma:

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

agora como eu jogo este render na jtable que possuo?

S
Shakall:
fiz desta forma:
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;
    }
}

agora como eu jogo este render na jtable que possuo?

S

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

victorwss
label.setHorizontalAlignment(JLabel.RIGHT);

label.setHorizontalAlignment(JLabel.LEFT);

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

label.setVerticalAlignment(JLabel.BOTTOM);

label.setVerticalAlignment(JLabel.CENTER);
victorwss

Shakall:
fiz desta forma:

...

agora como eu jogo este render na jtable que possuo?

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.

ivo_costa

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);
victorwss
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

S

ok valeu consegui fazer o que eu queria!!

Criado 3 de julho de 2008
Ultima resposta 4 de jul. de 2008
Respostas 14
Participantes 4