TableCellRenderer problem

I am trying to create a custom renderer for a column in a JTable. I need to paint the background red and the foreground white when a cell in this column contains a number greater than a threshold value. Below is what I have:

MyTableModel model =new MyTableModel();

model.addColumn("Date/Time");

model.addColumn("Working");

JTable table =new JTable(model);

final TableCellRenderer dcr = table.getDefaultRenderer(model.getColumnClass(1));

TableColumn tc = table.getColumn("Working");

tc.setCellRenderer(new TableCellRenderer(){

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

Component comp = dcr.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col);

if(col == 1 && ((Long)value).intValue() > THRESHOLD){

comp.setForeground(Color.WHITE);

comp.setBackground(Color.RED);

}

return comp;

}

});

This colors the cell fine, but then if the window is resized, all cells are painted this way, no longer just the one. Any ideas? Thanks in advance.

[1761 byte] By [jclemona] at [2007-11-27 7:27:09]
# 1

Create a separate return Component each time the getTableCellRendererComponent method is called and don't rely on the Component returned by the super (which I think is typically equal for all cells with the same data type (Long, in your case))

This works for me:import java.awt.Color;

import java.awt.Component;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JScrollPane;

import javax.swing.JTable;

import javax.swing.table.TableCellRenderer;

/**

* @author Mark Jeronimus

* @since 1.0

* @see

*

* date 2007/06/12

*/

public class TableCellDemo extends JFrame

{

final intTHRESHOLD= 3;

public static void main(String[] args)

{

new TableCellDemo();

}

public TableCellDemo()

{

super("Test");

super.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

super.setSize(300, 300);

JTable table =

new JTable(new Object[][]{{new Long(1), new Long(1)}, {new Long(2), new Long(2)}, {new Long(3), new Long(3)}, {new Long(4), new Long(4)},

{new Long(5), new Long(5)}}, new String[]{"Date/Time", "Working"});

table.getColumnModel().getColumn(1).setCellRenderer(new TableCellRenderer() {

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

{

JLabel comp = new JLabel(value.toString());

//Add code for editable cells here

if (((Long)value).intValue() > THRESHOLD)

{

comp.setOpaque(true);

comp.setForeground(Color.WHITE);

comp.setBackground(Color.RED);

}

return comp;

}

});

super.add(new JScrollPane(table));

super.setVisible(true);

}

}

Remember to configure your own MyTableModel (which I omitted) to set all cells non-editable, otherwise, add the following lines:if (value instanceof String)

{

try

{

value = new Long(Long.parseLong(value.toString()));

}

catch (NumberFormatException e)

{

value = new Long(0);

}

}

Zom-Ba at 2007-7-12 19:07:34 > top of Java-index,Desktop,Core GUI APIs...
# 2

> Create a separate return Component each time the getTableCellRendererComponent method is called

That defeats the whole purpose of using a renderer. The idea of using a renderer is that a single compnent can be used to renderer all the cells. Its very inefficient to create a new component every time a cell needs to be rendered.

The problem is that the foreground and background are not reset to the default value when you invoke super.getTableCellRendererComponent(...). So you simply need to add an else condition to your code:

else

{

comp.setBackground( table.getBackground() );

comp.setForeground( table.getForeground() );

}

camickra at 2007-7-12 19:07:34 > top of Java-index,Desktop,Core GUI APIs...
# 3
Hmm, sounds logical. But how does one create and re-use a custom component for when the table contains objects of user types (eg. Vector3D) then?
Zom-Ba at 2007-7-12 19:07:34 > top of Java-index,Desktop,Core GUI APIs...
# 4
Adding an else clause didn't help.I don't understand why the conditions of the IF clause are not being applied when the window is resized. I put some info logs in there and it says it's only applying it to column 1 cells, yet it's setting it for every cell in the table.
jclemona at 2007-7-12 19:07:34 > top of Java-index,Desktop,Core GUI APIs...
# 5

> Adding an else clause didn't help.

If you need further help then you need to create a [url http://homepage1.nifty.com/algafield/sscce.html]Short, Self Contained, Compilable and Executable, Example Program[/url] (SSCCE) that demonstrates the incorrect behaviour, because I can't guess exactly what you are doing based on the information provided.

Don't forget to use the [url http://forum.java.sun.com/help.jspa?sec=formatting]Code Formatting Tags[/url] so the posted code retains its original formatting.

> But how does one create and re-use a custom component for when .

> the table contains objects of user types (eg. Vector3D) then?

Don't understand the question. I don't know how you display a Vector3D. If you use the Vector to create some kind of image then it would be more efficient to create the image before hand and then store an ImageIcon in the table, then the icon would just be added to the renderer and painted.

camickra at 2007-7-12 19:07:34 > top of Java-index,Desktop,Core GUI APIs...