Reputation: 31
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 :
Row 0 : var = 1 -> Background BLUE
Row 1 : var = 1 -> Background BLUE
Row 2 : var = 2 -> Background RED
Row 3 : var = 3 -> Background BLUE
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.
Row 0 : var = 1 -> Background BLUE
Row 1 : var = 1 -> Background BLUE
Row 2 : var = 2 -> Background RED
Row 3 : var = 2 -> Background BLUE
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
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
Reputation: 47607
You also need to make the renderer opaque:
if (c instanceof JComponent)
((JComponent)c).setOpaque(true);
Upvotes: 2