Important Notice - Forums is archived
To simplify things and help our users to be more productive, we have archived the current forum and focus our efforts on helping developers on Stack Overflow. You can post new questions on Stack Overflow or join our Discord channel.

Vaadin lets you build secure, UX-first PWAs entirely in Java.
Free ebook & tutorial.
Change item in BeanItemContainer
Hi together,
I stuck in problems changing items in my BeanItemContainer. The container is the datasource of my grid and the container is filled with a list. Now I want to change a row in my grid. To do this, I'm trying to change an item in the list or in the container but I dont know how. Whenever I change an item in the list, I get java.lang.NullPointerException.
Some code:
List<Kontrakt> kontrakte = Arrays.asList(
new Kontrakt[]{
//added some stuff
});
BeanItemContainer<Kontrakt> container =
new BeanItemContainer<Kontrakt>(Kontrakt.class);
container.addAll(kontrakte);
grid.setContainerDataSource(container);
container.getItem(kontrakte.get(0)).getBean().setName("example");
I know that I could remove the item from the container, change it and add it again. But then the "new" row is always at the bottom of the list and I don't want to change the order by changing an item.
Thanks for your great help
Can you post the stack trace?
Have you implemented equals and hashcode on Kontrakt class?
Yes I've implemented hascode and equals on Kontrakt class.
Is my way to change the list item even the right way to edit the row?
Jun 06, 2016 12:37:01 PM com.vaadin.server.DefaultErrorHandler doDefault
SCHWERWIEGEND:
java.util.concurrent.ExecutionException: java.lang.NullPointerException
at java.util.concurrent.FutureTask.report(Unknown Source)
at java.util.concurrent.FutureTask.get(Unknown Source)
at com.vaadin.server.VaadinSession$FutureAccess.get(VaadinSession.java:124)
at com.vaadin.server.VaadinService.runPendingAccessTasks(VaadinService.java:1838)
at com.vaadin.server.VaadinSession.unlock(VaadinSession.java:990)
at com.vaadin.server.VaadinService.ensureAccessQueuePurged(VaadinService.java:1799)
at com.vaadin.server.VaadinService.accessSession(VaadinService.java:1765)
at com.vaadin.server.VaadinSession.access(VaadinSession.java:1380)
at com.vaadin.ui.UI.access(UI.java:1444)
at frontend.thesis.webapp.Fenster$4.run(Fenster.java:173)
at java.util.TimerThread.mainLoop(Unknown Source)
at java.util.TimerThread.run(Unknown Source)
Caused by: java.lang.NullPointerException
at frontend.thesis.webapp.Fenster$4.lambda$0(Fenster.java:173)
at com.vaadin.ui.UI.accessSynchronously(UI.java:1381)
at com.vaadin.ui.UI$3.run(UI.java:1447)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at com.vaadin.server.VaadinService.runPendingAccessTasks(VaadinService.java:1835)
... 8 more
It could be better update the item using the container property directly, so value change events are fired
container.getContainerProperty(kontrakte.get(0), "name").setValue("example");
Can you post the whole Fenster class?
I tried the container property you have provided with this error:
Jun 06, 2016 1:11:05 PM com.vaadin.server.DefaultErrorHandler doDefault
SCHWERWIEGEND:
java.lang.NullPointerException
at com.vaadin.ui.Grid$RowDataGenerator.writeData(Grid.java:2198)
at com.vaadin.ui.Grid$RowDataGenerator.generateData(Grid.java:2158)
at com.vaadin.server.communication.data.RpcDataProviderExtension.getRowData(RpcDataProviderExtension.java:395)
at com.vaadin.server.communication.data.RpcDataProviderExtension.pushRowData(RpcDataProviderExtension.java:383)
at com.vaadin.server.communication.data.RpcDataProviderExtension.beforeClientResponse(RpcDataProviderExtension.java:334)
at com.vaadin.server.communication.UidlWriter.write(UidlWriter.java:112)
at com.vaadin.server.communication.AtmospherePushConnection.push(AtmospherePushConnection.java:168)
at com.vaadin.server.communication.PushHandler$2.run(PushHandler.java:150)
at com.vaadin.server.communication.PushHandler.callWithUi(PushHandler.java:243)
at com.vaadin.server.communication.PushHandler.onMessage(PushHandler.java:503)
at com.vaadin.server.communication.PushAtmosphereHandler.onMessage(PushAtmosphereHandler.java:88)
at com.vaadin.server.communication.PushAtmosphereHandler.onRequest(PushAtmosphereHandler.java:78)
at org.atmosphere.cpr.AsynchronousProcessor.action(AsynchronousProcessor.java:199)
at org.atmosphere.cpr.AsynchronousProcessor.suspended(AsynchronousProcessor.java:107)
at org.atmosphere.container.Servlet30CometSupport.service(Servlet30CometSupport.java:66)
at org.atmosphere.cpr.AtmosphereFramework.doCometSupport(AtmosphereFramework.java:2075)
at org.atmosphere.websocket.DefaultWebSocketProcessor.dispatch(DefaultWebSocketProcessor.java:571)
at org.atmosphere.websocket.DefaultWebSocketProcessor$3.run(DefaultWebSocketProcessor.java:333)
at org.atmosphere.util.VoidExecutorService.execute(VoidExecutorService.java:101)
at org.atmosphere.websocket.DefaultWebSocketProcessor.dispatch(DefaultWebSocketProcessor.java:328)
at org.atmosphere.websocket.DefaultWebSocketProcessor.invokeWebSocketProtocol(DefaultWebSocketProcessor.java:425)
at org.atmosphere.container.JSR356Endpoint$1.onMessage(JSR356Endpoint.java:213)
at org.atmosphere.container.JSR356Endpoint$1.onMessage(JSR356Endpoint.java:210)
at org.apache.tomcat.websocket.WsFrameBase.sendMessageText(WsFrameBase.java:399)
at org.apache.tomcat.websocket.WsFrameBase.processDataText(WsFrameBase.java:500)
at org.apache.tomcat.websocket.WsFrameBase.processData(WsFrameBase.java:295)
at org.apache.tomcat.websocket.WsFrameBase.processInputBuffer(WsFrameBase.java:131)
at org.apache.tomcat.websocket.server.WsFrameServer.onDataAvailable(WsFrameServer.java:71)
at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler$WsReadListener.onDataAvailable(WsHttpUpgradeHandler.java:185)
at org.apache.coyote.http11.upgrade.AbstractServletInputStream.onDataAvailable(AbstractServletInputStream.java:198)
at org.apache.coyote.http11.upgrade.AbstractProcessor.upgradeDispatch(AbstractProcessor.java:96)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:647)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1520)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1476)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
My Fenster class:
public class Fenster extends Window {
Grid grid;
public Fenster() {
super("Orderbuch"); // Set window caption
center();
setWidth("600px");
VerticalLayout content = new VerticalLayout();
grid = new Grid();
grid.setColumnReorderingAllowed(true);
grid.setSizeFull();
grid.setEditorEnabled(true);
List<Kontrakt> kontrakte = Arrays.asList(
new Kontrakt[]{
new Kontrakt("item",1),
new Kontrakt("item2",2)
});
BeanItemContainer<Kontrakt> container =
new BeanItemContainer<Kontrakt2>(Kontrakt.class);
container.addAll(kontrakte);
grid.setContainerDataSource(container);
grid.setColumnOrder("name","id");
grid.removeColumn("id");
container.getContainerProperty(kontrakte.get(0), "name").setValue("example");
content.addComponent(grid);
content.setMargin(true);
setContent(content);
}
}
It works for me; I'm able to reproduce your last error only if I add mutable name property in the equals implementation of Kontrakt
I'm not sure what you mean. I generated the equals and the part with name looks like this:
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
Sorry, in my previous answer I wrote "equals implementation" but I meant "hashcode implementation".
If your hashcode implementation is based on the mutable field name then the BeanItemContainer could not lookup the bean from his internal itemIdToItem HashMap after modification as stated in javadocs
BeanItemContainer uses the beans themselves as identifiers. The Object.hashCode() of a bean is used when storing and looking up beans so it must not change during the lifetime of the bean (it should not depend on any part of the bean that can be modified). Typically this restricts the implementation of Object.equals(Object) as well in order for it to fulfill the contract between equals() andhashCode().
If you cannot modify the hashcode implementation you should end up wiht a remove, modify and insert operation
//container.getContainerProperty(kontrakte.get(0), "name").setValue("example");
Kontrakt kontrakt = kontrakte.get(0);
int idx = container.indexOfId(kontrakt);
container.removeItem(kontrakt); kontrakt.setName("example");
container.addItemAt(idx, kontrakt);
HTH
I deleted my hashcode in the kontrakt class. Now I can change the name property with:
container.getContainerProperty(kontrakte.get(0), "name").setValue("example");
I added another column bidqty to my grid and tried to change it the same way:
container.getContainerProperty(kontrakte.get(0), "bidqty").setValue(12);
​Unfortunately I get the error:
Exception in thread "Timer-6" com.vaadin.data.Property$ReadOnlyException
at com.vaadin.data.util.MethodProperty.setValue(MethodProperty.java:644)
at frontend.thesis.webapp.Fenster$1$1.run(Fenster.java:172)
at java.util.TimerThread.mainLoop(Unknown Source)
at java.util.TimerThread.run(Unknown Source)
And:
grid.setReadOnly(false);
container.getContainerProperty(kontrakte.get(0), "bidqty").setReadOnly(false);
doens't help to solve the error.
The first thing I can suppose is that your Kontract class does not have a public setter method
public void setBidqty(int qty)
Was my first thought as well, but my class has
public void setBidqty(int bidqty) {
this.bidqty = bidqty;
}
Ok I solved it. It's working now.
The setter wasn't the problem but the getter. I returned a String and not a int because it was easier for me to display the value of the int in the table. This was my getter:
public String getBidqty() {
return String.valueOf(bidqty);
}
I changed it to:
public int getBidqty() {
return bidqty;
}
and now I can edit the bidqty property as well.
Thank you for your help!!
I had a similar problem, but with a ComboBox. In my case, I had to change
public void setCertificateOfCompliance( Boolean certificateOfCompliance ){
if( certificateOfCompliance instanceof Boolean )
setCertificateOfCompliance( certificateOfCompliance.toString() );
else
setCertificateOfCompliance( "false" );
}
in my bean to
public void setCertificateOfCompliance( boolean certificateOfCompliance ){
setCertificateOfCompliance( "" + certificateOfCompliance );
}
So thanks for your help - it pointed me in the right direction. My problem was almost certainly the fact that the "setCertificateOfCompliance( String value )" was getting confused with "setCertificateofCompliance( Boolean value )" by the "BeanFieldGroup.bindFieldsUnbuffered" method call.