我的主要问题是,我想从键盘将数据插入我的网格。一些数据从数据库加载,用户可以更改(也可以更改加载的数据)或将新数据插入网格(手动)。然后我希望看到最后一行中的列的结果(检查我的图片中的结果) - 结果表示行中的数字,第一列中的数据是 - sum,average,min,max ......
所以,当我点击第三行,进入栏目,例如人物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)
我如何修复它?
这是问题,我不希望这个页脚始终在网格上可见。我只想在网格结束时看到页脚。你明白吗?
答案 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);
}
}