datagrid - 为 Vaadin 8 Grid 实现列渲染器

标签 datagrid vaadin renderer vaadin8

Vaadin Framework指南有一个page describing how to use Column RenderersVaadin Grid 。和this page describes implementing renderers ,但一切都太短暂了。

我想实现一个 InstantRenderer 来补充 Vaadin 8.1 中添加的部分 java.time 渲染器集。为 LocalDateLocalDateTime 添加了渲染器,但未为 InstantOffsetDateTimeZonedDateTime 添加了渲染器>。对于我的 Instant 渲染器,我目前只是应用当前默认时区 (ZoneId) 来获取 ZonedDateTime,我在其上调用 toString 方法。还可以做更多的事情,但这只是开始。

所以我的代码应该与提供的LocalDateTimeRenderer非常相似。我正在尝试遵循该代码作为指导。

在搜索 Vaadin 源代码并阅读文档时,似乎我需要三段源代码:

我已经完成了这个,并且全部编译通过。但我的表格无法渲染,我得到的只是页面上的一个白色空框。控制台或日志上没有出现错误。如果我删除对 InstantRenderer 的使用,并回退到让我的 Instant 对象通过它们自己的 toString 方法的默认渲染,所有一切顺利,表格按预期显示。所以我知道我的自定义渲染器有问题。

当谈到“服务器端”与“客户端”Vaadin 时,我是一个新手。

➠ 我需要执行某种打包吗?目前,我的 Vaadin 项目中有三个类以及 MyUI 源文件。

➠我还漏掉了其他部分吗?

我通过调用无参数构造函数来实例化渲染器:

this.entriesGrid
    .addColumn( Entry::getStart )
    .setCaption( "Start" )
    .setRenderer( new InstantRenderer(  ) )
;

这是我上面列出的三个文件,几乎完全取自 Vaadin 源代码。

即时渲染器

/*
 * By Basil Bourque. Taken almost entirely from source code published by Vaadin Ltd.
 *
 * --------
 *
 * Copyright 2000-2016 Vaadin Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package com.basil.timepiece;

import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;

import java.util.Locale;

import elemental.json.JsonValue;

/**
 * A renderer for presenting {@code Instant} objects.
 *
 * @author Vaadin Ltd
 * @since 8.1
 */
public class InstantRenderer
        extends com.vaadin.ui.renderers.AbstractRenderer< Object, Instant >
{
    private DateTimeFormatter formatter;
    private boolean getLocaleFromGrid;

    private ZoneId zoneId = ZoneId.systemDefault(); // Basil Bourque.

    /**
     * Creates a new InstantRenderer.
     * <p>
     * The renderer is configured to render with the grid's locale it is
     * attached to, with the format style being {@code FormatStyle.LONG} for the
     * date and {@code FormatStyle.SHORT} for time, with an empty string as its
     * null representation.
     *
     * @see <a href=
     * "https://docs.oracle.com/javase/8/docs/api/java/time/format/FormatStyle.html#LONG">
     * FormatStyle.LONG</a>
     * @see <a href=
     * "https://docs.oracle.com/javase/8/docs/api/java/time/format/FormatStyle.html#SHORT">
     * FormatStyle.SHORT</a>
     */
    public InstantRenderer ()
    {
        this( DateTimeFormatter.ofLocalizedDateTime( FormatStyle.LONG , FormatStyle.SHORT ) , "" );
        getLocaleFromGrid = true;
    }

    /**
     * Creates a new InstantRenderer.
     * <p>
     * The renderer is configured to render with the given formatter, with the
     * empty string as its null representation.
     *
     * @param formatter the formatter to use, not {@code null}
     * @throws IllegalArgumentException if formatter is null
     */
    public InstantRenderer ( DateTimeFormatter formatter )
    {
        this( formatter , "" );
    }

    /**
     * Creates a new InstantRenderer.
     * <p>
     * The renderer is configured to render with the given formatter.
     *
     * @param formatter          the formatter to use, not {@code null}
     * @param nullRepresentation the textual representation of the {@code null} value
     * @throws IllegalArgumentException if formatter is null
     */
    public InstantRenderer ( DateTimeFormatter formatter , String nullRepresentation )
    {
        super( Instant.class , nullRepresentation );

        if ( formatter == null )
        {
            throw new IllegalArgumentException( "formatter may not be null" );
        }

        this.formatter = formatter;
    }

    /**
     * Creates a new InstantRenderer.
     * <p>
     * The renderer is configured to render with the given string format, as
     * displayed in the grid's locale it is attached to, with an empty string as
     * its null representation.
     *
     * @param formatPattern the format pattern to format the date with, not {@code null}
     * @throws IllegalArgumentException if format pattern is null
     * @see <a href=
     * "https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#patterns">
     * Format Pattern Syntax</a>
     */
    public InstantRenderer ( String formatPattern )
    {
        this( formatPattern , Locale.getDefault() );
        getLocaleFromGrid = true;
    }

    /**
     * Creates a new InstantRenderer.
     * <p>
     * The renderer is configured to render with the given string format, as
     * displayed in the given locale, with an empty string as its null
     * representation.
     *
     * @param formatPattern the format pattern to format the date with, not {@code null}
     * @param locale        the locale to use, not {@code null}
     * @throws IllegalArgumentException if format pattern is null
     * @throws IllegalArgumentException if locale is null
     * @see <a href=
     * "https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#patterns">
     * Format Pattern Syntax</a>
     */
    public InstantRenderer ( String formatPattern , Locale locale )
    {
        this( formatPattern , locale , "" );
    }

    /**
     * Creates a new InstantRenderer.
     * <p>
     * The renderer is configured to render with the given string format, as
     * displayed in the given locale.
     *
     * @param formatPattern      the format pattern to format the date with, not {@code null}
     * @param locale             the locale to use, not {@code null}
     * @param nullRepresentation the textual representation of the {@code null} value
     * @throws IllegalArgumentException if format pattern is null
     * @throws IllegalArgumentException if locale is null
     * @see <a href=
     * "https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#patterns">
     * Format Pattern Syntax</a>
     */
    public InstantRenderer ( String formatPattern , Locale locale , String nullRepresentation )
    {
        super( Instant.class , nullRepresentation );

        if ( formatPattern == null )
        {
            throw new IllegalArgumentException( "format pattern may not be null" );
        }

        if ( locale == null )
        {
            throw new IllegalArgumentException( "locale may not be null" );
        }

        formatter = DateTimeFormatter.ofPattern( formatPattern , locale );
    }

    @Override
    public JsonValue encode ( Instant value )
    {
        String dateString;
        if ( value == null )
        {
            dateString = this.getNullRepresentation();
        } else if ( this.getLocaleFromGrid )
        {
            if ( null == this.getParentGrid() )
            {
                throw new IllegalStateException(
                        "Could not find a locale to format with: "
                                + "this renderer should either be attached to a grid "
                                + "or constructed with locale information" );
            }
            ZonedDateTime zdt = value.atZone( this.zoneId );  // Basil Bourque.
            Locale locale = this.getParentGrid().getLocale();
            dateString = zdt.format( formatter.withLocale( locale ) );
        } else
        {
            ZonedDateTime zdt = value.atZone( this.zoneId );  // Basil Bourque.
            dateString = zdt.format( formatter );
        }
        return encode( dateString , String.class );
    }

    @Override
    protected InstantRendererState getState ()
    {
        InstantRendererState s = ( InstantRendererState ) super.getState();
        return s;
    }

    @Override
    protected InstantRendererState getState ( boolean markAsDirty )
    {
        InstantRendererState s = ( InstantRendererState ) super.getState( markAsDirty );
        return s;
    }
}

InstantRendererConnector

/*
 * By Basil Bourque. Taken almost entirely from source code published by Vaadin Ltd.
 *
 * --------
 *
 * Copyright 2000-2016 Vaadin Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.basil.timepiece;

import com.vaadin.shared.ui.Connect;

/**
 * A connector for InstantRenderer.
 * <p>
 * The server-side Renderer operates on {@code Instant}s, but the data is
 * serialized as a string, and displayed as-is on the client side. This is to be
 * able to support the server's locale.
 *
 * @author Vaadin Ltd
 * @since 8.1
 */
@Connect( InstantRenderer.class )
public class InstantRendererConnector extends com.vaadin.client.connectors.grid.TextRendererConnector
{

    @Override
    public InstantRendererState getState ()
    {
        return ( InstantRendererState ) super.getState();
    }
}

InstantRendererState

/*
 * By Basil Bourque. Taken almost entirely from source code published by Vaadin Ltd.
 *
 * --------
 *
 * Copyright 2000-2016 Vaadin Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.basil.timepiece;

/**
 * Shared state of InstantRenderer.
 *
 * @author Vaadin Ltd
 * @since 8.1
 */
public class InstantRendererState extends com.vaadin.shared.ui.grid.renderers.TextRendererState
{
    // This code intentionally left blank.
}

BitBucket 上的来源

我已经发布了我的complete Maven-driven project on BitBucketInstantOffsetDateTimeZonedDateTime 列渲染器的所有必需文件。

功能请求

我发布了Issue # 10208 Implement column renderers for Vaadin Grid for other java.time types (Instant, OffsetDateTime, ZonedDateTime) to complement the LocalDate & LocalDateTime renderers in Vaadin 8.1.在 Vaadin 框架 GitHub 页面上。

最佳答案

需要特殊包装

是的,需要特殊包装。你不能简单地扔掉 Vaadin Grid column renderer implementation类到常规 Vaadin 应用程序中。

列渲染器实现所需的三个类中的两个涉及 client-side development ,而不是通常的 server-side development我们通常在 Vaadin 应用程序中进行工作。

幸运的是,这比听起来更容易。为了做一个简单的列渲染器,Vaadin 幸运地提供了一些父类(super class)来完成大部分繁重的工作。所以我们不需要了解 GWT 的所有血淋淋的细节。和 JavaScript瓦丁的幕后魔法正在发生。

成功之路包括:

vaadin-archetype-widget

使用 multi-module 启动一个新项目Maven archetype由 Vaadin 团队提供:vaadin-archetype-widgetthis list .

screen shot of IntelliJ > New Project > Create from archetype dialog box

插件模块

一旦您在 IDE 中根据该原型(prototype)创建了一个项目, ,添加三列渲染器类,如 Instant 的屏幕截图所示。渲染器。

  • Renderer 类位于“addon”模块的主包中。
  • RendererConnectorRendererState 类文件位于“addon”模块的嵌套 client 包中。

当然,在实际工作中,您会删除原型(prototype)创建的示例 MyComponent... 文件。

演示模块

构建完成后,您可以通过导入“addon”模块的包在“演示”模块的 Vaadin 应用程序中尝试列渲染器。在这种情况下:

import org.basilbourque.timecolrenderers.InstantRenderer;

GitHub 源

我成功实现的 Instant 列渲染器完全取自 Vaadin 8.1.3 源代码提供的三个 LocalDateTimeRenderer 相关类。您可以通过在 GitHub find file feature 中键入 LocalDateTimeRenderer 来查找这些类的当前版本。 .

enter image description here

screen shot of 'Project' pane in IntelliJ showing the position of three Java source files within the package hierarchy

关于datagrid - 为 Vaadin 8 Grid 实现列渲染器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45944529/

相关文章:

java - JTextArea 作为单元格渲染器似乎不适用于换行样式字

wpf - WPF DataGrid列交替着色

java - 如何配置 intellij vaadin 导入设置?

vb.net - Silverlight-DataGrid 控件-选择更改事件干扰排序

java - 瓦丁 : Filtering output on the table

java - Vaadin 推送功能

JList 中的 Java 格式化字符串

unity-game-engine - Unity Resources.Load<Sprite> 与作为 Sprite

wpf - DataGrid 的列宽 (width = "*") 不是 "refreshed"

.net - wpf 数据网格角度标题样式