2017-10-13 53 views
1

我知道我必须使用grid.getDataProvider()得到ListDataProvider(假设我发送Listgrid.setItems())。在其他计算页脚总我做的:如何计算一个Vaadin 8网格页脚与过滤总和

Collection myItems = ((ListDataProvider)grid.getDataProvider()).getItems(); 
for(MyItem myItem : myItems) 
    total += myItem.getValue(); 
footer.getCell(footerCell).setText(format(total)); 

但是,如果我添加了一个注脚,因为它计算了我的网格中的所有项目失败。因此,举例来说,如果我补充:因为页脚是不过滤,但总满格总

((ListDataProvider)grid.getDataProvider()).addFilter(myFilter); 

顶部的代码失败。

话虽这么说someone suggested I use

grid.getDataCommunicator().fetchItemsWithRange(...); 

然而,这是一个受保护的方法。假设我创建了自己的子类,我甚至不知道该方法是如何工作的。

但即便如此,这似乎过于复杂,应该很简单,特别是如果有能力在网格中添加过滤。

因此,我的一个大问题是,如果我过滤网格,如何计算Vaadin 8网格中的页脚总数?

回答

2

要重新计算总数,您可以使用在过滤器更改时触发的DataProviderListener。在其实现中,您可以使用fetchDataProvider中的项目Query,因为获取方法也会考虑您定义的过滤器。

下面的例子主要基于Vaadin grid sampler,这个想法是显示每月报价及其总数的列表。该过滤器将让你看到某个月开始的数据(这是愚蠢的,但它可以让你开始):

import com.vaadin.data.provider.ListDataProvider; 
import com.vaadin.data.provider.Query; 
import com.vaadin.ui.ComboBox; 
import com.vaadin.ui.Grid; 
import com.vaadin.ui.VerticalLayout; 
import com.vaadin.ui.components.grid.FooterRow; 
import com.vaadin.ui.components.grid.HeaderRow; 
import com.vaadin.ui.themes.ValoTheme; 

import java.util.List; 
import java.util.Random; 
import java.util.stream.Collectors; 
import java.util.stream.IntStream; 

public class FilteredGrid extends VerticalLayout { 
    public FilteredGrid() { 
     // list data provider with some random data 
     Random random = new Random(); 
     List<Quote> quotes = IntStream.range(1, 11).mapToObj(month -> new Quote(month, random.nextInt(10))).collect(Collectors.toList()); 
     ListDataProvider<Quote> provider = new ListDataProvider<>(quotes); 

     // month number filter combo 
     ComboBox<Integer> monthFilterCombo = new ComboBox<>("Starting with", IntStream.range(1, 10).boxed().collect(Collectors.toList())); 
     monthFilterCombo.setEmptySelectionCaption("All"); 
     monthFilterCombo.addStyleName(ValoTheme.COMBOBOX_SMALL); 
     monthFilterCombo.addValueChangeListener(event -> { 
      if (event.getValue() == null) { 
       provider.clearFilters(); 
      } else { 
       provider.setFilter(quote -> quote.getMonth() > event.getValue()); 
      } 
     }); 

     // grid setup 
     Grid<Quote> grid = new Grid<>(Quote.class); 
     grid.setDataProvider(provider); 

     // header and footer 
     HeaderRow header = grid.appendHeaderRow(); 
     header.getCell("month").setComponent(monthFilterCombo); 
     FooterRow footer = grid.prependFooterRow(); 
     footer.getCell("month").setHtml("<b>Total:</b>"); 
     provider.addDataProviderListener(event -> footer.getCell("value").setHtml(calculateTotal(provider))); 

     // add grid to UI 
     setSizeFull(); 
     grid.setSizeFull(); 
     addComponent(grid); 

     // trigger initial calculation 
     provider.refreshAll(); 
    } 

    // calculate the total of the filtered data 
    private String calculateTotal(ListDataProvider<Quote> provider) { 
     return "<b>" + String.valueOf(provider.fetch(new Query<>()).mapToInt(Quote::getValue).sum()) + "</b>"; 
    } 

    // basic bean for easy binding 
    public class Quote { 
     private int month; 
     private int value; 

     public Quote(int month, int value) { 
      this.month = month; 
      this.value = value; 
     } 

     public int getMonth() { 
      return month; 
     } 

     public void setMonth(int month) { 
      this.month = month; 
     } 

     public int getValue() { 
      return value; 
     } 

     public void setValue(int value) { 
      this.value = value; 
     } 
    } 
} 

结果:

Vaadin filtered Grid

+0

谢谢。我缺少的关键部分是能够执行新的查询<>()。我不知道你可以这么做。我认为如果它不是必需的,那么它不会是一个参数,并且默认情况下会在API中为您创建类似于空白查询的东西。无论如何谢谢你,完美的工作! –