Colorir linha especifica em JTable

Ola,
Seguinte tenho um caso em que quando o usuario fizer uma retirada total de dinheiro a celula deve ser desabilitada e colorida de outra cor.
Ja tentei alterar o renderer em runtime mas nao deu certo, simplesmente nao acontece nada…

Alguma ideia ? :roll:
Valeu! :thumbup:

Linha 0 , Coluna 2

JComponent comp = (JComponent) this.table.getCellRenderer(0, 2);
comp.setForeground(new Color(255,255,128));

Ok, ele pinta todas as linhas, nao apenas a linha 0. :evil:

TableCellRenderer cellRenderer = this.table.getCellRenderer(0, 2);
JComponent comp = (JComponent) cellRenderer;
comp.setBackground(Color.YELLOW);

Aqui nao acontece nada. :evil:

Ideias? :slight_smile:

O problema é que você deve implementar um TableCellRenderer. Eu fiz um testezinho tosqueira aqui, e creio que seja o que você tá querendo:
Aí vai o renderer:

package help.guj.keller;

import java.awt.Color;
import java.awt.Component;
import java.awt.Font;

import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;

public class LineSelectionTableCellRenderer 
	extends DefaultTableCellRenderer 
{

	@Override
	public Component getTableCellRendererComponent(
		JTable table,
		Object value,
		boolean isSelected,
		boolean hasFocus,
		int row,
		int column)
	{
		Component result = super.getTableCellRendererComponent(
			table,
			value,
			isSelected,
			hasFocus,
			row,
			column
		);
		
		if(isSelected) {
			result.setFont(new Font("arial", Font.BOLD, 12));
			result.setForeground(Color.white);
			result.setBackground(Color.blue);
		}else {
			result.setFont(new Font("arial", Font.PLAIN, 12));
			result.setForeground(Color.gray);
			result.setBackground(Color.black);
		}
		return result;
	}
	
}

E agora a classe de teste

package help.guj.keller;

import java.awt.BorderLayout;
import java.awt.Container;

import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.table.TableCellRenderer;

public class TableTest {

	public static void main(String[] args) {
		Object[] columns = new Object[] {"Num", "BR", "EN"};
		JTable tbl = new JTable(
			new Object[][] {
				{5, "Cinco", "Five"},
				{7, "Sete", "Seven"},
				{2, "Dois", "Two"},
				{0, "Zero", "Zero"},
			},
			columns
		);
		TableCellRenderer renderer = new LineSelectionTableCellRenderer();
		for (int c = 0; c < tbl.getColumnCount(); c++) {
			tbl.setDefaultRenderer(tbl.getColumnClass(c), renderer);
		}
		
		JFrame dlg = new JFrame("Teste");
		Container c = dlg.getContentPane();
		c.add(tbl, BorderLayout.CENTER);
		dlg.setSize(300, 300);
		dlg.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		dlg.setVisible(true);
	}

}

Divirta-se!

Ola,

Cara eu tenho um CellRenderer aqui

package x.y.z.common.components.table.color;

import java.awt.Color;
import java.awt.Component;

import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * @author Guilherme Keller
 */
public class ColorCellRenderer extends DefaultTableCellRenderer {
	
	public static final int R = 206;
	public static final int G = 255;
	public static final int B = 221;
	
	private static final long serialVersionUID = 433648737270300478L;
	private static final Log log = LogFactory.getLog(ColorCellRenderer.class);
	private Color color;
	
	public ColorCellRenderer(){
		super();
		log.info("ColorCellRenderer::constructor");
	}
	
	public ColorCellRenderer(Color color){
		super();
		this.color = color;
	}

	@Override
	public Component getTableCellRendererComponent(	JTable table, 
													Object value,
													boolean isSelected, 
													boolean hasFocus, 
													int row, 
													int column ) {
		
		if( row%2 != 0 ){
			this.setBackground( new Color(R,G,B) );
		}else{
			this.setBackground(Color.WHITE);
		}
		
		if(this.color != null){
			this.setBackground( this.color );
		}
		
		return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
		
	}

    public void validate() {}
    public void revalidate() {}
	
}

Que ele ja esta aplicado na table, e conforme a necessidade eu seto outros renderers+editors, como para colunas com checkbox, combobox, campo de data, campo cpf, etc…

Porem esse e um caso em que eu gostaria de uma solucao mais elegante do que sobrescrever o CellRenderer.

O grande problema e que a JTable trabalha com colunas.
Se voce pegar a implementacao do metodo getCellRenderer(row, col) voce ve que ele desconsidera a linha e leva em consideracao apenas coluna.

Ainda procuro uma solucao mais elegante que sobrescrever o CellRenderer imagine se cada caso eu terei que escrever um CellRenderer ficara realmente bem complicado o desenvolvimento…

Mas valeu pela ajuda! :thumbup:

Grande Mantu! :lol:
Depois de horas apanhando pra JTable olhei pro meu ColorCellRenderer e veio a luz!

private int row = -1;
private Color color;
public ColorCellRenderer(Color color, int row){
	super();
	this.color = color;
	this.row = row;
}

public void getTableCell..(params..){
    ...
	if(this.color != null && this.row != -1){
		if(this.row == row){
			this.setBackground( this.color );
		}
	}
}

Usage:

this.table.getColumnModel().getColumn(2).setCellRenderer(new ColorCellRenderer(Color.YELLOW,0));
//Coluna 2 , Linha 0

Perfeito! Valeu! :thumbup:

[up]
Nao funciona em multiplas linhas :cry:

this.table.setEditableCells(editableCells);
		for(int i = 0; i&lt;this.table.getColumnCount(); i++){
			if(!CheckBoxRenderer.class.isAssignableFrom(this.table.getColumnModel().getColumn(i).getCellRenderer().getClass())){
				this.table.getColumnModel().getColumn(i).setCellRenderer(new ColorCellRenderer(new Color(255,255,190),0));
				this.table.getColumnModel().getColumn(i).setCellRenderer(new ColorCellRenderer(new Color(255,255,190),1));
			}
		}

Ele pinta apenas a linha 2… :evil:
[/up]

[up2]
Agora funciona corretamente!

No ColorCellRenderer: private int[] rows;

public Component getTable..(params){
if(this.color != null && this.rows != null){
	for (int i = 0; i &lt this.rows.length; i++) {
		int rowToPaint = this.rows[i];
		if(rowToPaint == row){
			this.setBackground(this.color);
			}
		}
	}else if(this.color != null){
		this.setBackground( this.color );
	}
}

Usage:

int[] rows = {0,1};
for(int i = 0; i&lt;this.table.getColumnCount(); i++){
 if(!CheckBoxRenderer.class.isAssignableFrom(this.table.getColumnModel().getColumn(i).getCellRenderer().getClass())){
	this.table.getColumnModel().getColumn(i).setCellRenderer(new ColorCellRenderer(new Color(255,255,190),rows));
 }
}

[/up2]

Funcionando! :smiley:

Disponha!
Eu não sei vocês, mas eu acho muito loco essa estrutura MVC do Swing! Fica tudo separadinho, arrumadinho e tal! Muito massa!

Muito obrigado Mantu. Usando a sua classe consegui pintar as linhas perfeitamente :smiley:

Galera tou pecisando pintar algumas colunas da minha JTable mas apenas após a escolha de um item de uma jcombox.
Sera que alguem me pode ajudar?

Cumprimentos e Obrigado

Consegui colorir as linhas perfeitamente inclusive trocar a cor em tempo de execução,
mas não estou conseguindo remover linhas, inclusive depois de renderizar a tabela, não consigo enviar textos para o console inclusive,
com System.out.println, isso não é o problema, mas gostaria de compreender.
O problema mesmo é eu não conseguir remover a linha, em outra tabela sem esse renderer a linha abaixo funciona:

tmOmissos.removeRow(tbVendas2.getSelectedRow());

porque na tabela colorida não???
vale lembrar que ela esta dentro de um JtabbedPane.

Sei que o post é antigo, tomara que leiam, e por favor me ajudem.

Olá pessoal, a pergunta vai acho que mais especificamente para o Keller.

Seguinte…
Eu consegui colorir as minhas células direitinho. Porém as linhas pretas da grid desaparecem. Mesmo usando o setCridColor(Color color) a bendita crid ainda não aparece se pinto as células. Mais alguém teve esse problema ?

Keller, na sua grid isso também acontece ?

Desde já obrigado pessoal!

Aew Turma blz?

Seguinte, tenho uma tabela que mostra um extrato de conta (data, historico, valor).
Estou, tentando deixa a linha colorida de vermelho onde o valor for negativo.
Mas só consigo colorir a coluna valor.
Como faço para deixar a linha inteira vermelha onde o valor for negativo?

Segui o codigo:

class ColoredTableCellRenderer extends DefaultTableCellRenderer {

    public ColoredTableCellRenderer() {
    }

    @Override  
    public Component getTableCellRendererComponent(  
        JTable table,  
        Object value,  
        boolean isSelected,  
        boolean hasFocus,  
        int row,  
        int column)  
    {  
        Component result = super.getTableCellRendererComponent(  
            table,  
            value,  
            isSelected,  
            hasFocus,  
            row,  
            column  
        );  
          
        if (column == 2 && (Float.parseFloat(value.toString()) < 0)){
            result.setFont(new Font("arial", Font.PLAIN, 12));
            result.setForeground(Color.red);              
        }else{
            result.setFont(new Font("arial", Font.PLAIN, 12));
            result.setForeground(Color.black);              
        }
       
        return result;  
    }  
}

Opa, consegui!!!

Foi só capturar o valor da coluna e comparar se é negativo.
Ficou assim:

Object ref = table.getValueAt(row, 2);
        if (ref != null && (Float.parseFloat(ref.toString()) < 0)) {
            result.setFont(new Font("arial", Font.PLAIN, 12));
            result.setForeground(Color.red);
        } else {
            result.setFont(new Font("arial", Font.PLAIN, 12));
            result.setForeground(Color.black);
        }