FlorianB
FlorianB

Reputation: 31

Swing JTable - Change background color of a row in function of the previous row

I have a swing JXTable and the requirement is that background color must change if a field differs from the previous row.

Here is an example :

I've tried several solutions.

Overriding prepareRenderer, but this solution is not working fine. The lines blinks and color changes in function of the first line visible in the table.

    @Override
public Component prepareRenderer(TableCellRenderer renderer, int row, int column)
{
    Component c = super.prepareRenderer ( renderer , row , column );
    if(lastRow  != -1)
    {
        Data actualData = ( ( MessagesTableModel ) getModel ( ) ).getData ( row );
        Data previousData = ( ( MessagesTableModel ) getModel ( ) ).getData ( lastRow );
        if ( previousData != null )
        {
            if ( previousData.getNbr ( ) != actualData.getNbr ( ) )
            {
                if(lastColor.equals ( COLOR1 ))
                {
                    System.out.println ("A");
                    lastColor = COLOR2;
                }
                else
                {
                    System.out.println ("b");
                    lastColor = COLOR1;
                }
            }
        }
    }
    lastRow = row;
    c.setBackground ( lastColor );
    return c;
}

I've also think of defining a custom TableCellRender, but it was not concluant.

So I'm stuck I don't know how to do. Do you have any suggestions ?

EDIT

I've tried with HighlightPredicate since I'm using JXTable

        HighlightPredicate predicate = new HighlightPredicate ( )
    {
        public boolean isHighlighted(Component renderer, ComponentAdapter adapter)
        {
            Data actualData = ( ( MessagesTableModel ) getModel ( ) ).getData ( adapter.row );
            if ( adapter.row - 1 >= 0 )
            {
                Data previousData = ( ( MessagesTableModel ) getModel ( ) )
                        .getData ( adapter.row - 1 );
                if ( actualData.getNbr ( ) != previousData.getNbr ( ) )
                {   
                    return true;
                }

            }
            return false;
        }
    };

    addHighlighter ( new ColorHighlighter ( predicate , COLOR1 , null ) );

This time, the color changes if the value change, but if the row right after is not changing, the color changes.

This is normal because that's what is coded :) But I'm in front of the same problem, how to know if the previous row was highlighted or not.

EDIT 2

I've found a solution, don't seem very clean but it works.

        HighlightPredicate predicate = new HighlightPredicate ( )
    {
        public boolean isHighlighted(Component renderer, ComponentAdapter adapter)
        {
            Data actualData = ( ( MessagesTableModel ) getModel ( ) ).getData ( adapter.row );
            if ( adapter.row - 1 >= 0 )
            {
                Data previousData = ( ( MessagesTableModel ) getModel ( ) )
                        .getData ( adapter.row - 1 );
                if ( actualData.getMsgNbr ( ) != previousData.getMsgNbr ( ) )
                {   
                    adapter.row--;
                    if(isHighlighted ( renderer , adapter ))
                    {
                        return false;
                    }
                    else
                    {
                        return true;
                    }                       
                }
                else
                {
                    adapter.row--;
                    if(isHighlighted ( renderer , adapter ))
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
            }
            return false;
        }
    };

    addHighlighter ( new ColorHighlighter ( predicate , COLOR1 , null ) );

Thank you all for your help !

Upvotes: 0

Views: 1116

Answers (2)

StanislavL
StanislavL

Reputation: 57421

int lastRow=Math.max(0, row-1);

Instead of saving last row index just use actual row value and subtract 1.

Upvotes: 2

Guillaume Polet
Guillaume Polet

Reputation: 47607

You also need to make the renderer opaque:

if (c instanceof JComponent)
    ((JComponent)c).setOpaque(true);

Upvotes: 2

Related Questions