Not being able to read the size from the client component

Hi all,

I am designing a custom image viewer on the client side. In order to navigate through the images I display a small set of controls in order to iterate through the images. I want to position these controls in a bottom-center fashion in the display panel, but the problem is that I can’t read the width-height properties set from the server side when instantiating the component.

According to the documentation, the AbstractComponentConnector’s @OnStateChange methods for the “width” and “height” properties should be fired upon a change in state. In those annotated methods I implement the logic for the widget to be aware of its size, and reposition the panel holding the control buttons.

But this is not happening as expected. Is there any synchronization feature I am missing?. Other properties seem to be working fine, such as imageCount and transitionDelay, properties customizable from the server side.

Any help is greatly appreciated.

Carlos Conti.

Well, figured out to override setWidth/setHeight on the client side. But that’s a sort of brute force attack… any ideas why couldn’t do it through the state synchronization feature?..

It would help extend my understanding about server-client dynamics…

Regards,

Carlos Conti.

Hi,
If @OnStateChange for width/height didn’t trigger when you called server-side setWidth/setHeight then there is a problem somewhere.
I’m not sure about your level of knowledge so sorry if I point out too obvious things. Tha said, if you have setWidth(“100%”) for Component A and you change the size of component B which wraps A. The value of width for A is still 100% and doesn’t change although the actual size on browser will change, meaning you wouldn’t get @OnStateChange.

Thanks Johannes but that’s not the case. The component resized is the one directly mapped to the widget I am developing. So its connector @OnStateChange methods should be the ones to be hit.

I annotate them with the “width” and “height” property names. But that should be fine isn’t it? Let me post the contents of the Connector, perhaps you realize something else.

package com.sofia.widgetset.client.visor;

import com.sofia.visorfotos.Visor;

import com.vaadin.client.annotations.OnStateChange;
import com.vaadin.client.communication.RpcProxy;
import com.vaadin.client.communication.StateChangeEvent;
import com.vaadin.client.ui.AbstractComponentConnector;
import com.vaadin.shared.ui.Connect;

// Connector binds client-side widget class to server-side component class
// Connector lives in the client and the @Connect annotation specifies the
// corresponding server-side component
@Connect(Visor.class)
public class VisorConnector extends AbstractComponentConnector {

    // ServerRpc is used to send events to server. Communication implementation
    // is automatically created here
    VisorServerRpc rpc = RpcProxy.create(VisorServerRpc.class, this);

    public VisorConnector() {
        
        // To receive RPC events from server, we register ClientRpc implementation 
        registerRpc(VisorClientRpc.class, new VisorClientRpc() {
            
        });

        // We choose listed for mouse clicks for the widget
//        getWidget().addClickHandler(new ClickHandler() {
//            public void onClick(ClickEvent event) {
//                final MouseEventDetails mouseDetails = MouseEventDetailsBuilder
//                        .buildMouseEventDetails(event.getNativeEvent(),
//                                getWidget().getElement());
//                
//                // When the widget is clicked, the event is sent to server with ServerRpc
//                rpc.clicked(mouseDetails);
//            }
//        });

    }

    // We must implement getWidget() to cast to correct type 
    // (this will automatically create the correct widget type)
    @Override
    public VisorWidget getWidget() {
        return (VisorWidget) super.getWidget();
    }

    // We must implement getState() to cast to correct type
    @Override
    public VisorState getState() {
        return (VisorState) super.getState();
    }

//    // Whenever the state changes in the server-side, this method is called
//    @Override
//    public void onStateChanged(StateChangeEvent stateChangeEvent) {
//        super.onStateChanged(stateChangeEvent);
//
//        
//    }
        
        @OnStateChange("imageCount")
        void updateImages(){
            getWidget().imageCount = getState().imageCount;
            Integer imageCount = new Integer(getWidget().imageCount);
            getWidget().imagesUrl = new String[imageCount]
;
            for (int i = 0; i < imageCount; i++) {
                String s = this.getResourceUrl(new Integer(i).toString());
                getWidget().imagesUrl[i]
 = s;
                
            }
            getWidget().updateImagesRight();
            getWidget().transitionDelay = getState().transitionDelay;
            getWidget().start();
//            getWidget().start();
        }
        
        @OnStateChange("transitionDelay")
        void updateTransitionDelay(){
            getWidget().transitionDelay = getState().transitionDelay;
            getWidget().start();
        }
        
        
        @OnStateChange("modal")
        void updateModal(){
            getWidget().modal = getState().modal;
            getWidget().updateModal();
        }
        
        @OnStateChange("width"){
            getWidget().width = getState().width;
            getWidget().updateSizeUnits();
        }
        
        @OnStateChange("height"){
            getWidget().height = getState().height;
            getWidget().updateSizeUnits();
        }
        
       
}

Thanks and regards,

Carlos Conti.