如何指定如何将对象转换为字符串以在 JavaFX TableView 中显示它?

How do I specify how an object is converted to string to display it in a JavaFX TableView?

我有一个 TableView,其中包含几个使用 FXML 创建的列:

<TableView fx:id="logTable" BorderPane.alignment="CENTER">
    <columns>
        <TableColumn fx:id="timestampColumn" editable="false" text="Timestamp">
            <cellValueFactory>
                <PropertyValueFactory property="timestamp"/>
            </cellValueFactory>
        </TableColumn>
        <TableColumn fx:id="actionColumn" editable="false" text="Action">
            <cellValueFactory>
                <PropertyValueFactory property="action"/>
            </cellValueFactory>
        </TableColumn>
    </columns>
</TableView>

然后我有一个这样定义的对象:

private ObservableList<LogEntry> log = FXCollections.observableArrayList();

设置为 TableView 的模型:

logTable.setItems(log);

日志条目如下所示:

import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import org.joda.time.DateTime;

public class LogEntry {
    private SimpleObjectProperty<DateTime> timestamp = new SimpleObjectProperty<>();
    private SimpleStringProperty action = new SimpleStringProperty();

    public LogEntry(String format, Object... args) {
        this.timestamp.setValue(new DateTime());
        String s = String.format(format, args);
        System.out.println(s);
        this.action.setValue(s);
    }

    public DateTime getTimestamp() {
        return timestamp.getValue();
    }

    public String getAction() {
        return action.getValue();
    }
}

我的问题是,如何指定如何将 Jodatime DateTimes 转换为字符串进行显示?我想使用当前语言环境转换它们(但我想对该列进行排序仍然有效)。

我没有使用过 Joda Time,但使用过 LocalDateTime。

这是一个可能如何工作的例子。

首先您需要公开属性::

public class LogEntry {
    private SimpleObjectProperty<LocalDateTime> timestamp = new SimpleObjectProperty<>();
    private SimpleStringProperty action = new SimpleStringProperty();
    public final SimpleObjectProperty<LocalDateTime> timestampProperty() {
        return this.timestamp;
    }

    public final java.time.LocalDateTime getTimestamp() {
        return this.timestampProperty().get();
    }

    public final void setTimestamp(final java.time.LocalDateTime timestamp) {
        this.timestampProperty().set(timestamp);
    }

    public final SimpleStringProperty actionProperty() {
        return this.action;
    }

    public final java.lang.String getAction() {
        return this.actionProperty().get();
    }

    public final void setAction(final java.lang.String action) {
        this.actionProperty().set(action);
    }
}

然后设置单元格工厂和单元格值工厂:

dateTimeColumn.setCellFactory(tc -> new LocalDateTimeTableCell<LogEntry>(true));
dateTimeColumn.setCellValueFactory(data -> data.getValue().timestampProperty());

像这样创建一个 Table 单元格:

public class LocalDateTimeTableCell<S> extends TableCell<S, LocalDateTime> {
    private final DateTimeFormatter myDateFormatter = DateTimeFormatter.ofPattern("MM/dd/yyyy");
    private final DateTimeFormatter myDateTimeFormatter = DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm:ss a");
    private final boolean showTime;

    public LocalDateTimeTableCell(boolean showTime){
        this.showTime = showTime;
    }
    @Override
    protected void updateItem(LocalDateTime item, boolean empty) {
        super.updateItem(item, empty);
        if (item == null || empty) {
            setText(null);
            setStyle("");
        } else {
            // Format date.
            if(showTime) {
                setText(myDateTimeFormatter.format(item));
            }else {
                setText(myDateFormatter.format(item));
            }
        }
    }
}

我知道这不是你对 Joda 时间的要求 - 但应该给你方向。

using cell-factory to update the cell

private TableColumn<Customer, LocalDateTime> Col_date;
    Col_date.setCellFactory((TableColumn<LogEntry, LocalDateTime> param) -> {
        TableCell<LogEntry, LocalDateTime> cell = new TableCell<LogEntry, LocalDateTime>() {
            @Override
            public void updateItem(LocalDateTime item, boolean empty) {
                if (item != null) {
                    setText(getDateTimeFormat(item,"yyyy/MM/dd HH:mm"));

                } else {
                    setText(null);
                }
            }
        };
        return cell;
    });


public static String getDateTimeFormat(LocalDateTime dateTime,String format) throws DateTimeParseException {
    return dateTime.format(DateTimeFormatter.ofPattern(format));
}