component reference in shared state

Hello,
I’m trying to wrap gwt-graphics add-on in a vaadin component but I miss some Vaadin basics.

Here is some simplified code :

server side code :

[code]
public class SvgTestUI extends UI {
@Override
protected void init(VaadinRequest request) {
VerticalLayout layout = new VerticalLayout();
setContent(layout);
layout.addComponent(new Label(“HelloWorld”));
SvgDrawingArea svgDrawingArea = new SvgDrawingArea(800,500);
SvgRectangle svgRectangle = new SvgRectangle(50,50, 400, 400);
svgDrawingArea.addRectangle(svgRectangle);
layout.addComponent(svgDrawingArea);
}
}

public class SvgDrawingArea extends AbstractComponent {
@Override public SvgDrawingAreaState getState() { return (SvgDrawingAreaState) super.getState(); }
public SvgDrawingArea(int width, int height) {
super.setWidth(width, Unit.PIXELS);
super.setHeight(height, Unit.PIXELS);
}
public void addRectangle(SvgRectangle rectangle) {
getState().rectangle = rectangle;
}
}

public class SvgRectangle extends AbstractComponent {
@Override public SvgRectangleState getState() { return (SvgRectangleState) super.getState(); }
public SvgRectangle(int x, int y, int width, int height) {
getState().x = x;
getState().y = y;
super.setWidth(width, Unit.PIXELS);
super.setHeight(height, Unit.PIXELS);
}
}
[/code]shared states

[code]
public class SvgDrawingAreaState extends AbstractComponentState {
public Connector rectangle;
}

public class SvgRectangleState extends AbstractComponentState {
public int x, y;
}
[/code]connectors

@Connect(SvgDrawingArea.class) public class SvgDrawingAreaConnector extends AbstractComponentConnector { @Override protected DrawingArea createWidget() { DrawingArea drawingArea = new DrawingArea(0,0); return drawingArea; } @Override public DrawingArea getWidget() { return (DrawingArea) super.getWidget(); } @Override public SvgDrawingAreaState getState() { return (SvgDrawingAreaState) super.getState(); } @Override public void onStateChanged(StateChangeEvent stateChangeEvent) { Util.updateStateSize(getState()); super.onStateChanged(stateChangeEvent); SvgDrawingAreaState state = getState(); getWidget().setWidth(getState().width); getWidget().setHeight(getState().height); if (state.rectangle != null) { SvgRectangleConnector svgRectangleConnector = (SvgRectangleConnector)state.rectangle; Rectangle rectangle = svgRectangleConnector.getWidget(); getWidget().add(rectangle); } } } The client-side rectangle reference on the SvgDrawingAreaState state is always null.
In the Vaadin doc I see this statement :
“You should also notice that the connector you are sending still needs to be present in the connector hierarchy, otherwise the client-side will always see a null reference.”.
But I don’t undestand it.

Where am I wrong ?

Thanks!
Franck

Hi Franck,

The statement means that there cannot be “free-floating” connectors in a Vaadin UI - every connector except the UI itself has to be some other connector’s child - that is, A is B’s child if A.getParent() == B
and
B.iterator() yields A when iterated over. Basically this means that your SvgDrawingArea needs to extend AbstractComponentContainer, or perhaps preferably, extend CustomComponent and wrap such an AbstractComponentContainer implementation to shield the container from accidentally adding arbitrary components to it.

Hi Johanes,

Thanks for your advice. I’ve been digging since yesterday and came to a variation.
My code is now functional.

For people who face the same interrogation and who felt on my post here are my updates :

SvgDrawingArea implements HasComponents

[code]
public class SvgDrawingArea extends AbstractComponent implements HasComponents {

public void addShape(SvgShape shape) {
getState().shapes.add(shape);
shape.setParent(this);
}

@Override public Iterator iterator() {
List l = new ArrayList();
for (Connector c : getState(false).shapes) {
l.add((Component) c);
}
return l.iterator();
}
[/code]SvgDrawingAreaConnector extends AbstractComponentContainerConnector

@Connect(SvgDrawingArea.class) public class SvgDrawingAreaConnector extends AbstractComponentContainerConnector {
    .......
    @Override
    public void onConnectorHierarchyChange(ConnectorHierarchyChangeEvent connectorHierarchyChangeEvent) { }
    @Override
    public void updateCaption(ComponentConnector connector) { }

Franck

Yeah, sorry, I totally forgot that in this case it’s probably way easiest just to implement
HasComponents
directly. Nicely figured out!