如何指定如何将对象转换为字符串以在 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));
}
我有一个 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));
}