Basically the problem here is as follow, I have this TableCellRenderer:
public class CellRenderer_LocalDate extends DefaultTableCellRenderer implements TableCellRenderer {
private static final long serialVersionUID = -9184414041940041458L;
String displayFormat;
public CellRenderer_LocalDate(String dateFormat) {
this.displayFormat = dateFormat;
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
if (value instanceof LocalDate) {
LocalDate date = (LocalDate) value;
value = date.format(DateTimeFormatter.ofPattern(displayFormat));
}
return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
}
}
And this function to search a JTable:
/**
* Filters the table to show a specific text
*/
public void searchTable(JTextField searchTextField) {
// Get model & instantiate table sorter
DefaultTableModel tableToFilter = (DefaultTableModel) this.getModel();
TableRowSorter<DefaultTableModel> trSorter = new TableRowSorter<DefaultTableModel>(tableToFilter);
// Get text to search & Set row filter for this table
String search = searchTextField.getText();
// Filter table in correct format
trSorter.setRowFilter(RowFilter.regexFilter("(?i)" + search)); // Insensitive to upper case or lower case
this.setRowSorter(trSorter);
}
I have a column in the JTable that holds LocalDate in it. I made TableCellRenderer to display LocalDate column as dd.mm.yyyy. It works the way it should.
The problem is that when I use search function in format dd.mm.yyyy it does not show me any rows that match the way LocalDate is displayed in JTable.
An example: I have a column that holds LocalDate 2022-05-10. Due to the TableCellRenderer it is shown as 10.05.2022. Now if I use search and look for 10.05.2022 nothing will be shown as if nothing matches. But if I write in search field 2022-05-10 it will immediately show me the correct result. Please, what should I change in my functions to fix this bug?
Do not use CellRenderers for changing the text. CellRenderers should be used for things like colors, fonts, borders, and images.
A CellRenderer is just a visual painting of a cell’s value. JTable cannot look at pixels and know what text they contain.
To make JTable’s sorting and filtering work, you need to return a wrapper object whose
toString()method returns your formatted data. For example:You would place instances of the above class in your TableModel instead of plain LocalDate objects. For instance:
Because DisplayableDate implements Comparable, the RowSorter will know how to sort it. Because filters look at the toString value of each cell, table filtering will use the text that happens to be the text displayed.
Another benefit to doing it this way is accessibility—meaning, allowing disabled users to use the application. Sight impaired users rely on a computer’s screen reader, usually. Swing can tell a screen reader what text is in a component or a model value, but Swing cannot figure out what text is in a renderer, because, again, it’s just pixels. Using a wrapper object gives your application accessibility compliance with no additional effort needed.
One more advantage is clipboard compatibility. You can select rows of a JTable, press Ctrl-C (or Command-C), then paste them into a text file or spreadsheet. Again, Swing only knows how to copy string versions of model objects, so using a wrapper object lets you control what goes on the clipboard.