Aplicar TableCellRenderer apenas pra uma celula, tem como?

12 respostas
yurifw

eu tenho uma JTable, e usei um TableCellRenderer pra mostrar um icone em uma coluna.
meu problema é o seguinte:
eu preciso que quando o usuario aperte um botão, o icone da celula selecionada mude. eu não to conseguindo “atualizar” a celula, o meu metodo de mudar o icone esta funcionando, se eu usar um JOptionPane pra mostrar o icone ele aparece o icone certo, o que eu preciso é enviar esse icone pra celula, depois que eu inicio a tabela com akele CellRenderer eu ja n consigo mudar o que aparece la, tem algum jeito de fazer isso?

o que eu pensei seria usar uma instancia nova do CellRenderer diferente pra cada celula, por exemplo, qdo o usuario cliclar no botão eu faço uma nova instancia do CellRenderer com o icone novo e coloco esse CellRenderer so naquela celula, mas como faz isso?

muito obrigado xD

ah, e se alguem souber de um tutorial bom sobre CellRenderer e tiver como postar o link aki tb eu agradeço muito.

12 Respostas

ViniGodoy

O TableCellRenderer desenha um valor que está na tabela.

Faça-o desenhar com base no valor da coluna, que é fornecido pelo model. Quando o valor mudar, atualize o model e dispare um evento de tableCellChanged para aquela celula.

yurifw

o meu tableCellRenderer esta desenhando com o valor que eu passo na instancia dele, como faço pra fazer ele desenhar de acordo com o valor fornecido?

o codigo do meu CellRenderer:

public class TableCellRendererPersonalizado extends DefaultTableCellRenderer {
    ImageIcon icon = new ImageIcon(getClass().getResource("/imagens/nvl0.png"));
    String nome;
    public JLabel lbl = new JLabel();


    public TableCellRendererPersonalizado (ImageIcon icon) {
        this.icon=icon;                                                   
        
    }


    @Override
    public Component getTableCellRendererComponent (JTable table, Object value, boolean isSelected,
            boolean hasFocus, int row, int col) {
        lbl.setIcon(icon);
        return (JLabel)lbl;
    }
}

na hora de instanciar eu coloquei assim:

TableCellRendererPersonalizado tableCell = new TableCellRendererPersonalizado(new javax.swing.ImageIcon(getClass().getResource("/imagens/nvl0.png")));

e pra definir o CellRenderer eu fiz:

tableAntecedentes.setDefaultRenderer(Icon.class, tableCell);

eu sei mto pouco de tableCell, isso foi o que eu consegui lendo alguns posts aki do forum, mas n achei nenhum tutorial que tivesse o que eu precisava ^^"

ViniGodoy

Está vendo ali que um dos parâmetros recebidos no método getTableCellRendererComponent é o value?
Esse é o value que está na célula sendo desenhada. Basta usa-lo.

yurifw

mas eu so to conseguindo passar o icone quando eu instancio o Renderer, então como q eu vou usar o parametro?

ViniGodoy
public class IconCellRenderer extends DefaultTableCellRenderer {
    private Map<String, ImageIcon> icons = new HashMap<String, ImageIcon>();
    private JLabel lbl = new JLabel();

    public IconCellRenderer() {
    }

    @Override
    public Component getTableCellRendererComponent (JTable table, Object value, boolean isSelected,
        boolean hasFocus, int row, int col) {
        String resourceName = value.toString();
        ImageIcon icon = icons.get(value);
        if (icon == null) {
            icon = new ImageIcon(getClass().getResource(resourceName));
            icons.put(resourceName, icon);
        }
        
        lbl.setIcon(icon);
        return lbl;
    }
}

Agora é só fazer seu model retornar o nome do arquivo de recursos na coluna do ícone.

yurifw

cara, sem querer se chato nem nada, mas é q ta dando erro no codigo ^^"
na linha 13 (ta falando q n declarou a variavel)
e na linha 16 ta pedindo como parametro uma String e um Icon, ta dizendo q so achou a string, eu n mechi pq entendi mta pouca coisa do codigo

devo estar chato pra caramba ja, perdão ^^"

ViniGodoy

E você não conseguiu deduzir você mesmo o que estava errado?
Bom, já corrigi o código lá em cima…

Fiz de cabeça, por isso os erros.

yurifw

eu sabia o q tava errado, so n sabia consertar ^^"

yurifw

n, eu sabia o q tava errado mas eu n consegui resolver ^^"

public class AntecedenteDisciplinaModel extends AbstractTableModel{
    private final int COL_NOME=0;
    private final int COL_NIVEL=1;

    private List<AntecedenteDisciplina> antecedentes;

    public AntecedenteDisciplinaModel () {
        antecedentes = new ArrayList<AntecedenteDisciplina>();
    }

    public AntecedenteDisciplinaModel (List<AntecedenteDisciplina> lista) {
        antecedentes.addAll(lista);
    }

    public int getRowCount() {
        return antecedentes.size();
    }

    public int getColumnCount() {
        return 2;
    }

    public Object getValueAt(int rowIndex, int columnIndex) {
        AntecedenteDisciplina a = antecedentes.get(rowIndex);
        switch (columnIndex) {
            case COL_NOME:
                return a.getNome();
            case COL_NIVEL:
                return a.getNivel();
            default:
                return "Erro Desconhecido";
        }
    }

    @Override
    public void setValueAt (Object valor, int row, int col) {
        AntecedenteDisciplina a = antecedentes.get(row);
        if (col==COL_NOME) {
            //antecedentes.get(row).setNome(valor.toString());
            a.setNome(valor.toString());
        }
        if (col==COL_NIVEL) {
            //antecedentes.get(row).setNivel((JLabel)valor);
            a.setNivel((JLabel)valor);

        }
        fireTableDataChanged();
    }

    @Override
    public Class getColumnClass (int col) {
        if (col==COL_NIVEL)
            return Icon.class;
        else{
            return String.class;
        }
    }

    @Override
    public boolean isCellEditable (int row, int col) {
        if (col==COL_NIVEL)
            return false;
        return true;
    }

    public void excluir (int row) {
        antecedentes.remove(row);
        fireTableDataChanged();
    }

    public void inserir (AntecedenteDisciplina a) {
        antecedentes.add(a);
        fireTableDataChanged();
    }

    public void inserir () {
        AntecedenteDisciplina a = new AntecedenteDisciplina();
        JLabel label= new JLabel(new javax.swing.ImageIcon(getClass().getResource("/imagens/nvl0.png")));
        a.setNivel(label);
        a.setNome("");
        antecedentes.add(a);
        fireTableDataChanged();
    }

    @Override
    public String getColumnName (int col) {
        if (col==COL_NIVEL)
            return "Nivel";
        if (col==COL_NOME)
            return "Nome";
        return "Erro";
    }



}

qual metodo da table model tem que retornar o caminho do icone?

ViniGodoy

O getValueAt da coluna que você quiser apresentar o icone. Se for a de nível, a COL_NIVEL.

ViniGodoy

Se seu nível é um JLabel, então você poderia até fazer um Renderer para já usar o JLabel diretamente:

public class NivelCellRenderer extends DefaultTableCellRenderer {
    public NivelCellRenderer() {
    }

    @Override
    public Component getTableCellRendererComponent (JTable table, Object value, boolean isSelected,
        return value;
    }
}
Só lembre-se de dar um "fireTableCellUpdated" sempre que a célula tiver que mudar. E também troque a class da sua coluna de String.class para Nivel.class. Aí vc pode até associar o renderer a sua tabela com:
seuTable.setDefaultRenderer(Nivel.class, new NivelCellRenderer());
yurifw

cara, n teve jeito, n consegui, tentei tudo q vc disse mas n resolveu, agora nem o icone aparece mais na tabela =/
vou ter que me contentar em usar texto mesmo =/
foi mal desperdiçar seu tempo

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