Table scroll freezes when adding new bean to container in background

Hi,

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();
			}
		});
		
	}
}

Attaching project
13034.zip (16.1 KB)

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 :slight_smile:

Hi, maybe should I post better example? Problem still exists in vaadin 7.1.3