【问题标题】:How to calculate the total in a Vaadin 8 grid footer with filtering如何通过过滤计算 Vaadin 8 网格页脚中的总数
【发布时间】:2018-03-25 03:15:15
【问题描述】:

我知道我必须使用grid.getDataProvider() 来获取ListDataProvider(假设我向grid.setItems() 发送了List)。在其他计算页脚总数我做:

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 网格中的页脚总数?

【问题讨论】:

    标签: java vaadin vaadin8 vaadin-grid


    【解决方案1】:

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

    下面的示例主要基于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;
            }
        }
    }
    

    结果:

    【讨论】:

    • 谢谢。我缺少的关键部分是执行 new Query() 的能力。我不知道你能做到这一点。我假设如果它不是必需的,那么它就不会是一个参数,并且默认情况下会在 API 中为您创建一个空查询之类的东西。无论如何,谢谢你,效果很好!
    猜你喜欢
    • 2019-04-30
    • 2017-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-11
    • 1970-01-01
    相关资源
    最近更新 更多