4

i try to change the color of fields in a JTable according to their value. I don't want to change any color of the first column but it changes anyway in a buggy way(some fileds are not correctly filed like University and Possible_Reviewer):x is the first column

My code is as following:

table.setDefaultRenderer(Object.class, new CustomRenderer());

private class CustomRenderer extends DefaultTableCellRenderer {
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,boolean hasFocus, int row, int col){
         Component comp = super.getTableCellRendererComponent(table,  value, isSelected, hasFocus, row, col);
         try {
             Double val =  Double.parseDouble(value.toString());

             if(col == 0){
                 comp.setBackground(Color.white);
             } else {
                 comp.setBackground(changeColor(val));
             }
         } catch (NumberFormatException e){}
         return( comp );
    }

    private Color changeColor(Double val) {
        //returns a Color between red and green depending on val
    }
}

The weird thing is that when i use "col == 2" it turns the second column white but the first remains strangely colored.

Anyone an idea?

Heisenbug
  • 38,762
  • 28
  • 132
  • 190
kasten
  • 602
  • 2
  • 6
  • 17

2 Answers2

3

You should extend JTable class and override this method:

public TableCellRenderer getCellRenderer(int row, int column){}

Otherwise JTable will use the same renderer for each cell in the same column.

EDIT:

Like @Mark Bramnik pointed out, it's better to not instantiate a new TableCellRenderer object for every getCellRenderer call. You could implement a method like the following:

setCellRenderer(int row, int col, TableCellRenderer render) 

and store the renderer in the extended JTable itself.

Heisenbug
  • 38,762
  • 28
  • 132
  • 190
  • hi, note that you shouldn't return each time a new object of renderer from the getCellRenderer, otherwise in big tables it will be just too much objects in vain, and you can encounter performance-related issues. Try to minimize the amount of different renderer objects. – Mark Bramnik Aug 23 '11 at 09:27
  • @Mark Bramnik: yes I know that. I usually implement a setCellRenderer(int row, int col, TableCellRenderer render) and store the renderer in the extended table itself. I'll edit my answer thanks. – Heisenbug Aug 23 '11 at 09:29
  • +1 A limitation of this approach is that it affects the _view_ column. – trashgod Aug 23 '11 at 09:45
  • @trashgod: could you explain a bit more about this limitation? I'm not sure to have understand. – Heisenbug Aug 23 '11 at 09:49
  • Oops, my error; the problem would accrue to overriding `prepareRenderer()`. – trashgod Aug 23 '11 at 10:14
  • 1
    -1 for over-complicating ;-) There is very rarely any reason for a per-cell renderer, per-column is fine-grained enough. Besides, the renderer itself is designed to deal with configuration down to the cell, simply use a well-behaved implementation (note that DefaultTableCellRenderer is _not_ well-behaved) and do all config there as appropriate – kleopatra Aug 23 '11 at 12:08
  • @kleopatra what type of TableRenderer you'll preferred in all cases, what was/were your first word(s) in your mind, – mKorbel Aug 23 '11 at 16:33
3

How to Use Tables: Using Custom Renderers mentions this alternative approach: "To specify that cells in a particular column should use a renderer, you use the TableColumn method setCellRenderer()."

Addendum: A benefit of this approach is that the renderer "sticks" to the column if the user drags it to a different position. In this example, replace setDefaultRenderer() with setCellRenderer().

table.getColumnModel().getColumn(DATE_COL).setCellRenderer(new DateRenderer());
Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • doesn't setCellRenderer use the same renderer for each cell in the same column? – Heisenbug Aug 23 '11 at 09:14
  • Yes, but you can condition the appearance according to value, as shown [here](http://stackoverflow.com/questions/5798980/jtable-disable-checkbox-in-cell/5799016#5799016). – trashgod Aug 23 '11 at 09:33