Here's an example Nimbus JTable.
When a checkbox is selected, I want to color its entire row green.
The problem: the green skips every other row, only in the boolean column.
This problem only happens with the Nimbus LaF, which alternates white and gray rows by default. For boolean columns only, it's as if alternating color is being forced no matter what coloring you try to apply. Can this be overriden?
Code that produces the above tables (MCVE):
import java.awt.*;
import javax.swing.*;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;
import javax.swing.table.*;
public class AlternatingGreenTableTest extends JFrame {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (Exception e) {
try {
UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
} catch (Exception e1) {
e1.printStackTrace();
}
}
try {
AlternatingGreenTableTest frame = new AlternatingGreenTableTest();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public AlternatingGreenTableTest() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
String[] columnNames = {"First Name", "Vegetarian"};
Object[][] data = {
{"Kathy", new Boolean(false)},
{"John", new Boolean(false)},
{"Sue", new Boolean(false)},
{"Jane", new Boolean(false)},
{"Joe", new Boolean(false)},
{"Bob", new Boolean(false)}
};
TableModel model = new DefaultTableModel(data, columnNames) {
public Class getColumnClass(int c) {
/* Need this so that Boolean columns render as checkboxes */
return getValueAt(0, c).getClass();
}
};
JTable table = new JTable(model) {
public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
Component c = super.prepareRenderer(renderer, row, column);
if (!isRowSelected(row)) {
int modelRow = convertRowIndexToModel(row);
Boolean isExaminedChecked = (Boolean) getModel().getValueAt(modelRow, 1);
if (isExaminedChecked) {
/* 'Examined' is checked in the given row, so color the row green. */
c.setBackground(Color.GREEN);
} else {
/* 'Examined' is not checked in the given row, so color the row with one of the default alternating colors. */
Color defaultBackgroundColor = (Color) UIManager.get("Table:\"Table.cellRenderer\".background");
Color alternatingColor = (Color) UIManager.get("Table.alternateRowColor");
c.setBackground(row % 2 == 0 ? defaultBackgroundColor : alternatingColor);
}
}
return c;
}
};
/* Need this or Boolean column won't turn green at all */
((JComponent) table.getDefaultRenderer(Boolean.class)).setOpaque(true);
getContentPane().add(table);
pack();
}
}