使用Vaadin 7将数学运算的结果实时设置为Vaadin Grid(手动插入)

时间:2017-09-19 22:20:58

标签: vaadin

我的主要问题是,我想从键盘将数据插入我的网格。一些数据从数据库加载,用户可以更改(也可以更改加载的数据)或将新数据插入网格(手动)。然后我希望看到最后一行中的列的结果(检查我的图片中的结果) - 结果表示行中的数字,第一列中的数据是 - sum,average,min,max ......

enter image description here

所以,当我点击第三行,进入栏目,例如人物3,当我将值从5更改为6并且在此时间时,总和将为16,最大值为6,最小1和平均值为3.2

我的网格代码是:

%

我尝试将addValueChangeListener添加到网格(容器)

Grid grid = new Grid();

IndexedContainer container = new IndexedContainer();
grid.setContainerDataSource(container);

container.addContainerProperty("September", String.class, null);
container.addContainerProperty("Person1", String.class, null);
container.addContainerProperty("Person2", String.class, null);
container.addContainerProperty("Person3", String.class, null);
container.addContainerProperty("Person4", String.class, null);
container.addContainerProperty("Person5", String.class, null);
container.addContainerProperty("Person6", String.class, null);
container.addContainerProperty("Person7", String.class, null);
container.addContainerProperty("Person8", String.class, null);

for(int i = 0; i < 10; i++)
     container.addItem(i);

Item item = container.getItem(1);

item.getItemProperty("September").setValue("1.9.2017 Piatok");

item = container.getItem(2);
item.getItemProperty("September").setValue("2.9.2017 Sobota");

....

但我收到错误消息:

container.addValueChangeListener(e -> {

       int sum = 0;
       for(int i = 0; i < 5; i++)
       {
         Item item = container.getItem(i);
         sum += (Integer) item.getItemProperty("Person3").getValue();
       }

         item = container.getItem(6);
         item.getItemProperty("Person3").setValue(sum);

     });

问题是当我尝试更换2个或更多个单元格时......

sep 15, 2017 4:16:21 PM com.vaadin.server.DefaultErrorHandler doDefault
SEVERE: 
com.vaadin.data.Buffered$SourceException
    at com.vaadin.ui.AbstractField.setValue(AbstractField.java:546)
    at com.vaadin.ui.AbstractField.setValue(AbstractField.java:468)
    at com.vaadin.ui.AbstractTextField.changeVariables(AbstractTextField.java:205)
    at com.vaadin.server.communication.ServerRpcHandler.changeVariables(ServerRpcHandler.java:616)
    at com.vaadin.server.communication.ServerRpcHandler.handleInvocation(ServerRpcHandler.java:463)
    at com.vaadin.server.communication.ServerRpcHandler.handleInvocations(ServerRpcHandler.java:406)
    at com.vaadin.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:273)
    at com.vaadin.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:90)
    at com.vaadin.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:41)
    at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1422)
    at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:380)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:845)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1689)
    at org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter.doFilter(WebSocketUpgradeFilter.java:225)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1676)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:581)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
    at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548)
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:226)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1174)
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:511)
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1106)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
    at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:213)
    at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:119)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134)
    at org.eclipse.jetty.server.Server.handle(Server.java:524)
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:319)
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:253)
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:273)
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:95)
    at org.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:93)
    at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.executeProduceConsume(ExecuteProduceConsume.java:303)
    at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceConsume(ExecuteProduceConsume.java:148)
    at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:136)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:671)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:589)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.StackOverflowError
    at java.util.Hashtable.get(Hashtable.java:366)
    at com.vaadin.data.util.IndexedContainer$IndexedContainerProperty.setValue(IndexedContainer.java:848)
    at my.vaadin.app.MyUI.lambda$11(MyUI.java:3931)
    at com.vaadin.data.util.IndexedContainer.firePropertyValueChange(IndexedContainer.java:528)
    at com.vaadin.data.util.IndexedContainer.access$1000(IndexedContainer.java:63)
    at com.vaadin.data.util.IndexedContainer$IndexedContainerProperty.setValue(IndexedContainer.java:867)
    at my.vaadin.app.MyUI.lambda$11(MyUI.java:3931)

我如何修复它?

enter image description here

这是问题,我不希望这个页脚始终在网格上可见。我只想在网格结束时看到页脚。你明白吗?

2 个答案:

答案 0 :(得分:3)

这已在Using Vaadin 7.4.9 - How to delete data from the grid中得到解答 原因是相同的,你在container.setValue内调用container.addValueChangeListener导致无限循环。

你不能在听众中呼叫item.getItemProperty("Person3").setValue(sum);

您必须检查上次访问循环时是否尚未设置当前设置的项目。 想象一下:

int otherValue = 10;

public setValue(int newValue) {
  int sum = newValue + otherValue; //this is your sum
  setValue(sum);    //of course this causes a StackOverFlowError
}

这是一个可以适用于您的项目的解决方案:

if(!e.getProperty().equals(item.getItemProperty("Person3"))
    item.getItemProperty("Person3").setValue(sum);

答案 1 :(得分:2)

假设到现在为止你已经找到了使用ValueChangeListener来更新 sum行而获得SOE的原因,你可以通过类似的方法来解决这个问题编辑器CommitHandler,因此当保存编辑器更改时, sum行会更新。为简洁起见,下面的示例仅计算总和,但您可以为其余操作应用类似的逻辑:

public class GridWithCalculatedRow extends VerticalLayout {

    public GridWithCalculatedRow() {
        // indexed container allowing the definition of custom properties
        IndexedContainer container = new IndexedContainer();
        container.addContainerProperty("September", String.class, null);
        container.addContainerProperty("Person1", Integer.class, 0);
        container.addContainerProperty("Person2", Integer.class, 0);
        container.addContainerProperty("Person3", Integer.class, 0);


        // add some dummy data
        Random random = new Random();
        for (int i = 0; i < 5; i++) {
            Item item = container.addItem(i);
            item.getItemProperty("September").setValue(String.valueOf(i));
            item.getItemProperty("Person1").setValue(random.nextInt(10));
            item.getItemProperty("Person2").setValue(random.nextInt(10));
            item.getItemProperty("Person3").setValue(random.nextInt(10));
        }

        Item sumItem = container.addItem(6);
        sumItem.getItemProperty("September").setValue("Sum");

        // basic grid setup
        Grid grid = new Grid();
        grid.setContainerDataSource(container);
        grid.getColumn("September").setEditable(false);
        addComponent(grid);

        // initial sum
        updateSum(container, sumItem);

        // disable editing of sum item
        grid.addItemClickListener(event -> {
            if (event.getItemId().equals(6)) {
                grid.setEditorEnabled(false);
            } else {
                grid.setEditorEnabled(true);
            }
        });


        // editor commit handler to update the sum
        grid.getEditorFieldGroup().addCommitHandler(new FieldGroup.CommitHandler() {
            @Override
            public void preCommit(FieldGroup.CommitEvent commitEvent) throws FieldGroup.CommitException {
                // nothing to do here for now
            }

            @Override
            public void postCommit(FieldGroup.CommitEvent commitEvent) throws FieldGroup.CommitException {
                updateSum(container, sumItem);
            }
        });

    }

    // recalculate all sums and update the sum item
    private void updateSum(IndexedContainer container, Item sumItem) {
        Integer person1Sum = 0;
        Integer person2Sum = 0;
        Integer person3Sum = 0;

        // calculate sums
        for (int i = 0; i < 5; i++) {
            Item item = container.getItem(i);
            person1Sum += (Integer) item.getItemProperty("Person1").getValue();
            person2Sum += (Integer) item.getItemProperty("Person2").getValue();
            person3Sum += (Integer) item.getItemProperty("Person3").getValue();

        }

        // update grid item
        sumItem.getItemProperty("Person1").setValue(person1Sum);
        sumItem.getItemProperty("Person2").setValue(person2Sum);
        sumItem.getItemProperty("Person3").setValue(person3Sum);
    }
}

结果: vaadin-grid-with-calculated-row