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

时间:2015-03-23 06:53:34

标签: vaadin vaadin7 vaadin-grid

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

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

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

2 个答案:

答案 0 :(得分:5)

我考虑了两种方法:

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

screen shot of a pair of Grid instances

结果

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

第二种方法(替换容器而非项目)似乎应该有效,scant documentation中没有任何相反的建议。但没有任何反应。没有出现异常或错误,但没有出现新数据。我为此问题在Vaadin trac上打开了Ticket # 17268

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

示例App

下面显示了三个班级。您应该能够复制粘贴到新的Vaadin 7.4.x应用程序中。

  • 一个类是在每个新的Vaadin应用程序中创建的通常的“MyUI”。
  • 另一个是简单的JavaBeans风格的类,“天文学家”,为我们网格中的行提供数据。该Astronomer类包含一个方便的静态方法,用于生成实例列表。每个新的天文学家获得随机数量的人气投票,以显示新的数据值。
  • 该示例的内容部分位于“AstronomersLayout”类中,该类使用指定的按钮创建一对网格。

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

MyUI.java

让你的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
    {
    }

}

AstronomersLayout.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" );
    }

}

Astronomer.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 + " }";
    }

}

答案 1 :(得分:1)

您只需使用.getSelectedRow()通过clickListener获取已从按钮中删除的记录。 在此之后,您可以使用.removeItem()从网格中删除商品。

IE:

Grid yourGrid = new Grid();
yourGrid.setContainerDataSource(yourData);

Button removeItem = new Button("Remove item");

removeItem.addClickListener(l -> {
        Item selectedItem = (Item) yourGrid.getSelectedRow();
        yourGrid.getContainerDataSource().removeItem(selectedItem);
});

再见!