我需要从网格(容器)中删除数据,然后我需要刷新行。我怎么能这样做?
Grid grid = new Grid();
IndexedContainer container = new IndexedContainer();
grid.setContainerDataSource(container);
container.addContainerProperty("firstNumber", Integer.class, 0);
container.addContainerProperty("secondNumber", Integer.class, 0);
container.addItem(1);
Item item = container.getItem(1);
int firstNumber = item.getItemProperty("firstNumber").setValue("1");
item = container.getItem(1);
int secondNumber = item.getItemProperty("secondNumber").setValue("2");
现在我尝试仅更改单元格而不删除项目。我的代码是
container.addValueChangeListener(e -> {
Item item = container.getItem(35);
item.getItemProperty("Person5").setValue("SS");
grid.recalculateColumnWidths();
grid.clearSortOrder();
grid.refreshAllRows();
});
但我也有错误...... :(
Morfic的信息:
我需要更改网格单元格中显示的数据。所以......我有3行,其中propertyIds为firstNumber,secondNumber,第4行代表行的总和。所以,我从数据库中获得了一些数据。我需要手动“从键盘”到网格包含一些数据......
想象一下情况:
firstNumber在网格1中有数据,null,2 - 第4个单元格中的总和为3.我想在单元格中添加或更改数据。现在我添加第二个位置编号5.在网格中我现在有数字:1,5和2.我想在第四个单元格中立刻得到总和8。这是我的大问题。
我尝试将ValueChangeListener添加到网格中。
container.addValueChangeListener(e -> {
int sum = 0;
for(int i = 1; i <= 3; i++)
{
Item item = container.getItem(i);
sum += (Integer) item.getItemProperty("firstNumber").getValue();
}
item = container.getItem(4);
item.getItemProperty("firstNumber").setValue(sum);
grid.recalculateColumnWidths();
grid.clearSortOrder();
grid.refreshAllRows();
});
所以我收到错误:
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)
您的Caused by: java.lang.StackOverflowError
问题是因为您正在更改ValueChangeListener
内的值,这会生成其他事件,并且最终会无限循环,因为 @Manuel Kollegger 我试图指出,所以需要采用不同的方法。
我想到的最简单的想法是拥有一个生成的列,您可以根据另一个来计算该值。但是,根据docs,Vaadin 7中没有直接的方法来定义生成的列,因此您必须使用GeneratedPropertyContainer
包装容器:
网格没有生成列。相反,容器数据源可以围绕
GeneratedPropertyContainer
。
此外,您可能希望将generate属性设置为只读,以防止用户手动编辑它。
以下示例根据您的描述显示了如何完成此操作。请注意,为了简洁起见,它并不完全是万无一失的(空值,无效值等),但它应该让你开始:
import com.vaadin.data.Item;
import com.vaadin.data.util.GeneratedPropertyContainer;
import com.vaadin.data.util.IndexedContainer;
import com.vaadin.data.util.PropertyValueGenerator;
import com.vaadin.ui.Grid;
import com.vaadin.ui.VerticalLayout;
import java.util.Random;
public class GridWithCalculatedColumn extends VerticalLayout {
public GridWithCalculatedColumn() {
// indexed container allowing the definition of custom properties
IndexedContainer container = new IndexedContainer();
container.addContainerProperty("firstNumber", Integer.class, 0);
container.addContainerProperty("secondNumber", Integer.class, 0);
// generated property container allowing the definition of generated properties
GeneratedPropertyContainer wrappingContainer = new GeneratedPropertyContainer(container);
wrappingContainer.addGeneratedProperty("sum", new PropertyValueGenerator<Integer>() {
@Override
public Integer getValue(Item item, Object itemId, Object propertyId) {
// sum the other 2 columns
// NOTE: for the sake of simplicity this does not handle invalid values such as "null"
return (Integer) item.getItemProperty("firstNumber").getValue() + (Integer) item.getItemProperty("secondNumber").getValue();
}
@Override
public Class<Integer> getType() {
return Integer.class;
}
});
// add some dummy data
Random random = new Random();
for (int i = 0; i < 5; i++) {
Item item = wrappingContainer.addItem(i);
item.getItemProperty("firstNumber").setValue(random.nextInt(10));
item.getItemProperty("secondNumber").setValue(random.nextInt(10));
}
// basic grid setup
Grid grid = new Grid();
grid.setContainerDataSource(wrappingContainer);
grid.setEditorEnabled(true);
// disable editing of the "calculated value"
grid.getColumn("sum").setEditable(false);
addComponent(grid);
}
}
结果:
答案 1 :(得分:0)
使用Vaadin 7.4.9在网格方面非常繁琐。
必须使用container.removeItem(item)
删除项目。
另外,在Vaadin 7.7(添加refreshAll
和refreshRow()
的方法)中更容易刷新网格,在Vaadin 8中尤其容易(使用事件和数据提供者)。
在Vaadin 7中,你必须通过调用自动重绘网格的clearSortOrder
来破解它。
当您从另一个线程(即不在ValueChangeListener中)更新UI时,将使用以下代码,但是您需要启用Vaadin-Push Addon,它是一个单独的依赖项。
getUI.access(() -> {
List<SortOrder> sortOrders = new ArrayList<>();
grid.getSortOrder().forEach(sortOrder -> sortOrders.add(sortOrder));
grid.recalculateColumnWidths();
grid.clearSortOrder();
grid.setSortOrder(sortOrders);
getUI().push();
});
编辑:如果使用组合框的buttonClick或ValueChangeEvent进行删除,您可以执行以下操作:
component.addValueChangeListener(e -> {
Item item = container.getItem(35);
container.removeItem(item);
container.addItem(35);
item.getItemProperty("Person5").setValue("SS");
grid.recalculateColumnWidths();
grid.clearSortOrder();
grid.refreshAllRows();
});
但是请注意,您的实现在容器上有一个ValueChangeListener,它调用container.removeItem(35)
这将导致另一个触发另一个ValueChanged-Event,它将尝试再次删除项目编号35。您必须为ValueChangeListener使用另一个组件,否则您将遇到无限循环