I'm trying to write a custom renderer to change Text color in my JTable based on the values inside.
This is the code I have so far. I tried to simplify it as much as possible without actually changing the code so much:
import javax.swing.*;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import java.awt.*;
public class Main {
public static String[][] resultsArray;
public static JTable results;
public static JScrollPane resultScrollPane;
public static void main(String[] args) {
resultsArray = new String[][]{{"123456", "192.168.4.16", "3.4/01.73.10", "1x6216", "109986 MB", "Fail", "2xSSD480", "6xHDD2GB", "Fail", "Fail"}};
resultScrollPane = new JScrollPane();
JFrame f = new JFrame("Table with colors");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLayout(new BorderLayout());
f.add(resultScrollPane,BorderLayout.CENTER);
f.setSize(new Dimension(60,255));
setTableResults(resultsArray);
f.setVisible(true);
}
public static void setTableResults(String[][] result) {
Object[] columnNames = {
"Serial Number",
"IP Address",
"BIOS/IPMI-Firmware",
"CPUs",
"Memory",
"DCMS",
"SSDs",
"HDDs",
"Network AOC",
"AOC"
};
TableModel model = new DefaultTableModel(result, columnNames);
results = new JTable(model);
results.setDefaultRenderer(String.class, 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);
String data = (String) value;
switch (column) {
case 0, 1 -> c.setForeground(Color.BLACK);
case 2 -> c.setForeground((data.contains("3.4") && data.contains("01.73.10")) ? Color.BLACK : Color.RED);
case 3 -> c.setForeground((data.split("x")[0].equalsIgnoreCase("2")) ? Color.BLACK : Color.RED);
case 4 -> c.setForeground((Integer.parseInt(data.split(" ")[0]) == 200000) ? Color.BLACK : Color.RED);
case 5 -> c.setForeground((data.equalsIgnoreCase("ok")) ? Color.BLACK : Color.RED);
case 6 -> c.setForeground((Integer.parseInt(data.split("x")[0]) == 2) ? Color.BLACK : Color.RED);
case 7 -> c.setForeground((Integer.parseInt(data.split("x")[0]) == 6) ? Color.BLACK : Color.RED);
}
return c;
}
});
resultScrollPane.setViewportView(results);
results.repaint();
}
}
Problem with this is, the code doesn't actually work. All cells have the standard Black font color. I tried adding .repaint()
to make sure the JTable would be updated before displaying but that didn't change anything.
Does anyone know what my problem is here?
By default, the class associated with columns is Object
, as specified in the documentation for getColumnClass()
:
Returns Object.class regardless of columnIndex.
So you can change your code like this to make it work:
results.setDefaultRenderer(Object.class, new DefaultTableCellRenderer() {