I am having some problems, when I am trying to add new bean to itemcontainer in background.
When I try to scroll down table using scrollbar, it loses focus even if I still hold mouse button pressed. It happens when i stop scrolling and let table to refresh data. (thread in background is still adding beans to table). Is this behaviour normal, or maybe i am using beanitemcontainer wrong?
I am having this problem at chrome, ff and opera also.
I’ve made simple application to show the issue. Please see example below:
I could also post maven project to run.
package com.test;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import com.vaadin.annotations.PreserveOnRefresh;
import com.vaadin.data.util.BeanItemContainer;
import com.vaadin.server.VaadinRequest;
import com.vaadin.ui.Table;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
@SuppressWarnings("serial")
@PreserveOnRefresh
public class MyVaadinUI extends UI {
BeanItemContainer<TableEntry> beans = new BeanItemContainer<TableEntry>(TableEntry.class);
@Override
protected void init(VaadinRequest request) {
final VerticalLayout layout = new VerticalLayout();
setContent(layout);
Table f = new Table();
f.setContainerDataSource(beans);
final ScheduledExecutorService stpe = Executors.newSingleThreadScheduledExecutor();
for(int i = 0; i:love:00; i++){
beans.addItem(new TableEntry(0.0d, 0.0d));
}
stpe.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
System.err.println("adding bean");
beans.addItem(new TableEntry(0.1d, 0.4d));
}
}, 5, 1, TimeUnit.SECONDS);
layout.addComponent(f);
this.addDetachListener(new DetachListener() {
@Override
public void detach(DetachEvent event) {
stpe.shutdown();
}
});
}
}
Although not sure if it is the only problem here, the code executed in the background that touches Vaadin components (in this case by modifying a container that is bound to a component) must use proper locking. You should use VaadinSession.lock()/unlock() (Vaadin 7.0) or UI.access(Runnable) (Vaadin 7.1).
When using lock(), it should be immediately followed by a try-finally block that makes sure unlock() is called. The parts of the background thread that do not access Vaadin components etc. should typically be outside the lock to limit unnecessarily blocking the application.
Unfortunately problem exists also when using locking. (Old getLockInstance().lock() way and new access() way).
I’ve changed project vaadin version to 7.1.0.beta1 and problem still exitsts. Also, when I try to add push, there is another problem with scroll - it loses last scrollbar posistion when push operation is performed. Here is my UI class code:
package com.test;
import java.util.Random;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import com.vaadin.annotations.PreserveOnRefresh;
import com.vaadin.annotations.Push;
import com.vaadin.data.util.BeanItemContainer;
import com.vaadin.server.VaadinRequest;
import com.vaadin.shared.communication.PushMode;
import com.vaadin.ui.Label;
import com.vaadin.ui.Table;
import com.vaadin.ui.Table.ColumnGenerator;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
/**
* The Application's "main" class
*/
@SuppressWarnings("serial")
@PreserveOnRefresh
@Push(PushMode.MANUAL)
public class MyVaadinUI extends UI {
BeanItemContainer<TableEntry> beans = new BeanItemContainer<TableEntry>(TableEntry.class);
boolean runThread = true;
@Override
protected void init(VaadinRequest request) {
final VerticalLayout layout = new VerticalLayout();
setContent(layout);
final Table f = new Table();
f.setContainerDataSource(beans);
for(int i = 0; i:love:00; i++){
beans.addItem(new TableEntry(0.0d, 0.0d));
}
Thread t = new Thread(new Runnable() {
@Override
public void run() {
while(runThread){
try {
Thread.sleep(1000);
UI.getCurrent().access(new Runnable() {
@Override
public void run() {
beans.addItem(new TableEntry(0.1d, 0.4d));
for (final TableEntry b : beans.getItemIds()) {
beans.getItem(b).getItemProperty(TableEntry.PROPERTY_SECCOL).setValue(new Random().nextDouble());
}
push();
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
t.start();
layout.addComponent(f);
this.addDetachListener(new DetachListener() {
@Override
public void detach(DetachEvent event) {
runThread = false;
}
});
}
}
Of course i could post whole maven project.
Thank you