vaadin - 在 Vaadin 7.4 应用程序中使用一组新数据更新网格

标签 vaadin vaadin7 vaadin-grid

中新Vaadin 7.4 release ,新 Grid 小部件首次亮相是作为古老的替代品 Table .

显示 Grid 后,我稍后想用新数据替换整个数据集。我不想更新单个行,而是想简单地替换它们。

我碰巧正在使用 BeanItemContainer 使用 JavaBeans 样式的 getter 方法轻松地以只读方式显示某些对象。

最佳答案

我考虑了两种方法:

  • 替换 bean 项目的两步过程。
  • (1) 首先删除所有 BeanItem 带有 Container::removeAllItems 的对象方法。
  • (2) 然后添加替换BeanItem带有 BeanItemContainer::addAll 的对象方法。
  • 替换整个 BeanItemContainer .
  • 调用 Grid::setContainerDataSource 并传递 BeanItemContainer 的新实例用新鲜数据构建。

  • 下面是显示这两种方法的示例应用程序 (Vaadin 7.4.2)。出现一对相同的网格小部件。每个都有一个按钮,可以使用任一方法更新数据。

    screen shot of a pair of Grid instances

    结果

    第一种方法(删除项目和添加项目)有效。新数据立即出现。

    第二种方法(替换容器而不是元素)似乎应该有效,在 scant documentation 中没有任何相反的建议。 .但什么也没有发生。没有异常或错误发生,也没有新数据出现。我开了 Ticket # 17268关于这个问题的 Vaadin 跟踪。

    也许还有其他更好的方法。请张贴或评论任何替代方案。

    示例应用程序

    下面显示了三个类。您应该能够复制粘贴到新的 Vaadin 7.4.x 应用程序中。
  • 一个类是在每个新的 Vaadin 应用程序中创建的通常的“MyUI”。
  • 另一个是简单的 JavaBeans 样式类,“Astronomer”,为我们的 Grid 中的行提供数据。该 Astronomer 类包含一个方便的静态方法,用于生成实例列表。每个新天文学家都会获得随机数量的人气投票,以显示新的数据值。
  • 该示例的主要部分是在“AstronomersLayout”类中,它创建了一对带有指定按钮的网格。

  • 我使用 Java 8 Lambda 语法和新的 java.time 类。因此,您可能需要更改项目的设置以使用 Java 8。在 NetBeans 8 中,这意味着 Project > Properties > Sources > Source/Binary Format (popup menu) > 1.8 .

    我的用户界面

    让您的 Vaadin 应用程序运行起来。
    package com.example.vaadingridexample;
    
    import javax.servlet.annotation.WebServlet;
    
    import com.vaadin.annotations.Theme;
    import com.vaadin.annotations.VaadinServletConfiguration;
    import com.vaadin.annotations.Widgetset;
    import com.vaadin.server.VaadinRequest;
    import com.vaadin.server.VaadinServlet;
    import com.vaadin.ui.UI;
    
    /**
     * Example app in Vaadin 7.4.2 experimenting with two ways to replace data in a
     * displayed Grid.
     *
     * @author Basil Bourque
     */
    @Theme ( "mytheme" )
    @Widgetset ( "com.example.vaadingridexample.MyAppWidgetset" )
    public class MyUI extends UI
    {
    
        @Override
        protected void init ( VaadinRequest vaadinRequest )
        {
            this.setContent( new AstronomersLayout() );
        }
    
        @WebServlet ( urlPatterns = "/*" , name = "MyUIServlet" , asyncSupported = true )
        @VaadinServletConfiguration ( ui = MyUI.class , productionMode = false )
        public static class MyUIServlet extends VaadinServlet
        {
        }
    
    }
    

    天文学家布局.java

    示例的主要部分。
    package com.example.vaadingridexample;
    
    import com.vaadin.data.util.BeanItemContainer;
    import com.vaadin.shared.ui.grid.HeightMode;
    import com.vaadin.ui.Button;
    import com.vaadin.ui.Button.ClickEvent;
    import com.vaadin.ui.Grid;
    import com.vaadin.ui.VerticalLayout;
    import java.time.ZoneOffset;
    import java.time.ZonedDateTime;
    import java.time.format.DateTimeFormatter;
    import java.util.List;
    
    /**
     * Layout displays a pair of Grids, each with a Button to replace its contents
     * with fresh data in either of two ways: (a) Replace all the items within the
     * Container, or (b) Replace container itself.
     *
     * @author Basil Bourque
     */
    @SuppressWarnings ( "serial" )
    public class AstronomersLayout extends VerticalLayout
    {
    
        // -----|  Member vars  |--------------------------
        Grid grid_ReplaceItems;
        String gridCaption_ReplaceItems = "Astronomers - Replacing Items";
        Button button_ReplaceItems;
    
        Grid grid_ReplaceContainer;
        String gridCaption_ReplaceContainer = "Astronomers - Replacing Container";
        Button button_ReplaceContainer;
    
        // -----|  Constructor  |--------------------------
        public AstronomersLayout ()
        {
            this.prepareWidgets();
            this.composeLayout();
        }
    
        // -----|  Helper Methods  |--------------------------
        private void prepareWidgets ()
        {
            // Show updating a Grid by replacing the bean items within a container.
            // Grid
            List<Astronomer> listA = Astronomer.makeList();
            BeanItemContainer<Astronomer> containerA = new BeanItemContainer<>( Astronomer.class , listA );
            this.grid_ReplaceItems = new Grid( this.gridCaption_ReplaceItems , containerA );
            //this.grid_ReplaceItems.setColumnOrder( "votes" , "givenName" , "surName" , "birthYear" );
            this.grid_ReplaceItems.setColumnOrder( Astronomer.FIELD.VOTES.getName() , Astronomer.FIELD.GIVENNAME.getName() , Astronomer.FIELD.SURNAME.getName() , Astronomer.FIELD.BIRTHYEAR.getName() );  // Enum is a safer way of doing this: this.grid_ReplaceItems.setColumnOrder( "votes" , "givenName" , "surName" , "birthYear" );
            this.grid_ReplaceItems.setHeightMode( HeightMode.ROW ); // Show all rows of data for this grid.
            this.updateCaptionAndSize( this.grid_ReplaceItems , this.gridCaption_ReplaceItems );
            // Button
            this.button_ReplaceItems = new Button( "Replace Items" );
            this.button_ReplaceItems.addClickListener( ( ClickEvent event ) -> {
                @SuppressWarnings ( "unchecked" )
                BeanItemContainer<Astronomer> bic = ( BeanItemContainer<Astronomer> ) this.grid_ReplaceItems.getContainerDataSource(); // Access existing container. Cast as need be.
                bic.removeAllItems();  // Remove existing items.
                bic.addAll( Astronomer.makeList() ); // Add fresh bean items to existing container.
                this.updateCaptionAndSize( this.grid_ReplaceItems , this.gridCaption_ReplaceItems );
            } );
    
            // Show updating a Grid by replacing the container rather than its contents.
            // Grid
            List<Astronomer> listB = Astronomer.makeList();
            BeanItemContainer<Astronomer> containerB = new BeanItemContainer<>( Astronomer.class , listB );
            this.grid_ReplaceContainer = new Grid( this.gridCaption_ReplaceContainer , containerB );
            this.grid_ReplaceContainer.setColumnOrder( Astronomer.FIELD.VOTES.getName() , Astronomer.FIELD.GIVENNAME.getName() , Astronomer.FIELD.SURNAME.getName() , Astronomer.FIELD.BIRTHYEAR.getName() );
            this.grid_ReplaceContainer.setHeightMode( HeightMode.ROW ); // Show all rows of data for this grid.
            this.updateCaptionAndSize( this.grid_ReplaceContainer , this.gridCaption_ReplaceContainer );
            // Button
            this.button_ReplaceContainer = new Button( "Replace Container" );
            this.button_ReplaceContainer.addClickListener( ( ClickEvent event ) -> {
                @SuppressWarnings ( "unchecked" )
                BeanItemContainer<Astronomer> bic = new BeanItemContainer<>( Astronomer.class , listB ); // Create replacement container.
                this.grid_ReplaceContainer.setContainerDataSource( bic );
                this.updateCaptionAndSize( this.grid_ReplaceContainer , this.gridCaption_ReplaceContainer );
            } );
        }
    
        private void updateCaptionAndSize ( final Grid grid , final String caption )
        {
            // Caption
            grid.setCaption( caption + " ( updated " + this.now() + " )" );  // Update caption of Grid to indicate fresh data.
            // Show all rows.
            double h = grid.getContainerDataSource().size() > 0 ? grid.getContainerDataSource().size() : 3; // Cannot set height to zero rows. So if no data, set height to some arbitrary number of (empty) rows.
            grid.setHeightByRows( h );
        }
    
        private void composeLayout ()
        {
            // Initialize this layout.
            this.setMargin( true );
            this.setSpacing( true );
    
            // Content
            this.addComponent( this.button_ReplaceItems );
            this.addComponent( this.grid_ReplaceItems );
    
            this.addComponent( this.button_ReplaceContainer );
            this.addComponent( this.grid_ReplaceContainer );
        }
    
        // Helper method.
        private String now ()
        {
            // Get current time in UTC. Truncate fractional seconds. Append a 'Z' to indicate UTC time zone.
            return ZonedDateTime.now( ZoneOffset.UTC ).format( DateTimeFormatter.ISO_LOCAL_TIME ).substring( 0 , 8 ).concat( "Z" );
        }
    
    }
    

    天文学家.java

    数据,即 bean 项,存储在 BeanItemContainer 中以在 Grid 中显示。

    嵌套的 Enum 提供了一种更安全的方式来引用另一个类中的字段名称,AstronomersLayout调用 setColumnOrder .
    package com.example.vaadingridexample;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * Provides the beans to appear as rows in a BeanItemContainer backing a Grid.
     *
     * Note the static convenience method for generating a List of instances.
     *
     * @author Basil Bourque
     */
    public class Astronomer
    {
    
        public enum FIELD
        {
    
            SURNAME( "surname" ),
            GIVENNAME( "givenName" ),
            BIRTHYEAR( "birthYear" ),
            VOTES( "votes" );
    
            private String name;
    
            private FIELD ( String s )
            {
                this.name = s;
            }
    
            public String getName ()
            {
                return this.name;
            }
        }
    
        // Members
        private String surname;
        private String givenName;
        private Integer birthYear;
        private Integer votes;
    
        public Astronomer ( final String givenName , final String surName , final Integer birthYear )
        {
            this.surname = surName;
            this.givenName = givenName;
            this.birthYear = birthYear;
            this.votes = this.random();
        }
    
        public static List<Astronomer> makeList ()
        {
            List<Astronomer> list = new ArrayList<>( 7 );
    
            list.add( new Astronomer( "Hypatia" , "of Alexandria" , -370 ) );
            list.add( new Astronomer( "Nicolaus" , "Copernicus" , 1473 ) );
            list.add( new Astronomer( "Tycho" , "Brahe" , 1546 ) );
            list.add( new Astronomer( "Giordano" , "Bruno" , 1548 ) );
            list.add( new Astronomer( "Galileo" , "Galilei" , 1564 ) );
            list.add( new Astronomer( "Johannes" , "Kepler" , 1571 ) );
            list.add( new Astronomer( "Isaac" , "Newton" , 1643 ) );
            list.add( new Astronomer( "Caroline" , "Herschel" , 1750 ) );
    
            return list;
        }
    
        // ----|  Helper Methods  |----------------------------------
        private Integer random ()
        {
            return ( int ) ( java.lang.Math.random() * 100 );
        }
    
        // ----|  Bean Getters  |----------------------------------
        public String getSurname ()
        {
            return this.surname;
        }
    
        public String getGivenName ()
        {
            return this.givenName;
        }
    
        public Integer getBirthYear ()
        {
            return this.birthYear;
        }
    
        public Integer getVotes ()
        {
            return this.votes;
        }
    
        // ----|  Object Superclass  |----------------------------------
        @Override
        public String toString ()
        {
            return "Astronomer{ " + "surName=" + surname + " | givenName=" + givenName + " | birthYear=" + birthYear + " | votes=" + votes + " }";
        }
    
    }
    

    关于vaadin - 在 Vaadin 7.4 应用程序中使用一组新数据更新网格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29204674/

    相关文章:

    java - Vaadin 网格 : How to disable mouse event handler which runs inline editor?

    java - 默认情况下将我的 JavaBean 的所有属性添加为 Vaadin 8 网格中的列?

    javascript - polymer ,vaadin-combo-box;获取输入值

    Vaadin 通过链接加载另一个 View ?

    selenium - 并行运行 E2E 测试

    vaadin7 - VaadinService.getCurrent() 为空

    java - 如何去除 Vaadin 8 Grid 中的单元格边框?

    java - Spring security 阻止从后台线程导航到另一个 View

    java - 无法将组件添加到布局

    javascript - 更改 CKEditor 按钮颜色