JTable row hightlighter based on value from TableCell
how to set Alignment for TableCell into prepareRenderer,
This should NOT be done in the prepareRenderer code. This property should be set in the renderer for the class or for the column because it only applies to a specific class or renderer. Instead use:
table.setPreferredScrollableViewportSize(table.getPreferredSize());
DefaultTableCellRenderer stringRenderer = (DefaultTableCellRenderer)table.getDefaultRenderer(String.class);
stringRenderer.setHorizontalAlignment( SwingConstants.CENTER );
For the highlighting code I used code that assumes that the dealld
value is unique for a given set of transactions:
private Map<Object, Color> rowColor = new HashMap<Object, Color>();
private Color nextColor = Color.ORANGE;
@Override
public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
Component c = super.prepareRenderer(renderer, row, column);
JComponent jc = (JComponent) c;
if (isRowSelected(row)) return c;
Object value = table.getValueAt(row, 7);
Color background = rowColor.get(value);
if (background != null)
{
c.setBackground( background );
}
else
{
rowColor.put(value, nextColor);
c.setBackground( nextColor );
nextColor = (nextColor == Color.ORANGE) ? Color.YELLOW : Color.ORANGE;
}
return c;
}
Note: It won't work if sorting is required.
Here is another approach that should work even if sorting is required (but I didn't test it with sorting);
@Override
public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
Component c = super.prepareRenderer(renderer, row, column);
JComponent jc = (JComponent) c;
if (!isRowSelected(row))
{
c.setBackground(getRowBackground(row));
}
return c;
}
private Color getRowBackground(int row)
{
boolean isDark = true;
Object previous = getValueAt(0, 7);
for (int i = 1; i <= row; i++)
{
Object current = getValueAt(i, 7);
if (! current.equals(previous))
{
isDark = !isDark;
previous = current;
}
}
return isDark ? Color.ORANGE : Color.YELLOW;
}
it's Sunday, wheather detoriating, so couldn't resist to show the SwingX version. It's the same logic as @camickr 2nd, thanks :-)
Advantages:
- code can focus on logic as the value retrieving handles sorting/filtering/column moves automagically
- knows about default ui alternate striping colors (and updates on switching the LAF)
- Highlighter support is built-in, no need to subclass the table nor care about renderer misbehaviour
- easy to add additional highlighters (yelling sell, sell, sell :-)
The code snipped:
JXTable table = new JXTable(data, columnNames);
HighlightPredicate predicate = new HighlightPredicate() {
@Override
public boolean isHighlighted(Component renderer,
ComponentAdapter adapter) {
if (adapter.row == 0) return false;
return isOddValue(adapter);
}
private boolean isOddValue(ComponentAdapter adapter) {
Object previous = adapter.getFilteredValueAt(0, 7);
boolean odd = false;
for (int i = 1; i <= adapter.row; i++) {
Object current = adapter.getFilteredValueAt(i, 7);
if (!previous.equals(current)) {
odd = !odd;
}
previous = current;
}
return odd;
}
};
table.addHighlighter(new UIColorHighlighter(predicate));