I've a JTable
with a custom cell renderer
to highlight the cell if there is a new chapter online.
DefaultTableCellRenderer :
static class CustomRenderer extends DefaultTableCellRenderer {
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
Component cellComponent = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
double valueAt = (double) table.getValueAt(row, column);
double compareValue = (double) table.getValueAt(row, column - 1);
if (compareValue < valueAt) {
cellComponent.setBackground(Color.green);
} else {
Component tableCellRendererComponent = super.getTableCellRendererComponent(table, compareValue, isSelected, hasFocus, row, column - 1);
// Component tableCellRendererComponent = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column - 1);
// Component tableCellRendererComponent = super.getTableCellRendererComponent(table, valueAt, isSelected, hasFocus, row, column - 1);
Color background = tableCellRendererComponent.getBackground();
cellComponent.setBackground(background);
}
return cellComponent;
}
}
Table Model:
private String[] columnsGetNewest = {"Current Chapter", "Chapter Online"};
private DefaultTableModel dataModelGetNewest = new DefaultTableModel(columnsGetNewest, 0);
It's applied using:
tableGetNewest.setModel(dataModelGetNewest);
TableColumn column = tableGetNewest.getColumnModel().getColumn(1);
column.setCellRenderer(new CustomRenderer());
Desired Result:
But for some reason it doesn't work as intended:
The code seems to work as it goes into the else branch.
If i comment out //cellComponent.setBackground(Color.green);
the result looks like:
What's the problem with my code? How can i get the desired result?
If I understood correctly you are trying to turn Green
all cells in right column that have higher value than the cells in the left column. Correct if I am wrong.
The problem is on your TableCellRenderer
. In the following part:
if (compareValue < valueAt) {
cellComponent.setBackground(Color.green);
} else {
Component tableCellRendererComponent = super.getTableCellRendererComponent(table, compareValue, isSelected, hasFocus, row, column - 1);
// Component tableCellRendererComponent = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column - 1);
// Component tableCellRendererComponent = super.getTableCellRendererComponent(table, valueAt, isSelected, hasFocus, row, column - 1);
Color background = tableCellRendererComponent.getBackground();
cellComponent.setBackground(background);
}
I think the best way to explain you what you did wrong is with an example. Let's say the right value is higher than the left value in left column, so your if
takes place and the background of the renderer
turns green
. Now, let's render row 2. The right value is smaller than the left, so the if
does not take place. Guess what? You did it green in previous row render, so it remains green
. That's why they are staying all green. If you turn it once and you do not restore it, it will stay for the rest of them.
Now, in your attemt to restore the background you super.getTableCellRendererComponent(table, valueAt, isSelected, hasFocus, row, column - 1);
. This is wrong since this method is not a simple getter. It also makes changes to the table (renderers). Calling this method for another row/column values will not work.
In order to make this work, you will have to restore it according to its default value coming from DefaultTableCellRenderer
. A full example:
public class Example extends JFrame {
private static final long serialVersionUID = 811854316682851407L;
private static final String[] COLUMNS = { "Current Chapter", "Chapter Online" };
public Example() {
super("test");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new BorderLayout());
JTable table = new JTable(data(), COLUMNS);
table.getColumnModel().getColumn(1).setCellRenderer(new DefaultTableCellRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row,
int column) {
Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if (c instanceof JLabel) {
JLabel renderer = (JLabel) c;
int valueAt = (int) table.getValueAt(row, column);
int compareValue = (int) table.getValueAt(row, column - 1);
if (compareValue < valueAt) {
renderer.setBackground(Color.GREEN);
} else {
if (isSelected)
renderer.setBackground(table.getSelectionBackground());
else {
renderer.setBackground(table.getBackground());
}
}
}
return c;
}
});
JScrollPane sp = new JScrollPane(table);
add(sp);
pack();
setLocationRelativeTo(null);
}
private Object[][] data() {
Object[][] data = { { 113, 444 }, { 233, 555 }, { 110, 92 }, { 55, 66 }, { 123, 603 }, { 412, 120 }, };
return data;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new Example().setVisible(true));
}
}
Preview: