javaswingjtablecellrenderer

JTable CellRenderer changes foreground color only when focused


I am trying to implement a cellrenderer that changes color depending on the value of an integer. However, the color of the cell changes only when focused on. See picture below.

@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row,
        int column) {
    super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);

    switch (column) {
        case 1:this.setFont(this.getFont().deriveFont(Font.BOLD)); break;
        case 3:this.setFont(this.getFont().deriveFont(Font.BOLD)); break;
    }
    if (column == 4 && (Integer)value > 0) {
        setForeground(Color.green);
    } else {
        setForeground(Color.red); 
    }
    return this;
}

enter image description here


Solution

  • I guess your table isn't firing the correct update event, so there is no redraw of the cell.

    A MRE incorporating all the given code that fails to reproduce the problem:

    import java.awt.*;
    import javax.swing.*;
    
    class Code extends javax.swing.table.DefaultTableCellRenderer {
        public static void main(String[] args) throws Throwable {
            java.awt.EventQueue.invokeLater(Code::go);
        }
        private static void go() {
            JTable table = new JTable(
                new Object[][] {  { 0, 1, 2, 3, 4 }, { 1, 2, 3, 4, 5 } },
                new Object[] { "0", "1", "2", "3", "3" }
            );
            table.setDefaultRenderer​(Object.class, new Code());
            JFrame frame = new JFrame("Table");
            frame.add(table);
            frame.pack();
            frame.setVisible(true);
    
            new Timer(1000, event -> {
                table.setValueAt(
                    -(Integer)table.getValueAt(0, 4),
                    0, 4
                );
            }).start();
        }
        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row,
                int column) {
            super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
    
            switch (column) {
                case 1:this.setFont(this.getFont().deriveFont(Font.BOLD)); break;
                case 3:this.setFont(this.getFont().deriveFont(Font.BOLD)); break;
            }
            if (column == 4 && (Integer)value > 0) {
                setForeground(Color.green);
            } else {
                setForeground(Color.red); 
            }
            return this;
        }
    }