Vaadin 21:在区域设置更改时更改网格中 LocalDateTimeRenderer 的日期格式

Vaadin 21: change date format at LocalDateTimeRenderer in Grid on locale change

情况与问题,短

Vaadin 21 中的 LocalDateTimeRenderer 在德语浏览器中显示德语日期,即使 Vaadin 会话中的区域设置更改为例如Locale.UK.

情况和问题,长/详细

在 Vaadin 21 Grid 我有一个 LocalDateTime 列。它是为实体类型 T:

创建的
private <T> Column<T> addLocalDateTimeColumn(Grid<T> grid, ValueProvider<T, LocalDateTime> getter) {
    LocalDateTimeRenderer<T> renderer = new LocalDateTimeRenderer(getter);
    Column<T> column = grid.addColumn(renderer).setAutoWidth(true);
    return column;
}

当我通过调用 UI.getCurrent().getSession().setLocale(locale); 更改会话中的 Locale 时,整个应用程序都被翻译成新语言,但 LocalDateTime 列的内容没有被翻译。

通过调用 grid.getDataProvider().refreshAll() 刷新整个 Grid (参见此处 Vaadin 21: re-translate column with ItemLabelGenerator on locale change )会导致上面代码示例中的 ValueProvider 再次被调用(我的一个很好的指标想想),但它没有用新选择的语言格式化 LocalDateTime(这是意外行为)。

因此,即使会话中的语言环境是英语/Locale.UKLocalDateTime 值的格式也是德语,如下所示:

像这样使用本地化的 DateTimeFormatter LocalDateTimeRenderer<T> renderer = new LocalDateTimeRenderer(getter, DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL, FormatStyle.SHORT)); 也无济于事:样式不同但月份仍然翻译成德语。

解决方法

使用自定义 TextRenderer 有效(= 列 LocalDateTime 内容使用会话的语言环境翻译):

private <T> Column<T> addLocalDateTimeColumn(Grid<T> grid, ValueProvider<T, LocalDateTime> getter) {
    Renderer<T> renderer = new TextRenderer<T>(new ItemLabelGenerator<T>() {

        @Override
        public String apply(T entity) {
            final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd. MMMM yyyy HH:mm", UI.getCurrent().getLocale());
            return getter.apply(entity).format(formatter);
        }
    });
    Column<T> column = grid.addColumn(renderer).setAutoWidth(true);
    return column;
}

问题

是否有一些技巧可以使用 Vaadins LocalDateTimeRenderer 获得相同的结果?

不,如果您在 Vaadin 21 或 Vaadin 22 中使用 LocalDateRendererLocalDateTimeRenderer,则无法动态更改列的区域设置。这是因为以下原因:

  1. 语言环境未明确保存在渲染器中。提供给渲染器构造函数(或默认值)的 Locale 用于生成一个 Formatter,它被保存到字段 private DateTimeFormatter formatter;
  2. formatter 没有任何 getter 或 setter。
  3. 即使 VaadinSession 的语言环境发生变化,formatter 的语言环境仍保持与创建时相同
  4. 列的 Renderer 创建后无法更改为其他内容。

可以做的是删除该列,然后使用具有请求区域设置的新LocalDate(Time)Renderer重新添加它。

我建议在 https://github.com/vaadin/flow-components/

中创建关于此的功能请求