1

Is there a way to have a column in the TableView show a proper date instead of:

java.util.GregorianCalendar[time=?areFieldsSet=false...

I want to know because it's irritating having it displayed like that on the Date column I have and having to switch between Date and GregorianCalendar get's messy and annoying.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
Kyu Vulpes
  • 79
  • 11
  • 2
    Use a cell factory.... – James_D Apr 20 '18 at 17:08
  • @James_D I've seen that before, however, whenever I insert it, IntelliJ keeps doing this: new Callback, ObservableValue>() and changing Date to Calendar won't let it compile. – Kyu Vulpes Apr 20 '18 at 17:13
  • 2
    That's a cell **value** factory, not a cell factory. – James_D Apr 20 '18 at 17:15
  • [This popular tutorial](http://code.makery.ch/blog/javafx-8-tableview-cell-renderer/) summarizes the difference between cell factories and cell value factories nicely. – James_D Apr 20 '18 at 17:32

1 Answers1

3

First, I would strongly recommend using the java.time API, instead of legacy classes such as java.util.Calendar and java.util.Date, etc.

In any case, you can change how data in cells in a given column are displayed by using a cell factory on the column. In the case where your cell value factory is generating Calendar instances, you presumably have

TableColumn<MyTableType, Calendar> dateColumn ;
// ...
dateColumn.setCellValueFactory(...);

You can additionally do

DateFormat dateFormat = DateFormat.getDateInstance();
dateColumn.setCellFactory(col -> new TableCell<MyTableType, Calendar>() {
    @Override
    protected void updateItem(Calendar date, boolean empty) {
        super.updateItem(date, empty);
        if (empty) {
            setText(null);
        } else {
            setText(dateFormat.format(date.getTime()));
        }
    }
});

If you use the aforementioned java.time API, you represent a date with LocalDate and use a DateTimeFormatter to do the formatting:

TableColumn<MyTableType, LocalDate> dateColumn ;
// ...
dateColumn.setCellValueFactory(...);
DateTimeFormatter dateFormat = DateTimeFormatter.ISO_LOCAL_DATE;
dateColumn.setCellFactory(col -> new TableCell<MyTableType, LocalDate>() {
    @Override
    protected void updateItem(LocalDate date, boolean empty) {
        super.updateItem(date, empty);
        if (empty) {
            setText(null);
        } else {
            setText(dateFormat.format(date));
        }
    }
});
James_D
  • 201,275
  • 16
  • 291
  • 322
  • Thank you. This type of explanation is what I was expecting since I have no idea what I'm doing. – Kyu Vulpes Apr 20 '18 at 17:27
  • Using `java.time` is certainly recommended, thank you. In the last snippet you can just use `date.toString()` since this produces the same ISO format as `ISO_LOCAL_DATE`. – Ole V.V. Apr 21 '18 at 05:28