Search code examples
javaswingjtabletablecellrenderer

Change background color of JTable whole row based on column value


So what I am trying to do, is to change the color of each row based on values inside of the last column.

I already found this solution: Change Background Color of JTable which worked very well.

But in addition I want to switch the color of the row to green when the fourth column reaches the same value as the second one.

I used the approach of Cristian Marian and wrote my own class

    @Override
public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
    Component comp = super.prepareRenderer(renderer, row, column);


        int second = (int) this.getModel().getValueAt(row, 1);
        int forth = (int) this.getModel().getValueAt(row, 3);
        int kat = Kategorie.getNumber((String) this.getModel().getValueAt(row, 2)); 
        if (kat > 0) {
            if (second == forth) {
                comp.setBackground(Color.GREEN);
            } else {
                comp.setBackground(Color.RED);
            }
        }

    return comp;
}

Still only the last cell in each column changes to green instead of the whole one. But when I clock on the row, the whole row switches the color

The values in the last column are changed by another frame.

Table at the beginning: https://i.sstatic.net/qIIVf.jpg

When the value in the last column reaches the same value as in the second one it looks like this:

After reaching the given value: https://i.sstatic.net/pSzU7.jpg


Solution

  • The problem with your approach is that you use getTableCellRendererComponent so only that cell will have its color changed.

    I had to make something similar. Based on the value of a column, I had to color the row.

    I used a class that extended the JTable and Override prepareRenderer

    @Override
    public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
        Component comp = super.prepareRenderer(renderer, row, column);
        if (populated) {  //this if was just to make sure that I have data in my table
            /*
            *This piece makes the code ignore the rows that are selected as this approach messes up that blue color that selected rows get
            */
            int[] rows = this.getSelectedRows();
            boolean rowisSelected = false;
    
            for (int rowIndex : rows) {
                if (row == rowIndex) {
                    rowisSelected = true;
                    break;
                }
            }
            /*
            *And this is the part that does the coloring
            */
            if (!rowisSelected) {
                Integer status = Integer.parseInt((String) 
                int modelRow = convertRowIndexToModel(row);
                this.getModel().getValueAt(modelRow, Constants.HIDDEN_COLUMN));
                switch (status) {
                case 1:
                    comp.setForeground(Color.BLACK);
                    comp.setBackground(Color.WHITE);
                    break;
                case 2:
                    comp.setForeground(Color.LIGHT_GRAY);
                    comp.setBackground(Color.WHITE);
                    break;
                case 3:
                    comp.setForeground(Color.BLACK);
                    comp.setBackground(Constants.DOWNLOADED_COLOR);
                    break;
                case 4:
                    comp.setForeground(Color.LIGHT_GRAY);
                    comp.setBackground(Constants.DOWNLOADED_COLOR);
                    break;
                }
            }
        }
        return comp;
    }
    

    Yours should be something like this (without the selected row thing):

    @Override
    public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
        Component comp = super.prepareRenderer(renderer, row, column);
        int modelRow = convertRowIndexToModel(row);
        String second = this.getModel().getValueAt(modelRow, 1));
        String forth= this.getModel().getValueAt(modelRow, 3));
        if(second.equals(forth)){
            comp.setBackground(Color.GREEN);
        }
        return comp;
    }