Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Formatting an ObjectProperty<LocalDateTime> in a TableView column

In this example, I would like for a column in my TableView to format from LocalDateTime (which is in the source data model) to the format of "yyyy/MM/dd kk:mm" in a TableColumn. (Note: For rendering, not editing) Well, I will need to work with Local/ZonedDateTime types in a few data models when displaying in table views. What is the best way to do this? (I did not notice an example of this type of capability in the Oracle Table View tutorial).

Edit-add: Or, maybe keeping the values in the data models as String (formatted), and converting to LocalDateTime for when used in processing records would be best?

import java.time.LocalDateTime;

import javafx.application.Application;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.stage.Stage;

public class Main extends Application {
    @Override
    public void start(Stage stage) {

        final ObservableList<Foo> data = FXCollections.observableArrayList();
        LocalDateTime ldt = LocalDateTime.now();
        data.add(new Foo(ldt));
        data.add(new Foo(ldt.plusDays(1)));
        data.add(new Foo(ldt.plusDays(2)));

        TableView<Foo> table = new TableView<Foo>();
        table.setItems(data);

        TableColumn<Foo, LocalDateTime> ldtCol = new TableColumn<Foo, LocalDateTime>("LDT");
        // --- Set cell factory value ---

        table.getColumns().addAll(ldtCol);
        Scene scene = new Scene(table);
        stage.setScene(scene);
        stage.show();
    } 

    public static void main(String[] args) {
        launch(args);
    }

    class Foo {
        private final ObjectProperty<LocalDateTime> ldt = 
                new SimpleObjectProperty<LocalDateTime>();

        Foo(LocalDateTime ldt) {
            this.ldt.set(ldt);
        }

        public ObjectProperty<LocalDateTime> ldtProperty() { return ldt; }
        public LocalDateTime getLdt() { return ldt.get(); }
        public void setLdt(LocalDateTime value) { ldt.set(value); }

    }
}
like image 697
Mark Meyers Avatar asked Jun 27 '16 03:06

Mark Meyers


1 Answers

You can have the TableColumn as TableColumn<Foo, LocalDateTime>: use the LocalDateTime property as value and you can define the cellFactory for the column to display it:

TableColumn<Foo, LocalDateTime> ldtCol = new TableColumn<Foo, LocalDateTime>("LDT");
ldtCol.setCellValueFactory(cellData -> cellData.getValue().ldtProperty());
ldtCol.setCellFactory(col -> new TableCell<Foo, LocalDateTime>() {
    @Override
    protected void updateItem(LocalDateTime item, boolean empty) {

        super.updateItem(item, empty);
        if (empty)
            setText(null);
        else
            setText(String.format(item.format(formatter)));
    }
});

Alternatively, you can have a DateTimeFormatter to convert the LocalDateTime into a String, but in this case table sorting will not work (will use string ordering). Thanks @JFValdes to point that out.

In this case you can use the setCellValueFactory method of TableColumn to display it as a String on the TableView.

private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd hh:mm");

...    

TableColumn<Foo, String> ldtCol = new TableColumn<Foo, String>("LDT");
ldtCol.setCellValueFactory(foo -> new SimpleStringProperty(foo.getValue().getLdt().format(formatter)));
like image 88
DVarga Avatar answered Oct 09 '22 22:10

DVarga