Setting row color in JTable

I am trying to display some rows in a JTable in a different color regardless of selection status. The row color criteria would be from data from the object in the row, i.e., given a certain status of a record, I would want to show it as red instead of black.
[272 byte] By [jnaue] at [2007-9-26 2:38:54]
# 1

Hi ,

Are u using the Default Table Model or creating your own ?

If you are creating your own , try using colorTableRenderer,ColorTableCellRenderer ...

I havent used it till now but even me needs to use it in near future ( to near to be frank ! )

hope it helps ...

Max

gkaran at 2007-6-29 10:10:30 > top of Java-index,Archived Forums,Swing...
# 2

Hi ,

Are u using the Default Table Model or creating your own ?

If you are creating your own , try using colorTableRenderer,ColorTableCellRenderer ...

I havent used it till now but even me needs to use it in near future ( to near to be frank ! )

hope it helps ...

Max

gkaran at 2007-6-29 10:10:30 > top of Java-index,Archived Forums,Swing...
# 3

Hi Max,

I have solved the problem since this morning. I had already set up the Table Cell Renderer:

class StatusColorRenderer extends DefaultTableCellRenderer

{

public StatusColorRenderer()

{

super();

}

public Component getTableCellRendererComponent(JTable table,

Object value, boolean isSelected,

boolean hasFocus, int row, int column)

{

MyObjectClass myObject;

Component c = super.getTableCellRendererComponent(table,

value, isSelected, hasFocus, row, column);

myObject = (MyObjectClass ) myTableModel.getMyVector().elementAt(row);

if (myObject.getTheStatus().compareTo(Status.BAD_STAT) == 0)

c.setForeground(Color.red);

else if (myObject.getTheStatus().compareTo(Status.IN_PROGRESS) == 0)

c.setForeground(Color.green);

else if (myObject.getOtherFactor().compareTo(OtherFactors.NOT_DEFAULT) == 0)

c.setForeground(Color.blue);

else

c.setForeground(Color.black);

c.repaint();

((JLabel) c).setOpaque(true);

return c;

}

}

My problem (fix) was that I had to loop through and set as the Default renderer for every column:

for (int i =0; i<myTableModel.getColumnCount();i++)

{

column = myTable.getColumnModel().getColumn(i);

myTable.setDefaultRenderer(PendingBatchTable.getColumnClass(i), new StatusColorRenderer());

}

-John

>

jnaue at 2007-6-29 10:10:30 > top of Java-index,Archived Forums,Swing...
# 4
// oops - wrongmyTable.setDefaultRenderer(PendingBatchTable.getColumnClass(i), new StatusColorRenderer());SHOULD HAVE BEENmyTable.setDefaultRenderer(myTable.getColumnClass(i), new StatusColorRenderer());- John
jnaue at 2007-6-29 10:10:30 > top of Java-index,Archived Forums,Swing...
# 5

A few optimizations:

class StatusColorRenderer

extends DefaultTableCellRenderer

{

public StatusColorRenderer()

{

// super(); not needed, call by default

setOpaque(true);

// DefaultTableCellRenderer returns itself as a CellRenderer Component, it extends JLabel so you can call setOpaque on it

}

// since this method is called at every paint for every cell it should be HIGHLY optimized

public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)

{

Component c = super.getTableCellRendererComponent( table, value, isSelected, hasFocus, row, column);

MyObjectClass myObject = ( MyObjectClass ) myTableModel.getMyVector().elementAt(row);

<SomeClass> myStatus = myObject.getTheStatus();

if ( myStatus.compareTo(Status.BAD_STAT) == 0)

c.setForeground(Color.red);

else if (myStatus.compareTo(Status.IN_PROGRESS) == 0)

c.setForeground(Color.green);

else if ( myObject.getOtherFactor().compareTo(OtherFactors.NOT_DEFAULT) == 0)

c.setForeground(Color.blue);

else

c.setForeground(Color.black);

// c.repaint(); NEVER DO THAT

return c;

}

}

StatusColorRenderer myRenderer = new StatusColorRenderer();

// only one instance of the renderer

for ( int i = myTableModel.getColumnCount() - 1 ; i >= 0 ; i-- )

{

//column = myTable.getColumnModel().getColumn( i );

myTable.setDefaultRenderer( myTable.getColumnClass( i ),

myRenderer );

}

Comment:

AbstractTableModel and DefaultTableModel.getColumnClass method returns Object.class, it is used by the JTable to setup the editor and the renderer of a column

so if you're using the DefaultTableModel and JTable without overriden getColumnClass, you can set a generic renderer for your JTable by using:

myTable.setDefaultRenderer( Object.class, myRenderer );

Titie at 2007-6-29 10:10:30 > top of Java-index,Archived Forums,Swing...