Problems with push in Vaadin 7.1

I want to achieve the following behavior , there is a UI that contents a CustomComponent that his subcomponents are generated dynamically depending on data in a database. this customComponent “PanelMatrix”is fill with components Layouts (cells), Labels (content inside of the cells) and buttons (to add more content) , and this info is refreshed in all the connected clients using @Push. Then any client can intro texts and press a button, this text (labels) should be show in all the other clients.

The problem is that even the GeneratedCells part it works fine- (see attached picture 1)> If one of the users press the corresponding button then the others clients get the cells in his page with out pressing nothing, but when any of the clients fills data and press the button to share with the others instead of the others see this new input, that input appears as many clients exits in the first panelMatrix that was open, but not in others. (see attached picture 2)

picture 1

picture 2

Even that in the trace is showing “different Instances”


		System.err.println("pos texto en "+ this);
		celda.addComponent(hlEntrada);

pos texto en coop.intergal.asambleas.sala.ui.PanelMatrix@b0a942b
pos texto en coop.intergal.asambleas.sala.ui.PanelMatrix@1d7b83bd

the code I use:
****************** The UI class ***********************


@Push
@SuppressWarnings("serial")
@Theme("sala_reuniones")
public class Sala_reuniones_UI extends UI implements BroadcastListener

*adds the CustomComponent panelMatrix to it


			panelMatrix = new PanelMatrix();
			tabsZonaPrincipal.addTab(panelMatrix, "Matriz");

Listen to event buton event for fill PanelMatrix*


	 mostrarMatriz.addClickListener(new Button.ClickListener() {
	            @Override
	            public void buttonClick(ClickEvent event) {
	    			Broadcaster.mostrarMatriz(idProp, idMatrizProp, userConectado, entidad, idAsam);
	    				            }
	         });

(in the case of post test the listener of the buttonClick is the customComponent class, see bellow)
*Listen to events send from BroadcastListener with


	@Override // THIS WORKS FINE
	public void receiveMostrarMatriz(final String entidad, final Long idProp,
			final Integer idMatrizProp, final String userConectado, final Long idAsam) {
	        System.err.println("instancia sala que recibe el Mostrar Matriz "+ this);
	 		final String elUserQueVota = this.userConectado;
			final String laEntidadQueEsInvocada = this.entidad;
//			final Integer elIdDeMatriz = this.idMatrizProp;
			final Sala_reuniones_UI ui = this;
			access(new Runnable() {
				

				@Override
	            public void run() {
//	                Notification n = new Notification("Message received",
//	                		textoVotacion, Type.TRAY_NOTIFICATION);
//	                n.show(getPage());
	       
			System.err.println("es la entidad "+ laEntidadQueEsInvocada + " y es invocado por la entidad "+ entidad );
			if (laEntidadQueEsInvocada.equals(entidad))
			{
				System.err.println("abre la matriz el usuario"+ elUserQueVota + " y es invocado por la entidad "+ entidad + " y con la idMatriz" + idMatrizProp);
				ui.idMatrizProp = idMatrizProp;
				ui.updatePanelMatriz(idMatrizProp);

				
				}
			
			
			}
				
	            
	        });
		}
	@Override // THIS FAILS
	public void receivePosEnMatriz(final Integer idMatrizProp, final String entidad,
			Long idAsam, final Object value, final Object keyBoton, final Object keyApunte) {
        System.err.println("instancia sala que recibe el pos en Matriz "+ this);
 		final String elUserQueVota = this.userConectado;
		final String laEntidadQueEsInvocada = this.entidad;
//		final Integer elIdDeMatriz = this.idMatrizProp;
		final Sala_reuniones_UI ui = this;
		access(new Runnable() {
			

			@Override
            public void run() {
//                Notification n = new Notification("Message received",
//                		textoVotacion, Type.TRAY_NOTIFICATION);
//                n.show(getPage());
       
		System.err.println("es la entidad "+ laEntidadQueEsInvocada + " y es invocado por la entidad "+ entidad );
		if (laEntidadQueEsInvocada.equals(entidad))
		{
			System.err.println("pos en la matriz el usuario"+ elUserQueVota + " y es invocado por la entidad "+ entidad + " y con la idMatriz" + idMatrizProp);
			ui.idMatrizProp = idMatrizProp;
//			w.updatePanelMatriz(idMatrizProp);
			ui.postEnPanelMatriz(value, keyBoton, keyApunte);

			
			}
		
		
		}
			
            
        });
	}

******** Calls the corresponding methods in the panelMatrix *****


      panelMatrix.generaCeldas(matrizJpaContainer.getItem(idMatrizProp), entidad, idAsam); // This works 

      panelMatrix.postTexto(value, keyBoton, keyApunte); // This fails

***** CustomComponent panelMatrix


@SuppressWarnings("serial")
public class PanelMatrix extends CustomComponent implements ClickListener 

***** Generates the cells **** // This works fine 

	public void generaCeldas(EntityItem<PropMatriz> item, String entidad, long idAsam) {
		
		this.propMatriz = item.getEntity();
		this.entidad = entidad;
		this.idAsam = idAsam;
		PanelMatrix.idPropMatriz = (Integer) item.getItemProperty("idPropMatriz").getValue();
		Integer x = (Integer) item.getItemProperty("tiposMatriz.filas").getValue();
		Integer y = (Integer) item.getItemProperty("tiposMatriz.columnas").getValue();
		String  listaTitulos = (String) item.getItemProperty("tiposMatriz.titulosCeldas").getValue();
		tableApuntes = new Table();
		setuApuntesCeldaJPAContainer();
		item.getContainer().refresh();
		apuntesCeldaJpaContainer.refresh();
		filterApuntes();
		titulos = new String [x]
[y]
;  
		StringTokenizer st = new StringTokenizer(listaTitulos, ",");
		
		for (int i=0; i < x; i++)
		{
			// crea linea
			for (int ii=0; ii < y; ii++)
			{
				String titulo = st.nextToken();
				if (titulo != null)
					{
					titulos [i]
[ii]
 = titulo;
					}
				else
				{
					break;
				}
			}
			
		}
		generaCeldas(x,y);
		
		cargaCeldas();

***** for Each cell creates VerticalLayout that will receive the test (labels) and his corresponding button and a listener for each button events **********


	private Component creaVerticalLayout(final int i, final int x) {
	
			try {
				vl = new SortableLayout(i*100+x);// SortableLayout.class.newInstance();
				b = Button.class.newInstance();
//				b.addListener(this);
				b.addClickListener(new Button.ClickListener() {
		            @Override
		            public void buttonClick(ClickEvent event) {
		    			System.err.println("buttonClick que ha pulsado el boton "+ this);
						Integer idApunte = salvaEntrada((String) textoAEnviar.getValue(), i*100+x);
						publicapPostTexto(textoAEnviar.getValue(), i*100+x,idApunte);
						SortableLayout celda = gCeldas.get(i*100+x );
						celda.setData(idApunte);	            }
		           });
			
			} catch (InstantiationException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			vl.setCaption(titulos[i-1]
[x-1]
); //"VL"+i+"/"+x);
			vl.setWidth(anchoCelda,UNITS_PIXELS);
			vl.setHeight("100px");
			vl.setData(i*100+x); // salva la coordenada en el layout
			vl.addComponent(new Label());
			b.setCaption(titulos[i-1]
[x-1]
);
			gCeldas.put(i*100+x , vl);
			gButtons.put(i*100+x, b);
			botonera.addComponent(b);
			return vl;
		} 

********* the method in PanelMatrix that calls the receiver


	private void publicapPostTexto(Object value, Object keyBoton, Object keyApunte) {
		
		System.err.println("(2)........... Instancia que invoca el broacast "+ this);
		Broadcaster.posEnMatriz(idPropMatriz, entidad, idAsam, value, keyBoton, keyApunte);	 }

********* the class Broadcaster that handles the push events *******


public class Broadcaster {

    private static final List<BroadcastListener> listeners = new CopyOnWriteArrayList<BroadcastListener>();

    public static void register(BroadcastListener listener) {
        listeners.add(listener);
    }

    public static void unregister(BroadcastListener listener) {
        listeners.remove(listener);
    }

    public static void broadcastAbreVotaciones(String entidad, Long idProp, Long idConsulta, String UserConectado, String textoVotacion) {
        for (BroadcastListener listener : listeners) {
            listener.receiveAbreVotaciones(entidad,idProp,idConsulta,UserConectado,textoVotacion);
        }
    }

  
	public static void mostrarMatriz(Long idProp, Integer idMatrizProp,
			String userConectado, String entidad, Long idAsam) {
	     for (BroadcastListener listener : listeners) {
	            listener.receiveMostrarMatriz(entidad,idProp,idMatrizProp,userConectado,idAsam);
	        }
		
	}
	public static void posEnMatriz(Integer idMatrizProp,
			 String entidad, Long idAsam, Object value, Object keyBoton, Object keyApunte) {
	     for (BroadcastListener listener : listeners) {
		        System.err.println("(3).......instancia en el broadcaster, llama al receiver   "+ listener);
	            listener.receivePosEnMatriz(idMatrizProp, entidad, idAsam, value, keyBoton, keyApunte);
	        }
		
	}

I am trying to implement simple chat and I am having exactly the same problem (using latest Vaadin 7.1.9)

UI.getCurrent().access(new Runnable() { … is caled on correct UI instance and it tries to update Label value.
However change is propagated only on the first instance that is created. All other instances receive the value but change is not propagated to the client.

I am now trying to dig deeper and understand Push and UI updating works …

I figured out what was wrong.

UI.getCurrent() realy does not return UI beloning to actual session, it returns first UI that was instantiated.
When I implement broadcaster in class extending UI, it works. Since I call function access directly from UI instance.
Before I had broadcaster tied to the Chat* class and I had to access UI using static UI.getCurrrent which caused the issue.

Maybe this will help some of you out there.

Well, yes and no.

The reference returned by UI.getCurrent() is stored in an
inheritable ThreadLocal
. When a UI is accessed, either via a client request, or by the user invoking UI.access(), the UI.getCurrent() value is set to that UI.

In an arbitrary background thread, outside a UI.access() invocation, there cannot be a concept of a “current UI”. Why, then, UI.getCurrent() in many cases
does
return a non-null value even in a background thread? This is because, as mentioned, the ThreadLocal is inheritable. That is to say, if a child thread is spawned by a thread that at that time has UI.getCurrent() set, the value is inherited by the child thread. This is most likely the effect you’re seeing. It makes some things a bit more convenient, but I’m not actually sure it’s actually a good idea for it to be inheritable - it stretches the meaning of “current” and may cause the user to forget to do proper synchronization before accessing the “current” UI.